diff options
| author | Shauren <shauren.trinity@gmail.com> | 2015-04-14 01:12:20 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2015-04-14 01:12:20 +0200 |
| commit | d9e941dde3cc6105d5cd68ae3da55e4a7efcb244 (patch) | |
| tree | 0143efd544e61725a7f37acb13a5b4db29c75d81 /src | |
| parent | e5675412735a33f05f9c3215fb0cc7327a800c6c (diff) | |
Core/Quests: Added research results about last field in QuestPackageItem.db2
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 21 | ||||
| -rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 4 | ||||
| -rw-r--r-- | src/server/game/DataStores/DB2Structure.h | 6 | ||||
| -rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 8 | ||||
| -rw-r--r-- | src/server/game/Entities/Item/ItemTemplate.cpp | 8 | ||||
| -rw-r--r-- | src/server/game/Entities/Item/ItemTemplate.h | 3 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 32 | ||||
| -rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 23 | ||||
| -rw-r--r-- | src/server/shared/Database/Implementation/HotfixDatabase.cpp | 2 |
9 files changed, 71 insertions, 36 deletions
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 71090011c64..bed2cc793f4 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -66,7 +66,6 @@ TaxiMask sAllianceTaxiNodesMask; TaxiMask sDeathKnightTaxiNodesMask; TaxiPathSetBySource sTaxiPathSetBySource; TaxiPathNodesByPath sTaxiPathNodesByPath; -QuestPackageItemMap sQuestPackageItemStoreMap; typedef std::list<std::string> DB2StoreProblemList; @@ -202,6 +201,9 @@ void DB2Manager::LoadStores(std::string const& dataPath) if (PhaseEntry const* phase = sPhaseStore.LookupEntry(group->PhaseID)) _phasesByGroup[group->PhaseGroupID].insert(phase->ID); + for (QuestPackageItemEntry const* questPackageItem : sQuestPackageItemStore) + _questPackages[questPackageItem->QuestPackageID].push_back(questPackageItem); + for (SpellPowerEntry const* power : sSpellPowerStore) { if (SpellPowerDifficultyEntry const* powerDifficulty = sSpellPowerDifficultyStore.LookupEntry(power->ID)) @@ -305,14 +307,6 @@ void DB2Manager::LoadStores(std::string const& dataPath) } } - for (uint32 i = 0; i < sQuestPackageItemStore.GetNumRows(); ++i) - { - if (QuestPackageItemEntry const* pack = sQuestPackageItemStore.LookupEntry(i)) - { - sQuestPackageItemStoreMap[pack->QuestPackageID].push_back(pack); - } - } - // error checks if (bad_db2_files.size() >= DB2FilesCount) { @@ -499,6 +493,15 @@ MountEntry const* DB2Manager::GetMount(uint32 spellId) const return nullptr; } +std::vector<QuestPackageItemEntry const*> const* DB2Manager::GetQuestPackageItems(uint32 questPackageID) const +{ + auto itr = _questPackages.find(questPackageID); + if (itr != _questPackages.end()) + return &itr->second; + + return nullptr; +} + std::set<uint32> DB2Manager::GetPhasesForGroup(uint32 group) const { auto itr = _phasesByGroup.find(group); diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index 29dc68a451c..ece71c7413e 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -51,7 +51,6 @@ extern TaxiMask sAllianceTaxiNodesMask; extern TaxiMask sDeathKnightTaxiNodesMask; extern TaxiPathSetBySource sTaxiPathSetBySource; extern TaxiPathNodesByPath sTaxiPathNodesByPath; -extern QuestPackageItemMap sQuestPackageItemStoreMap; struct HotfixNotify { @@ -75,6 +74,7 @@ public: typedef std::unordered_map<uint32, std::set<ItemBonusTreeNodeEntry const*>> ItemBonusTreeContainer; typedef std::unordered_map<uint32, MountEntry const*> MountContainer; typedef std::unordered_map<uint32, std::set<uint32>> PhaseGroupContainer; + typedef std::unordered_map<uint32, std::vector<QuestPackageItemEntry const*>> QuestPackageItemContainer; typedef std::unordered_map<uint32, std::vector<SpellPowerEntry const*>> SpellPowerContainer; typedef std::unordered_map<uint32, std::unordered_map<uint32, std::vector<SpellPowerEntry const*>>> SpellPowerDifficultyContainer; @@ -98,6 +98,7 @@ public: std::set<uint32> GetItemBonusTree(uint32 itemId, uint32 itemBonusTreeMod) const; uint32 GetItemDisplayId(uint32 itemId, uint32 appearanceModId) const; MountEntry const* GetMount(uint32 spellId) const; + std::vector<QuestPackageItemEntry const*> const* GetQuestPackageItems(uint32 questPackageID) const; std::set<uint32> GetPhasesForGroup(uint32 group) const; std::vector<SpellPowerEntry const*> GetSpellPowers(uint32 spellId, Difficulty difficulty = DIFFICULTY_NONE, bool* hasDifficultyPowers = nullptr) const; @@ -113,6 +114,7 @@ private: ItemToBonusTreeContainer _itemToBonusTree; MountContainer _mountsBySpellId; PhaseGroupContainer _phasesByGroup; + QuestPackageItemContainer _questPackages; SpellPowerContainer _spellPowers; SpellPowerDifficultyContainer _spellPowerDifficulties; }; diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index ee6f4fdcc85..912ae5d60d5 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -296,19 +296,15 @@ struct PhaseXPhaseGroupEntry uint32 PhaseGroupID; }; -// QuestPackageItem.db2 struct QuestPackageItemEntry { uint32 ID; // 0 uint32 QuestPackageID; // 1 uint32 ItemID; // 2 uint32 ItemCount; // 3 - uint32 Unk; // 4 + uint32 FilterType; // 4 }; -typedef std::vector<QuestPackageItemEntry const*> QuestPackageItemList; -typedef std::unordered_map<uint32, QuestPackageItemList> QuestPackageItemMap; - struct SoundEntriesEntry { uint32 ID; // 0 diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index 30bd11af8c5..aca745c52a3 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -491,6 +491,14 @@ enum MountFlags MOUNT_FLAG_HIDE_IF_UNKNOWN = 0x40 }; +enum QuestPackageFilter +{ + QUEST_PACKAGE_FILTER_LOOT_SPECIALIZATION = 0, // Players can select this quest reward if it matches their selected loot specialization + QUEST_PACKAGE_FILTER_CLASS = 1, // Players can select this quest reward if it matches their class + QUEST_PACKAGE_FILTER_UNMATCHED = 2, // Players can select this quest reward if no class/loot_spec rewards are available + QUEST_PACKAGE_FILTER_EVERYONE = 3 // Players can always select this quest reward +}; + enum SkillRaceClassInfoFlags { SKILL_FLAG_NO_SKILLUP_MESSAGE = 0x2, diff --git a/src/server/game/Entities/Item/ItemTemplate.cpp b/src/server/game/Entities/Item/ItemTemplate.cpp index e0e577f1d38..10d8272fca8 100644 --- a/src/server/game/Entities/Item/ItemTemplate.cpp +++ b/src/server/game/Entities/Item/ItemTemplate.cpp @@ -138,18 +138,18 @@ void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamag maxDamage = floor(float(avgDamage * (GetStatScalingFactor() * 0.5f + 1.0f) + 0.5f)); } -bool ItemTemplate::CanWinForPlayer(Player* plr) const +bool ItemTemplate::CanWinForPlayer(Player const* player) const { if (!Specializations.size()) return true; - uint32 spec = plr->GetSpecId(plr->GetActiveTalentGroup()); + uint32 spec = player->GetSpecId(player->GetActiveTalentGroup()); if (!spec) - spec = plr->GetDefaultSpecId(); + spec = player->GetDefaultSpecId(); if (!spec) return false; - + UsableTalentSpecs::const_iterator itr = Specializations.find(spec); return itr != Specializations.end(); } diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h index 3272de6ac5a..9ab04727ced 100644 --- a/src/server/game/Entities/Item/ItemTemplate.h +++ b/src/server/game/Entities/Item/ItemTemplate.h @@ -584,6 +584,7 @@ const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] = #define MIN_ITEM_LEVEL 1 #define MAX_ITEM_LEVEL 1000 +class Player; typedef std::set<uint32> UsableTalentSpecs; struct ItemTemplate @@ -704,7 +705,7 @@ struct ItemTemplate char const* GetDefaultLocaleName() const; uint32 GetArmor(uint32 itemLevel) const; void GetDamage(uint32 itemLevel, float& minDamage, float& maxDamage) const; - bool CanWinForPlayer(Player* plr) const; + bool CanWinForPlayer(Player const* player) const; }; // Benchmarked: Faster than std::map (insert/find) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 8305949b352..a720f7ed529 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -14442,23 +14442,25 @@ bool Player::CanRewardQuest(Quest const* quest, uint32 reward, bool msg) } } } - + // QuestPackageItem.db2 if (quest->GetQuestPackageID()) { - if (sQuestPackageItemStoreMap.find(quest->GetQuestPackageID()) != sQuestPackageItemStoreMap.end()) + if (std::vector<QuestPackageItemEntry const*> const* questPackageItems = sDB2Manager.GetQuestPackageItems(quest->GetQuestPackageID())) { - QuestPackageItemList itemList = sQuestPackageItemStoreMap[quest->GetQuestPackageID()]; - for (QuestPackageItemList::const_iterator itr = itemList.begin(); itr != itemList.end(); ++itr) + for (QuestPackageItemEntry const* questPackageItem : *questPackageItems) { - if (ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate((*itr)->ItemID)) + if (questPackageItem->ItemID != reward) + continue; + + if (ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID)) { if (rewardProto->CanWinForPlayer(this)) { - InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, (*itr)->ItemID, (*itr)->ItemCount); + InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemCount); if (res != EQUIP_ERR_OK) { - SendEquipError(res, NULL, NULL, (*itr)->ItemID); + SendEquipError(res, NULL, NULL, questPackageItem->ItemID); return false; } } @@ -14660,20 +14662,22 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, // QuestPackageItem.db2 if (quest->GetQuestPackageID()) { - if (sQuestPackageItemStoreMap.find(quest->GetQuestPackageID()) != sQuestPackageItemStoreMap.end()) + if (std::vector<QuestPackageItemEntry const*> const* questPackageItems = sDB2Manager.GetQuestPackageItems(quest->GetQuestPackageID())) { - QuestPackageItemList itemList = sQuestPackageItemStoreMap[quest->GetQuestPackageID()]; - for (QuestPackageItemList::const_iterator itr = itemList.begin(); itr != itemList.end(); ++itr) + for (QuestPackageItemEntry const* questPackageItem : *questPackageItems) { - if (ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate((*itr)->ItemID)) + if (questPackageItem->ItemID != reward) + continue; + + if (ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID)) { if (rewardProto->CanWinForPlayer(this)) { ItemPosCountVec dest; - if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, (*itr)->ItemID, (*itr)->ItemCount) == EQUIP_ERR_OK) + if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemCount) == EQUIP_ERR_OK) { - Item* item = StoreNewItem(dest, (*itr)->ItemID, true, Item::GenerateItemRandomPropertyId((*itr)->ItemID)); - SendNewItem(item, (*itr)->ItemCount, true, false); + Item* item = StoreNewItem(dest, questPackageItem->ItemID, true, Item::GenerateItemRandomPropertyId(questPackageItem->ItemID)); + SendNewItem(item, questPackageItem->ItemCount, true, false); } } } diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 5e73fb71ae8..d7ad9c71956 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -242,7 +242,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPackets::Quest::Quest Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID); if (!quest) return; - + // This is Real Item Entry, not slot id as pre 5.x if (packet.ItemChoiceID) { @@ -263,6 +263,27 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPackets::Quest::Quest } } + if (quest->GetQuestPackageID()) + { + if (std::vector<QuestPackageItemEntry const*> const* questPackageItems = sDB2Manager.GetQuestPackageItems(quest->GetQuestPackageID())) + { + for (QuestPackageItemEntry const* questPackageItem : *questPackageItems) + { + if (questPackageItem->ItemID != packet.ItemChoiceID) + continue; + + if (ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID)) + { + if (rewardProto->CanWinForPlayer(_player)) + { + itemValid = true; + break; + } + } + } + } + } + if (!itemValid) { TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (%s) tried to get reward item (Item Entry: %u) wich is not a reward for quest %u (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.ItemChoiceID, packet.QuestID); diff --git a/src/server/shared/Database/Implementation/HotfixDatabase.cpp b/src/server/shared/Database/Implementation/HotfixDatabase.cpp index 73441855483..e13863d9326 100644 --- a/src/server/shared/Database/Implementation/HotfixDatabase.cpp +++ b/src/server/shared/Database/Implementation/HotfixDatabase.cpp @@ -119,7 +119,7 @@ void HotfixDatabaseConnection::DoPrepareStatements() PrepareStatement(HOTFIX_SEL_PHASE_GROUP, "SELECT ID, PhaseID, PhaseGroupID FROM phase_group ORDER BY ID DESC", CONNECTION_SYNCH); // QuestPackageItem.db2 - PrepareStatement(HOTFIX_SEL_QUEST_PACKAGE_ITEM, "SELECT ID, QuestPackageID, ItemID, ItemCount, Unk FROM quest_package_item ORDER BY ID DESC", CONNECTION_SYNCH); + PrepareStatement(HOTFIX_SEL_QUEST_PACKAGE_ITEM, "SELECT ID, QuestPackageID, ItemID, ItemCount, FilterType FROM quest_package_item ORDER BY ID DESC", CONNECTION_SYNCH); // SoundEntries.db2 PrepareStatement(HOTFIX_SEL_SOUND_ENTRIES, "SELECT ID, SoundType, Name, FileDataID1, FileDataID2, FileDataID3, FileDataID4, FileDataID5, " |
