diff options
author | Shauren <shauren.trinity@gmail.com> | 2024-12-05 14:08:37 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2024-12-05 14:08:37 +0100 |
commit | 243314806ff10d9cd4a7595cb48a7bb5878058d6 (patch) | |
tree | b0c9d758643c6d2516b4820284ad2580ed0db7ab | |
parent | 65e2474ff264e40f579ce2aa29921e9d72c75c6f (diff) |
Core/Spells: Fixed item level requirements for enchanting spells
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 30 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 2 | ||||
-rw-r--r-- | src/server/shared/SharedDefines.h | 2 | ||||
-rw-r--r-- | src/server/shared/enuminfo_SharedDefines.cpp | 6 |
4 files changed, 27 insertions, 13 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 53be3ce0f1b..4251ccc3e17 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -6889,9 +6889,19 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 / if (!targetItem) return SPELL_FAILED_ITEM_NOT_FOUND; - // required level has to be checked also! Exploit fix - if (targetItem->GetTemplate()->ItemLevel < m_spellInfo->BaseLevel || (targetItem->GetTemplate()->RequiredLevel && targetItem->GetTemplate()->RequiredLevel < m_spellInfo->BaseLevel)) - return SPELL_FAILED_LOWLEVEL; + // Apply item level restriction + if (!m_spellInfo->HasAttribute(SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF)) + { + uint32 requiredLevel = targetItem->GetTemplate()->RequiredLevel; + if (!requiredLevel) + requiredLevel = targetItem->GetTemplate()->ItemLevel; + + if (requiredLevel < m_spellInfo->BaseLevel) + return SPELL_FAILED_LOWLEVEL; + } + if (m_CastItem + && m_spellInfo->MaxLevel > 0 && targetItem->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel) + return SPELL_FAILED_HIGHLEVEL; bool isItemUsable = false; for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e) @@ -6959,14 +6969,18 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 / return SPELL_FAILED_NOT_TRADEABLE; } - // Apply item level restriction if the enchanting spell has max level restrition set - if (m_CastItem && m_spellInfo->MaxLevel > 0) + // Apply item level restriction + if (!m_spellInfo->HasAttribute(SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF)) { - if (item->GetTemplate()->ItemLevel < m_CastItem->GetTemplate()->RequiredLevel) + uint32 requiredLevel = item->GetTemplate()->RequiredLevel; + if (!requiredLevel) + requiredLevel = item->GetTemplate()->ItemLevel; + + if (requiredLevel < m_spellInfo->BaseLevel) return SPELL_FAILED_LOWLEVEL; - if (item->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel) - return SPELL_FAILED_HIGHLEVEL; } + if (m_CastItem && m_spellInfo->MaxLevel > 0 && item->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel) + return SPELL_FAILED_HIGHLEVEL; break; } case SPELL_EFFECT_ENCHANT_HELD_ITEM: diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index d308b1ff023..6f080491ef8 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -3361,7 +3361,7 @@ SpellInfo const* SpellInfo::GetAuraRankForLevel(uint8 level) const return this; // Client ignores spell with these attributes (sub_53D9D0) - if (HasAttribute(SPELL_ATTR0_NEGATIVE_1) || HasAttribute(SPELL_ATTR2_UNK3) || HasAttribute(SPELL_ATTR3_DRAIN_SOUL)) + if (HasAttribute(SPELL_ATTR0_NEGATIVE_1) || HasAttribute(SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF) || HasAttribute(SPELL_ATTR3_DRAIN_SOUL)) return this; bool needRankSelection = false; diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index e255a05f42f..e2f6fc37774 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -480,7 +480,7 @@ enum SpellAttr2 : uint32 SPELL_ATTR2_CAN_TARGET_DEAD = 0x00000001, // TITLE Can target dead players or corpses SPELL_ATTR2_UNK1 = 0x00000002, // TITLE Unknown attribute 1@Attr2 SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS = 0x00000004, // TITLE Ignore Line of Sight - SPELL_ATTR2_UNK3 = 0x00000008, // TITLE Ignore aura scaling + SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF = 0x00000008, // TITLE Allow Low Level Buff SPELL_ATTR2_DISPLAY_IN_STANCE_BAR = 0x00000010, // TITLE Show in stance bar (client only) SPELL_ATTR2_AUTOREPEAT_FLAG = 0x00000020, // TITLE Ranged auto-attack spell SPELL_ATTR2_CANT_TARGET_TAPPED = 0x00000040, // TITLE Cannot target others' tapped units DESCRIPTION Can only target untapped units, or those tapped by caster diff --git a/src/server/shared/enuminfo_SharedDefines.cpp b/src/server/shared/enuminfo_SharedDefines.cpp index c29d65018a6..61e776be136 100644 --- a/src/server/shared/enuminfo_SharedDefines.cpp +++ b/src/server/shared/enuminfo_SharedDefines.cpp @@ -529,7 +529,7 @@ TC_API_EXPORT EnumText EnumUtils<SpellAttr2>::ToString(SpellAttr2 value) case SPELL_ATTR2_CAN_TARGET_DEAD: return { "SPELL_ATTR2_CAN_TARGET_DEAD", "Can target dead players or corpses", "" }; case SPELL_ATTR2_UNK1: return { "SPELL_ATTR2_UNK1", "Unknown attribute 1@Attr2", "" }; case SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS: return { "SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS", "Ignore Line of Sight", "" }; - case SPELL_ATTR2_UNK3: return { "SPELL_ATTR2_UNK3", "Ignore aura scaling", "" }; + case SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF: return { "SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF", "Allow Low Level Buff", "" }; case SPELL_ATTR2_DISPLAY_IN_STANCE_BAR: return { "SPELL_ATTR2_DISPLAY_IN_STANCE_BAR", "Show in stance bar (client only)", "" }; case SPELL_ATTR2_AUTOREPEAT_FLAG: return { "SPELL_ATTR2_AUTOREPEAT_FLAG", "Ranged auto-attack spell", "" }; case SPELL_ATTR2_CANT_TARGET_TAPPED: return { "SPELL_ATTR2_CANT_TARGET_TAPPED", "Cannot target others' tapped units", "Can only target untapped units, or those tapped by caster" }; @@ -573,7 +573,7 @@ TC_API_EXPORT SpellAttr2 EnumUtils<SpellAttr2>::FromIndex(size_t index) case 0: return SPELL_ATTR2_CAN_TARGET_DEAD; case 1: return SPELL_ATTR2_UNK1; case 2: return SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS; - case 3: return SPELL_ATTR2_UNK3; + case 3: return SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF; case 4: return SPELL_ATTR2_DISPLAY_IN_STANCE_BAR; case 5: return SPELL_ATTR2_AUTOREPEAT_FLAG; case 6: return SPELL_ATTR2_CANT_TARGET_TAPPED; @@ -614,7 +614,7 @@ TC_API_EXPORT size_t EnumUtils<SpellAttr2>::ToIndex(SpellAttr2 value) case SPELL_ATTR2_CAN_TARGET_DEAD: return 0; case SPELL_ATTR2_UNK1: return 1; case SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS: return 2; - case SPELL_ATTR2_UNK3: return 3; + case SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF: return 3; case SPELL_ATTR2_DISPLAY_IN_STANCE_BAR: return 4; case SPELL_ATTR2_AUTOREPEAT_FLAG: return 5; case SPELL_ATTR2_CANT_TARGET_TAPPED: return 6; |