From dba73b611dc208c739cd845549dd963a3c8b4dcd Mon Sep 17 00:00:00 2001 From: Trazom Date: Thu, 30 Apr 2009 03:00:59 +0400 Subject: [PATCH] [7737] Implement ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE. Zone dependent achievement criteria required DB support. Signed-off-by: VladimirMangos --- src/game/AchievementMgr.cpp | 48 ++++++++++++++++++++++++++++++------- src/game/LootHandler.cpp | 2 ++ src/game/LootMgr.h | 18 +++++++++++++- src/game/Player.cpp | 3 +++ src/game/Player.h | 13 ---------- src/shared/revision_nr.h | 2 +- 6 files changed, 62 insertions(+), 24 deletions(-) diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index 363e8cbe7..912f9508d 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -78,8 +78,9 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) switch(criteria->requiredType) { - case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: + case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: break; default: sLog.outErrorDb( "Table `achievement_criteria_data` have data for not supported criteria type (Entry: %u Type: %u), ignore.", criteria->ID, criteria->requiredType); @@ -861,6 +862,30 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID)) SetCriteriaProgress(achievementCriteria, 1); break; + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: + { + // miscvalue1=loot_type (note: 0 = LOOT_CORSPE and then it ignored) + // miscvalue2=count of item loot + if (!miscvalue1 || !miscvalue2) + continue; + if (miscvalue1 != achievementCriteria->loot_type.lootType) + continue; + + // zone specific + if(achievementCriteria->loot_type.lootTypeCount==1) + { + // those requirements couldn't be found in the dbc + AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria); + if(!data) + continue; + + if(!data->Meets(GetPlayer(),unit)) + continue; + } + + SetCriteriaProgress(achievementCriteria, miscvalue2, PROGRESS_ACCUMULATE); + break; + } case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: // speedup for non-login case if(miscvalue1 && achievementCriteria->own_item.itemID != miscvalue1) @@ -1142,7 +1167,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED: case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED: case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN: - case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS: case ACHIEVEMENT_CRITERIA_TYPE_TOTAL: break; // Not implemented yet :( @@ -1232,6 +1256,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve return progress->counter >= achievementCriteria->cast_spell.castCount; case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL: return progress->counter >= 1; + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: + return progress->counter >= achievementCriteria->loot_type.lootTypeCount; case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: return progress->counter >= achievementCriteria->own_item.itemCount; case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: @@ -1672,18 +1698,22 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() switch(criteria->requiredType) { - case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: - if(!GetCriteriaDataSet(criteria)) - sLog.outErrorDb( "Table `achievement_criteria_data` not have expected data for for criteria (Entry: %u Type: %u).", criteria->ID, criteria->requiredType); - break; case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: // need skip generic cases - if(criteria->do_emote.count && !GetCriteriaDataSet(criteria)) - sLog.outErrorDb( "Table `achievement_criteria_data` not have expected data for for criteria (Entry: %u Type: %u).", criteria->ID, criteria->requiredType); + if(criteria->do_emote.count==0) + continue; break; - default: // unexpected case processed in IsValid check + case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: // any cases break; + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: // need skip generic cases + if(criteria->loot_type.lootTypeCount!=1) + continue; + break; + default: // type not use DB data, ignore + continue; } + if(!GetCriteriaDataSet(criteria)) + sLog.outErrorDb( "Table `achievement_criteria_data` not have expected data for for criteria (Entry: %u Type: %u).", criteria->ID, criteria->requiredType); } sLog.outString(); diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp index 69b9a1f1c..0dc2b5598 100644 --- a/src/game/LootHandler.cpp +++ b/src/game/LootHandler.cpp @@ -141,6 +141,7 @@ void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data ) player->SendNewItem(newitem, uint32(item->count), false, false, true); player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count); + player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count); } else player->SendEquipError( msg, NULL, NULL ); @@ -497,6 +498,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data ) Item * newitem = target->StoreNewItem( dest, item.itemid, true, item.randomPropertyId ); target->SendNewItem(newitem, uint32(item.count), false, false, true ); target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count); + target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, pLoot->loot_type, item.count); // mark as looted item.count=0; diff --git a/src/game/LootMgr.h b/src/game/LootMgr.h index 40ea2303a..b67ef9a31 100644 --- a/src/game/LootMgr.h +++ b/src/game/LootMgr.h @@ -55,6 +55,21 @@ enum PermissionTypes NONE_PERMISSION = 3 }; +enum LootType +{ + LOOT_CORPSE = 1, + LOOT_PICKPOCKETING = 2, + LOOT_FISHING = 3, + LOOT_DISENCHANTING = 4, + // ignored always by client + LOOT_SKINNING = 6, + LOOT_PROSPECTING = 7, + LOOT_MILLING = 8, + + LOOT_FISHINGHOLE = 20, // unsupported by client, sending LOOT_FISHING instead + LOOT_INSIGNIA = 21 // unsupported by client, sending LOOT_CORPSE instead +}; + class Player; class LootStore; @@ -224,8 +239,9 @@ struct Loot std::vector items; uint32 gold; uint8 unlootedCount; + LootType loot_type; // required for achievement system - Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0) {} + Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0), loot_type(LOOT_CORPSE) {} ~Loot() { clear(); } // if loot becomes invalid this reference is used to inform the listener diff --git a/src/game/Player.cpp b/src/game/Player.cpp index da003ff80..8383aec49 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -7320,6 +7320,9 @@ void Player::SendLoot(uint64 guid, LootType loot_type) default: break; } + // need know merged fishing/corpse loot type for achievements + loot->loot_type = loot_type; + WorldPacket data(SMSG_LOOT_RESPONSE, (9+50)); // we guess size data << uint64(guid); diff --git a/src/game/Player.h b/src/game/Player.h index 87768cc38..4eabfb5d5 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -457,20 +457,7 @@ enum ActivateTaxiReplies ERR_TAXINOTSTANDING = 12 }; -enum LootType -{ - LOOT_CORPSE = 1, - LOOT_PICKPOCKETING = 2, - LOOT_FISHING = 3, - LOOT_DISENCHANTING = 4, - // ignored always by client - LOOT_SKINNING = 6, - LOOT_PROSPECTING = 7, - LOOT_MILLING = 8, - LOOT_FISHINGHOLE = 20, // unsupported by client, sending LOOT_FISHING instead - LOOT_INSIGNIA = 21 // unsupported by client, sending LOOT_CORPSE instead -}; enum MirrorTimerType { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9fa633605..308f2ff10 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7736" + #define REVISION_NR "7737" #endif // __REVISION_NR_H__