diff options
-rw-r--r-- | src/server/game/Entities/Item/ItemTemplate.cpp | 17 | ||||
-rw-r--r-- | src/server/game/Entities/Item/ItemTemplate.h | 7 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 2 |
5 files changed, 18 insertions, 14 deletions
diff --git a/src/server/game/Entities/Item/ItemTemplate.cpp b/src/server/game/Entities/Item/ItemTemplate.cpp index ebed45eaaac..e513c2f26dc 100644 --- a/src/server/game/Entities/Item/ItemTemplate.cpp +++ b/src/server/game/Entities/Item/ItemTemplate.cpp @@ -197,19 +197,20 @@ void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamag maxDamage = floor(float(avgDamage * (GetStatScalingFactor() * 0.5f + 1.0f) + 0.5f)); } -bool ItemTemplate::CanWinForPlayer(Player const* player) const +bool ItemTemplate::IsUsableBySpecialization(Player const* player) const { - std::unordered_set<uint32> const& specs = Specializations[player->getLevel() > 40]; - if (specs.empty()) - return true; - uint32 spec = player->GetSpecId(player->GetActiveTalentGroup()); if (!spec) spec = player->GetDefaultSpecId(); - if (!spec) + ChrSpecializationEntry const* chrSpecialization = sChrSpecializationStore.LookupEntry(spec); + if (!chrSpecialization) return false; - auto itr = specs.find(spec); - return itr != specs.end(); + return Specializations[player->getLevel() > 40].test(CalculateItemSpecBit(chrSpecialization)); +} + +std::size_t ItemTemplate::CalculateItemSpecBit(ChrSpecializationEntry const* spec) +{ + return (spec->ClassID - 1) * MAX_SPECIALIZATIONS + spec->OrderIndex; } diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h index 76c129d325a..3ad9189c6aa 100644 --- a/src/server/game/Entities/Item/ItemTemplate.h +++ b/src/server/game/Entities/Item/ItemTemplate.h @@ -21,6 +21,7 @@ #include "DB2Structure.h" #include "SharedDefines.h" +#include <bitset> enum ItemModType { @@ -643,6 +644,7 @@ const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] = #define MAX_ITEM_LEVEL 1000 class Player; +struct ChrSpecializationEntry; struct TC_GAME_API ItemTemplate { @@ -716,7 +718,7 @@ struct TC_GAME_API ItemTemplate uint32 MaxMoneyLoot; uint32 FlagsCu; float SpellPPMRate; - std::unordered_set<uint32> Specializations[2]; // one set for 1-40 level range and another for 41-100 + std::bitset<MAX_CLASSES * MAX_SPECIALIZATIONS> Specializations[2]; // one set for 1-40 level range and another for 41-100 // helpers bool CanChangeEquipStateInCombat() const; @@ -745,7 +747,8 @@ struct TC_GAME_API ItemTemplate char const* GetDefaultLocaleName() const; uint32 GetArmor(uint32 itemLevel) const; void GetDamage(uint32 itemLevel, float& minDamage, float& maxDamage) const; - bool CanWinForPlayer(Player const* player) const; + bool IsUsableBySpecialization(Player const* player) const; + static std::size_t CalculateItemSpecBit(ChrSpecializationEntry const* spec); }; // 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 b60dce4f668..2875d3a2d5a 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -14064,7 +14064,7 @@ bool Player::CanRewardQuest(Quest const* quest, uint32 reward, bool msg) if (ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID)) { - if (rewardProto->CanWinForPlayer(this)) + if (rewardProto->IsUsableBySpecialization(this)) { InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemCount); if (res != EQUIP_ERR_OK) @@ -14285,7 +14285,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, if (ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID)) { - if (rewardProto->CanWinForPlayer(this)) + if (rewardProto->IsUsableBySpecialization(this)) { ItemPosCountVec dest; if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemCount) == EQUIP_ERR_OK) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 9cae9926477..985c8bc7c89 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2677,7 +2677,7 @@ void ObjectMgr::LoadItemTemplates() if (ChrSpecializationEntry const* specialization = sChrSpecializationStore.LookupEntry(itemSpec->SpecID)) if ((1 << (specialization->ClassID - 1)) & sparse->AllowableClass) - itemTemplate.Specializations[itemSpec->MaxLevel > 40].insert(itemSpec->SpecID); + itemTemplate.Specializations[itemSpec->MaxLevel > 40].set(ItemTemplate::CalculateItemSpecBit(specialization)); } } } diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index bfa0bc3db16..6ef966a2340 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -285,7 +285,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPackets::Quest::Quest rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID); if (rewardProto) { - if (rewardProto->CanWinForPlayer(_player)) + if (rewardProto->IsUsableBySpecialization(_player)) { itemValid = true; break; |