diff options
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index b304491ba31..d6fa46bb267 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5100,10 +5100,60 @@ SpellCastResult Spell::CheckCast(bool strict) } case SPELL_EFFECT_APPLY_GLYPH: { - uint32 glyphId = effect->MiscValue; - if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId)) - if (m_caster->HasAura(gp->SpellID)) - return SPELL_FAILED_UNIQUE_GLYPH; + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return SPELL_FAILED_GLYPH_NO_SPEC; + + Player* caster = m_caster->ToPlayer(); + if (!caster->HasSpell(m_misc.SpellId)) + return SPELL_FAILED_NOT_KNOWN; + + if (uint32 glyphId = effect->MiscValue) + { + GlyphPropertiesEntry const* glyphProperties = sGlyphPropertiesStore.LookupEntry(glyphId); + if (!glyphProperties) + return SPELL_FAILED_INVALID_GLYPH; + + std::vector<uint32> const* glyphBindableSpells = sDB2Manager.GetGlyphBindableSpells(glyphId); + if (!glyphBindableSpells) + return SPELL_FAILED_INVALID_GLYPH; + + if (std::find(glyphBindableSpells->begin(), glyphBindableSpells->end(), m_misc.SpellId) == glyphBindableSpells->end()) + return SPELL_FAILED_INVALID_GLYPH; + + if (std::vector<uint32> const* glyphRequiredSpecs = sDB2Manager.GetGlyphRequiredSpecs(glyphId)) + { + if (!caster->GetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID)) + return SPELL_FAILED_GLYPH_NO_SPEC; + + if (std::find(glyphRequiredSpecs->begin(), glyphRequiredSpecs->end(), caster->GetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID)) == glyphRequiredSpecs->end()) + return SPELL_FAILED_GLYPH_INVALID_SPEC; + } + + uint32 replacedGlyph = 0; + for (uint32 activeGlyphId : caster->GetGlyphs(caster->GetActiveTalentGroup())) + { + if (std::vector<uint32> const* activeGlyphBindableSpells = sDB2Manager.GetGlyphBindableSpells(activeGlyphId)) + { + if (std::find(activeGlyphBindableSpells->begin(), activeGlyphBindableSpells->end(), m_misc.SpellId) != activeGlyphBindableSpells->end()) + { + replacedGlyph = activeGlyphId; + break; + } + } + } + + for (uint32 activeGlyphId : caster->GetGlyphs(caster->GetActiveTalentGroup())) + { + if (activeGlyphId == replacedGlyph) + continue; + + if (activeGlyphId == glyphId) + return SPELL_FAILED_UNIQUE_GLYPH; + + if (sGlyphPropertiesStore.AssertEntry(activeGlyphId)->GlyphExclusiveCategoryID == glyphProperties->GlyphExclusiveCategoryID) + return SPELL_FAILED_GLYPH_EXCLUSIVE_CATEGORY; + } + } break; } case SPELL_EFFECT_FEED_PET: |