From 0ae2133254f9a3ebe178ea9a38bd9dde2ddc4002 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 16 Nov 2008 23:29:08 +0300 Subject: [PATCH] [6833] More correct aura cancel for channeled spells. Remove auras at channeled target. Cancel channeled spell at spell aura cancel. Also move battleground resurection spell code to more appropriate place. --- src/game/SpellAuras.cpp | 11 ++++++++ src/game/SpellHandler.cpp | 22 ++++++++++----- src/game/Unit.cpp | 59 +++++++++++++++++++++++++++++++-------- src/game/Unit.h | 1 + src/shared/revision_nr.h | 2 +- 5 files changed, 76 insertions(+), 19 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 82770dfd0..fbb1d2e84 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2010,6 +2010,17 @@ void Aura::HandleAuraDummy(bool apply, bool Real) caster->CastSpell(m_target,finalSpelId,true,NULL,this); return; } + + // Waiting to Resurrect + if(GetId()==2584) + { + // Waiting to resurrect spell cancel, we must remove player from resurrect queue + if(m_target->GetTypeId() == TYPEID_PLAYER) + if(BattleGround *bg = ((Player*)m_target)->GetBattleGround()) + bg->RemovePlayerFromResurrectQueue(m_target->GetGUID()); + return; + } + // Dark Fiend if(GetId()==45934) { diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 773ae004f..ecc17cf70 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -355,15 +355,23 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket) if(!IsPositiveSpell(spellId) || (spellInfo->Attributes & SPELL_ATTR_CANT_CANCEL)) return; - _player->RemoveAurasDueToSpellByCancel(spellId); - - if (spellId == 2584) // Waiting to resurrect spell cancel, we must remove player from resurrect queue + // channeled spell case (it currently casted then) + if(IsChanneledSpell(spellInfo)) { - BattleGround *bg = _player->GetBattleGround(); - if(!bg) - return; - bg->RemovePlayerFromResurrectQueue(_player->GetGUID()); + if(Spell* spell = _player->m_currentSpells[CURRENT_CHANNELED_SPELL]) + { + if(spell->m_spellInfo->Id==spellId) + { + spell->cancel(); + spell->SetReferencedFromCurrent(false); + _player->m_currentSpells[CURRENT_CHANNELED_SPELL] = NULL; + } + } + return; } + + // non channeled case + _player->RemoveAurasDueToSpellByCancel(spellId); } void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 30d4f9e17..4bd6e5fe8 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4098,12 +4098,17 @@ void Unit::RemoveNotOwnSingleTargetAuras() void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) { - if (IsSingleTargetSpell((*i).second->GetSpellProto())) + Aura* Aur = i->second; + SpellEntry const* AurSpellInfo = Aur->GetSpellProto(); + + Unit* caster = NULL; + if (IsSingleTargetSpell(AurSpellInfo)) { - if(Unit* caster = (*i).second->GetCaster()) + caster = Aur->GetCaster(); + if(!caster) { AuraList& scAuras = caster->GetSingleCastAuras(); - scAuras.remove((*i).second); + scAuras.remove(Aur); } else { @@ -4112,13 +4117,12 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) } } - if ((*i).second->GetModifier()->m_auraname < TOTAL_AURAS) + // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order) + if (Aur->GetModifier()->m_auraname < TOTAL_AURAS) { - m_modAuras[(*i).second->GetModifier()->m_auraname].remove((*i).second); + m_modAuras[Aur->GetModifier()->m_auraname].remove(Aur); } - // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order) - Aura* Aur = i->second; // Set remove mode Aur->SetRemoveMode(mode); // some ShapeshiftBoosts at remove trigger removing other auras including parent Shapeshift aura @@ -4126,18 +4130,31 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) m_Auras.erase(i); ++m_removedAuras; // internal count used by unit update - // Status unsummoned at aura remove + // Statue unsummoned at aura remove Totem* statue = NULL; - if(IsChanneledSpell(Aur->GetSpellProto())) - if(Unit* caster = Aur->GetCaster()) + bool caster_channeled = false; + if(IsChanneledSpell(AurSpellInfo)) + { + if(!caster) // can be already located for IsSingleTargetSpell case + caster = Aur->GetCaster(); + + if(caster) + { if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE) statue = ((Totem*)caster); + else + caster_channeled = caster==this; + } + } sLog.outDebug("Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode); Aur->ApplyModifier(false,true); Aur->_RemoveAura(); delete Aur; + if(caster_channeled) + RemoveAurasAtChanneledTarget (AurSpellInfo); + if(statue) statue->UnSummon(); @@ -10859,4 +10876,24 @@ bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura ) // heal CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid); return true; -} \ No newline at end of file +} + +void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo) +{ + uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT); + + if(!IS_UNIT_GUID(target_guid)) + return; + + Unit* target = ObjectAccessor::GetUnit(*this, target_guid); + if(!target) + return; + + for (AuraMap::iterator iter = target->GetAuras().begin(); iter != target->GetAuras().end(); ) + { + if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID()==GetGUID()) + target->RemoveAura(iter); + else + ++iter; + } +} diff --git a/src/game/Unit.h b/src/game/Unit.h index 9447c5d93..a81308c51 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -997,6 +997,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler); void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer); void RemoveAurasDueToSpellByCancel(uint32 spellId); + void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo); void RemoveNotOwnSingleTargetAuras(); void RemoveSpellsCausingAura(AuraType auraType); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d2d1ba018..1cf8f518c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "6832" + #define REVISION_NR "6833" #endif // __REVISION_NR_H__