aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Item/ItemTemplate.cpp17
-rw-r--r--src/server/game/Entities/Item/ItemTemplate.h7
-rw-r--r--src/server/game/Entities/Player/Player.cpp4
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp2
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp2
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;