aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2018-01-01 17:17:49 -0300
committerariel- <ariel-@users.noreply.github.com>2018-01-01 17:18:00 -0300
commit5e284d4b3826cd345193298688c1d2bc5b3c8f72 (patch)
treeb9fbba9138c57a1a8c53263255a6ad5962b37148 /src
parent90f7fe609ac980883cab7dfd5eb68cf497f7bf92 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp7
-rw-r--r--src/server/game/Spells/Spell.cpp23
2 files changed, 17 insertions, 13 deletions
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<int32> *spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
+ if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
{
- for (std::vector<int32>::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