diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Item/ItemTemplate.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Player/PlayerStorage.cpp | 72 | ||||
-rw-r--r-- | src/server/game/Handlers/ItemHandler.cpp | 64 |
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); |