From 5e284d4b3826cd345193298688c1d2bc5b3c8f72 Mon Sep 17 00:00:00 2001 From: ariel- Date: Mon, 1 Jan 2018 17:17:49 -0300 Subject: Core/Entities: fix crash - m_currentSpells and spell would be different in case cancelation of a channeled spell would remove the aura, and aura scripted to cast another channeled spell on remove - In the above situation, we would lose reference of currentSpell and remove reference from wrong one, this was fixed by clearing the pointer before spell cancelation. Closes #20172 --- src/server/game/Entities/Unit/Unit.cpp | 7 ++++--- src/server/game/Spells/Spell.cpp | 23 +++++++++++++---------- 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index b3eed68c6a1..41e6d255baf 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3146,11 +3146,12 @@ void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool wi if (GetTypeId() == TYPEID_PLAYER) ToPlayer()->SendAutoRepeatCancel(this); + m_currentSpells[spellType] = nullptr; + if (spell->getState() != SPELL_STATE_FINISHED) spell->cancel(); - - m_currentSpells[spellType] = nullptr; - spell->SetReferencedFromCurrent(false); + else + spell->SetReferencedFromCurrent(false); } } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 1ba7bebbc38..b6f368d3a56 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3339,13 +3339,15 @@ void Spell::_cast(bool skipCheck) CallScriptAfterCastHandlers(); - if (const std::vector *spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id)) + if (std::vector const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id)) { - for (std::vector::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i) - if (*i < 0) - m_caster->RemoveAurasDueToSpell(-(*i)); + for (int32 id : *spell_triggered) + { + if (id < 0) + m_caster->RemoveAurasDueToSpell(-id); else - m_caster->CastSpell(m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : m_caster, *i, true); + m_caster->CastSpell(m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : m_caster, id, true); + } } if (modOwner) @@ -7122,8 +7124,8 @@ bool SpellEvent::Execute(uint64 e_time, uint32 p_time) return true; // spell is deletable, finish event } // event will be re-added automatically at the end of routine) - } break; - + break; + } case SPELL_STATE_DELAYED: { // first, check, if we have just started @@ -7177,13 +7179,14 @@ bool SpellEvent::Execute(uint64 e_time, uint32 p_time) m_Spell->GetCaster()->m_Events.AddEvent(this, e_time + m_Spell->GetDelayMoment(), false); return false; // event not complete } - } break; - + break; + } default: { // all other states // event will be re-added automatically at the end of routine) - } break; + break; + } } // spell processing not complete, plan event on the next update interval -- cgit v1.2.3