aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Spells')
-rw-r--r--src/server/game/Spells/Spell.cpp58
-rw-r--r--src/server/game/Spells/Spell.h4
-rw-r--r--src/server/game/Spells/SpellEffects.cpp35
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*/)