summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Item/ItemTemplate.h3
-rw-r--r--src/server/game/Entities/Player/PlayerStorage.cpp72
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp64
3 files changed, 110 insertions, 29 deletions
diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h
index f11b3fc723..a256d04715 100644
--- a/src/server/game/Entities/Item/ItemTemplate.h
+++ b/src/server/game/Entities/Item/ItemTemplate.h
@@ -817,6 +817,9 @@ struct ItemTemplate
[[nodiscard]] bool IsArmorVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT; }
[[nodiscard]] bool IsConjuredConsumable() const { return Class == ITEM_CLASS_CONSUMABLE && (Flags & ITEM_FLAG_CONJURED); }
+ [[nodiscard]] bool HasStat(ItemModType stat) const;
+ [[nodiscard]] bool HasSpellPowerStat() const;
+
void InitializeQueryData();
};
diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp
index 9f8dcd9189..dedc3ccb17 100644
--- a/src/server/game/Entities/Player/PlayerStorage.cpp
+++ b/src/server/game/Entities/Player/PlayerStorage.cpp
@@ -2353,13 +2353,13 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje
// Used by group, function NeedBeforeGreed, to know if a prototype can be used by a player
const static uint32 item_weapon_skills[MAX_ITEM_SUBCLASS_WEAPON] =
- {
- SKILL_AXES, SKILL_2H_AXES, SKILL_BOWS, SKILL_GUNS, SKILL_MACES,
- SKILL_2H_MACES, SKILL_POLEARMS, SKILL_SWORDS, SKILL_2H_SWORDS, 0,
- SKILL_STAVES, 0, 0, SKILL_FIST_WEAPONS, 0,
- SKILL_DAGGERS, SKILL_THROWN, SKILL_ASSASSINATION, SKILL_CROSSBOWS, SKILL_WANDS,
- SKILL_FISHING
- }; //Copy from function Item::GetSkill()
+ {
+ SKILL_AXES, SKILL_2H_AXES, SKILL_BOWS, SKILL_GUNS, SKILL_MACES,
+ SKILL_2H_MACES, SKILL_POLEARMS, SKILL_SWORDS, SKILL_2H_SWORDS, 0,
+ SKILL_STAVES, 0, 0, SKILL_FIST_WEAPONS,0,
+ SKILL_DAGGERS, SKILL_THROWN, SKILL_ASSASSINATION, SKILL_CROSSBOWS, SKILL_WANDS,
+ SKILL_FISHING
+ }; //Copy from function Item::GetSkill()
if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getRaceMask()) == 0)
return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
@@ -2380,36 +2380,50 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje
if (proto->Class == ITEM_CLASS_WEAPON && GetSkillValue(item_weapon_skills[proto->SubClass]) == 0)
return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
- if (proto->Class == ITEM_CLASS_ARMOR && proto->SubClass > ITEM_SUBCLASS_ARMOR_MISC && proto->SubClass < ITEM_SUBCLASS_ARMOR_BUCKLER && proto->InventoryType != INVTYPE_CLOAK)
+ if (proto->Class == ITEM_CLASS_ARMOR && proto->SubClass > ITEM_SUBCLASS_ARMOR_MISC && proto->SubClass < ITEM_SUBCLASS_ARMOR_BUCKLER &&
+ proto->InventoryType != INVTYPE_CLOAK)
{
- if (_class == CLASS_WARRIOR || _class == CLASS_PALADIN || _class == CLASS_DEATH_KNIGHT)
+ uint32 subclassToCompare = ITEM_SUBCLASS_ARMOR_CLOTH;
+ switch (_class)
{
- if (getLevel() < 40)
- {
- if (proto->SubClass != ITEM_SUBCLASS_ARMOR_MAIL)
+ case CLASS_WARRIOR:
+ if (proto->HasStat(ITEM_MOD_SPELL_POWER) || proto->HasSpellPowerStat())
+ {
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
- }
- else if (proto->SubClass != ITEM_SUBCLASS_ARMOR_PLATE)
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ }
+ [[fallthrough]];
+ case CLASS_DEATH_KNIGHT:
+ case CLASS_PALADIN:
+ subclassToCompare = ITEM_SUBCLASS_ARMOR_PLATE;
+ break;
+ case CLASS_HUNTER:
+ case CLASS_SHAMAN:
+ subclassToCompare = ITEM_SUBCLASS_ARMOR_MAIL;
+ break;
+ case CLASS_ROGUE:
+ if (proto->HasStat(ITEM_MOD_SPELL_POWER) || proto->HasSpellPowerStat())
+ {
+ return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ }
+ [[fallthrough]];
+ case CLASS_DRUID:
+ subclassToCompare = ITEM_SUBCLASS_ARMOR_LEATHER;
+ break;
+ default:
+ break;
}
- else if (_class == CLASS_HUNTER || _class == CLASS_SHAMAN)
+
+ if (proto->SubClass > subclassToCompare)
{
- if (getLevel() < 40)
+ return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ }
+ else if (proto->ItemLevel > 70)
+ {
+ if (proto->SubClass < subclassToCompare)
{
- if (proto->SubClass != ITEM_SUBCLASS_ARMOR_LEATHER)
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
- }
- else if (proto->SubClass != ITEM_SUBCLASS_ARMOR_MAIL)
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ }
}
-
- if (_class == CLASS_ROGUE || _class == CLASS_DRUID)
- if (proto->SubClass != ITEM_SUBCLASS_ARMOR_LEATHER)
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
-
- if (_class == CLASS_MAGE || _class == CLASS_PRIEST || _class == CLASS_WARLOCK)
- if (proto->SubClass != ITEM_SUBCLASS_ARMOR_CLOTH)
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
}
return EQUIP_ERR_OK;
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 2b799c5bb5..00266fe87a 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -290,6 +290,70 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket& recvData)
_player->DestroyItem(bag, slot, true);
}
+bool ItemTemplate::HasStat(ItemModType stat) const
+{
+ for (uint8 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
+ {
+ if (i >= StatsCount)
+ {
+ break;
+ }
+
+ if (ItemStat[i].ItemStatType == stat)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ItemTemplate::HasSpellPowerStat() const
+{
+ bool invalid = false;
+ for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
+ {
+ _Spell const& spellData = Spells[i];
+ if (!spellData.SpellId)
+ {
+ continue;
+ }
+
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellData.SpellId);
+ if (!spellInfo)
+ {
+ continue;
+ }
+
+ for (uint8 j = EFFECT_0; j <= EFFECT_2; ++j)
+ {
+ switch (spellInfo->Effects[j].ApplyAuraName)
+ {
+ case SPELL_AURA_MOD_HEALING_DONE:
+ case SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT:
+ case SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER:
+ case SPELL_AURA_MOD_HEALING:
+ invalid = true;
+ break;
+ case SPELL_AURA_MOD_DAMAGE_DONE:
+ case SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT:
+ case SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER:
+ case SPELL_AURA_MOD_DAMAGE_TAKEN:
+ if (!(spellInfo->Effects[j].MiscValue & SPELL_SCHOOL_MASK_SPELL))
+ {
+ return false;
+ }
+ invalid = true;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return invalid;
+}
+
void ItemTemplate::InitializeQueryData()
{
queryData.Initialize(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 1);