Instead mark spell as delatable mark it as executed and referenced from Unit current spells array and not deleted spell in like cases.

This is solve crashs if spell deleted at caster die in result triggered spells casting chain from currently executed spell.
This commit is contained in:
VladimirMangos 2008-11-03 01:09:18 +03:00
parent 322b201c4d
commit ed7390dede
7 changed files with 61 additions and 25 deletions

View file

@ -268,7 +268,8 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
m_caster = Caster;
m_selfContainer = NULL;
m_triggeringContainer = triggeringContainer;
m_deletable = true;
m_referencedFromCurrentSpell = false;
m_executedCurrently = false;
m_delayAtDamageCount = 0;
m_applyMultiplierMask = 0;
@ -2019,6 +2020,8 @@ void Spell::cancel()
void Spell::cast(bool skipCheck)
{
SetExecutedCurrently(true);
uint8 castResult = 0;
// update pointers base at GUIDs to prevent access to non-existed already object
@ -2028,6 +2031,7 @@ void Spell::cast(bool skipCheck)
if(!m_targets.getUnitTarget() && m_targets.getUnitTargetGUID() && m_targets.getUnitTargetGUID() != m_caster->GetGUID())
{
cancel();
SetExecutedCurrently(false);
return;
}
@ -2039,6 +2043,7 @@ void Spell::cast(bool skipCheck)
{
SendCastResult(castResult);
finish(false);
SetExecutedCurrently(false);
return;
}
@ -2050,6 +2055,7 @@ void Spell::cast(bool skipCheck)
{
SendCastResult(castResult);
finish(false);
SetExecutedCurrently(false);
return;
}
}
@ -2082,7 +2088,10 @@ void Spell::cast(bool skipCheck)
FillTargetMap();
if(m_spellState == SPELL_STATE_FINISHED) // stop cast if spell marked as finish somewhere in Take*/FillTargetMap
{
SetExecutedCurrently(false);
return;
}
SendCastResult(castResult);
SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
@ -2114,6 +2123,8 @@ void Spell::cast(bool skipCheck)
// Immediate spell, no big deal
handle_immediate();
}
SetExecutedCurrently(false);
}
void Spell::handle_immediate()
@ -5063,3 +5074,8 @@ void SpellEvent::Abort(uint64 /*e_time*/)
if (m_Spell->getState() != SPELL_STATE_FINISHED)
m_Spell->cancel();
}
bool SpellEvent::IsDeletable() const
{
return m_Spell->IsDeletable();
}