diff options
Diffstat (limited to 'src/server/game/Spells')
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 58 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.h | 4 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 35 |
3 files changed, 92 insertions, 5 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: diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 33e3107dc03..1fa5fa6aa08 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -570,7 +570,9 @@ class TC_GAME_API Spell { // Alternate names for this value uint32 TalentId; - uint32 GlyphSlot; + + // SPELL_EFFECT_APPLY_GLYPH + uint32 SpellId; // SPELL_EFFECT_TALENT_SPEC_SELECT uint32 SpecializationId; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index e2656495467..0df4abea54f 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -61,6 +61,7 @@ #include "DuelPackets.h" #include "MiscPackets.h" #include "SpellPackets.h" +#include "TalentPackets.h" pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= { @@ -3923,6 +3924,40 @@ void Spell::EffectApplyGlyph(SpellEffIndex /*effIndex*/) Player* player = m_caster->ToPlayer(); if (!player) return; + + std::vector<uint32>& glyphs = player->GetGlyphs(player->GetActiveTalentGroup()); + std::size_t replacedGlyph = glyphs.size(); + for (std::size_t i = 0; i < glyphs.size(); ++i) + { + if (std::vector<uint32> const* activeGlyphBindableSpells = sDB2Manager.GetGlyphBindableSpells(glyphs[i])) + { + if (std::find(activeGlyphBindableSpells->begin(), activeGlyphBindableSpells->end(), m_misc.SpellId) != activeGlyphBindableSpells->end()) + { + replacedGlyph = i; + player->RemoveAurasDueToSpell(sGlyphPropertiesStore.AssertEntry(glyphs[i])->SpellID); + break; + } + } + } + + uint32 glyphId = effectInfo->MiscValue; + if (replacedGlyph < glyphs.size()) + { + if (glyphId) + glyphs[replacedGlyph] = glyphId; + else + glyphs.erase(glyphs.begin() + replacedGlyph); + } + else if (glyphId) + glyphs.push_back(glyphId); + + if (GlyphPropertiesEntry const* glyphProperties = sGlyphPropertiesStore.LookupEntry(glyphId)) + player->CastSpell(player, glyphProperties->SpellID, true); + + WorldPackets::Talent::ActiveGlyphs activeGlyphs; + activeGlyphs.Glyphs.emplace_back(m_misc.SpellId, uint16(glyphId)); + activeGlyphs.IsFullUpdate = false; + player->SendDirectMessage(activeGlyphs.Write()); } void Spell::EffectEnchantHeldItem(SpellEffIndex /*effIndex*/) |
