diff options
-rw-r--r-- | src/game/Spell.cpp | 64 | ||||
-rw-r--r-- | src/game/Spell.h | 2 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 34 | ||||
-rw-r--r-- | src/game/SpellAuras.h | 7 | ||||
-rw-r--r-- | src/game/Unit.cpp | 50 |
5 files changed, 70 insertions, 87 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 5bc50b2b9d4..8ba4df32e79 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -33,6 +33,7 @@ #include "Player.h" #include "Pet.h" #include "Unit.h" +#include "Totem.h" #include "Spell.h" #include "DynamicObject.h" #include "Group.h" @@ -1268,13 +1269,19 @@ void Spell::DoAllEffectOnTarget(ItemTargetInfo *target) HandleEffects(NULL, target->item, NULL, effectNumber); } -bool Spell::IsAliveUnitPresentInTargetList() +bool Spell::UpdateChanneledTargetList() { // Not need check return true if (m_needAliveTargetMask == 0) return true; uint8 needAliveTargetMask = m_needAliveTargetMask; + uint8 needAuraMask = 0; + for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i) + if (m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA) + needAuraMask |= 1<<i; + + needAuraMask &= needAliveTargetMask; for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) { @@ -1283,7 +1290,24 @@ bool Spell::IsAliveUnitPresentInTargetList() Unit *unit = m_caster->GetGUID()==ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID); if (unit && unit->isAlive()) + { + if (needAuraMask & ihit->effectMask) + { + if(Aura * aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID())) + { + if (m_caster != unit && !m_caster->IsWithinDistInMap(unit,m_caster->GetSpellMaxRangeForTarget(unit,GetSpellRangeStore()->LookupEntry(m_spellInfo->rangeIndex)))) + { + ihit->effectMask &= ~aur->GetEffectMask(); + unit->RemoveAura(aur); + continue; + } + } + else + continue; + } + needAliveTargetMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target + } } } @@ -2601,8 +2625,9 @@ void Spell::update(uint32 difftime) } // check if there are alive targets left - if (!IsAliveUnitPresentInTargetList()) + if (!UpdateChanneledTargetList()) { + sLog.outError("Spell cancel"); SendChannelUpdate(0); finish(); } @@ -2663,7 +2688,6 @@ void Spell::finish(bool ok) if(m_spellState == SPELL_STATE_FINISHED) return; - m_spellState = SPELL_STATE_FINISHED; if(IsChanneledSpell(m_spellInfo)) @@ -2672,6 +2696,40 @@ void Spell::finish(bool ok) if(!m_caster->IsNonMeleeSpellCasted(false, false, true)) m_caster->clearUnitState(UNIT_STAT_CASTING); + // Unsummon summon as possessed creatures on spell cancel + if(IsChanneledSpell(m_spellInfo) + && m_caster->m_currentSpells[CURRENT_CHANNELED_SPELL] == this + && m_caster->GetTypeId() == TYPEID_PLAYER) + { + if (Unit * charm = m_caster->GetCharm()) + for(int i = 0; i < 3; ++i) + { + if(m_spellInfo->Effect[i] == SPELL_EFFECT_SUMMON) + if(SummonPropertiesEntry const *SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i])) + if(SummonProperties->Category == SUMMON_CATEGORY_POSSESSED) + { + if(charm->GetTypeId() == TYPEID_UNIT) + { + if(((Creature*)charm)->isPet() && ((Pet*)charm)->getPetType() == POSSESSED_PET) + ((Pet*)charm)->Remove(PET_SAVE_AS_DELETED); + break; + } + } + } + } + else if (m_caster->GetTypeId()==TYPEID_UNIT && ((Creature*)m_caster)->isSummon()) + { + // Unsummon statue + uint32 spell = m_caster->GetUInt32Value(UNIT_CREATED_BY_SPELL); + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell ); + if (spellInfo && spellInfo->SpellIconID==2056) + { + sLog.outDebug("Statue %d is unsummoned in spell %d finish", m_caster->GetGUIDLow(), m_spellInfo->Id); + m_caster->setDeathState(JUST_DIED); + return; + } + } + // other code related only to successfully finished spells if(!ok) return; diff --git a/src/game/Spell.h b/src/game/Spell.h index e2724d5f3e4..cc4fed8c320 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -589,7 +589,7 @@ class Spell void DoSpellHitOnUnit(Unit *unit, uint32 effectMask); void DoAllEffectOnTarget(GOTargetInfo *target); void DoAllEffectOnTarget(ItemTargetInfo *target); - bool IsAliveUnitPresentInTargetList(); + bool UpdateChanneledTargetList(); void SearchAreaTarget(std::list<Unit*> &data, float radius, const uint32 &type, SpellTargets TargetType, uint32 entry = 0); void SearchChainTarget(std::list<Unit*> &data, float radius, uint32 unMaxTargets, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index ea3746e8b46..bd39d167716 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -376,7 +376,6 @@ m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),m_aura //damage = caster->CalculateSpellDamage(m_spellProto,m_effIndex,m_currentBasePoints,target); m_maxduration = caster->CalcSpellDuration(m_spellProto); } - m_formalCasterGUID = formalCaster ? formalCaster->GetGUID() : m_caster_guid; if(m_maxduration == -1 || m_isPassive && m_spellProto->DurationIndex == 0) m_permanent = true; @@ -517,7 +516,8 @@ AreaAuraEffect::AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * curre m_removeTime = FRIENDLY_AA_REMOVE_TIME; m_isAreaAura = true; - Unit* caster_ptr = formalCaster ? formalCaster : m_target; + Unit* caster_ptr = formalCaster ? formalCaster : caster ? caster : m_target; + m_formalCasterGUID = caster_ptr->GetGUID(); if (m_spellProto->Effect[effIndex] == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY) m_radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex])); @@ -599,7 +599,7 @@ Unit* Aura::GetCaster() const return unit && unit->IsInWorld() ? unit : NULL; } -Unit* Aura::GetFormalCaster() const +Unit* AreaAuraEffect::GetFormalCaster() const { if(m_formalCasterGUID==m_target->GetGUID()) return m_target; @@ -655,28 +655,6 @@ void Aura::Update(uint32 diff) } } - // Channeled aura required check distance from caster - if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID() - && !IsAreaAura() && !IsPersistent()) // check for these is done in auraeffect - { - Unit* caster = GetFormalCaster(); - if(!caster) - { - m_target->RemoveAura(this); - return; - } - float radius = caster->GetSpellMaxRangeForTarget(m_target, sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex)) ; - - if(Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod(GetId(), SPELLMOD_RANGE, radius,NULL); - - if(!caster->IsWithinDistInMap(m_target,radius)) - { - m_target->RemoveAura(this); - return; - } - } - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (m_partAuras[i]) m_partAuras[i]->Update(diff); @@ -703,7 +681,7 @@ void AuraEffect::Update(uint32 diff) void AreaAuraEffect::Update(uint32 diff) { // update for the caster of the aura - if(GetFormalCasterGUID() == m_target->GetGUID()) + if(m_formalCasterGUID == m_target->GetGUID()) { Unit* caster = m_target; @@ -791,7 +769,7 @@ void AreaAuraEffect::Update(uint32 diff) return; // Caster may be deleted due to update - Unit* caster = GetParentAura()->GetFormalCaster(); + Unit* caster = GetFormalCaster(); // remove aura if out-of-range from caster (after teleport for example) // or caster is isolated or caster no longer has the aura @@ -840,7 +818,7 @@ void AreaAuraEffect::Update(uint32 diff) void PersistentAreaAuraEffect::Update(uint32 diff) { - if(Unit *caster = GetParentAura()->GetFormalCaster()) + if(Unit *caster = GetParentAura()->GetCaster()) { if(DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex())) { diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index a1b8f0b2736..89d8da7e500 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -57,11 +57,8 @@ class TRINITY_DLL_SPEC Aura uint64 GetCastItemGUID() const { return m_castItemGuid; } uint64 const& GetCasterGUID() const { return m_caster_guid; } - uint64 const& GetFormalCasterGUID() const { return m_formalCasterGUID; } Unit* GetCaster() const; - Unit* GetFormalCaster() const; Unit* GetTarget() const { return m_target; } - time_t GetAuraApplyTime() const { return m_applyTime; } int32 GetAuraMaxDuration() const { return m_maxduration; } @@ -136,7 +133,6 @@ class TRINITY_DLL_SPEC Aura SpellEntry const *m_spellProto; Unit * const m_target; uint64 m_caster_guid; - uint64 m_formalCasterGUID; // used for check range uint64 m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted time_t m_applyTime; @@ -333,7 +329,6 @@ class TRINITY_DLL_SPEC AuraEffect inline Unit * GetCaster() const{ return m_parentAura->GetCaster(); } inline uint64 GetCasterGUID() const{ return m_parentAura->GetCasterGUID(); } - inline uint64 GetFormalCasterGUID() const { return m_parentAura->GetFormalCasterGUID(); } Aura * GetParentAura() const { return m_parentAura; } SpellEntry const* GetSpellProto() const { return m_spellProto; } @@ -394,11 +389,13 @@ class TRINITY_DLL_SPEC AreaAuraEffect : public AuraEffect public: AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * currentBasePoints, Unit * caster=NULL, Item * castItem=NULL, Unit * formalCaster=NULL); ~AreaAuraEffect(); + Unit* GetFormalCaster() const; void Update(uint32 diff); private: float m_radius; int32 m_removeTime; AreaAuraType m_areaAuraType; + uint64 m_formalCasterGUID; // used for check range }; class TRINITY_DLL_SPEC PersistentAreaAuraEffect : public AuraEffect diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 5effacc14a3..a29d19cb0c4 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3198,56 +3198,6 @@ void Unit::_DeleteAuras() for (AuraList::iterator i = m_removedAuras.begin(); i != m_removedAuras.end();i = m_removedAuras.begin()) { Aura * Aur = *i; - SpellEntry const* AurSpellInfo = Aur->GetSpellProto(); - // Statue unsummoned at aura delete - Totem* statue = NULL; - if(Aur->GetAuraDuration() && !Aur->IsPersistent() && IsChanneledSpell(Aur->GetSpellProto())) - { - Unit* caster = Aur->GetFormalCaster(); - if(caster && caster->isAlive()) - { - // stop caster chanelling state - if(caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) - { - // same spell - if (AurSpellInfo == caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo - //prevent recurential call - && caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED) - { - if (caster==this || !IsAreaOfEffectSpell(AurSpellInfo)) - { - // remove auras only for non-aoe spells or when chanelled aura is removed - // because aoe spells don't require aura on target to continue - caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel(); - } - - if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE) - statue = ((Totem*)caster); - } - } - - // Unsummon summon as possessed creatures on spell cancel - if(caster->GetTypeId() == TYPEID_PLAYER) - { - for(int i = 0; i < 3; ++i) - { - if(AurSpellInfo->Effect[i] == SPELL_EFFECT_SUMMON) - if(SummonPropertiesEntry const *SummonProperties = sSummonPropertiesStore.LookupEntry(AurSpellInfo->EffectMiscValueB[i])) - if(SummonProperties->Category == SUMMON_CATEGORY_POSSESSED) - { - ((Player*)caster)->StopCastingCharm(); - break; - } - } - } - } - } - if(statue) - { - sLog.outDebug("Statue %d is unsummoned by aura %d delete from unit %d", statue->GetGUIDLow(), Aur->GetId(),GetGUIDLow()); - statue->UnSummon(); - } - sLog.outDebug("Aura %d is deleted from unit %d", Aur->GetId(), GetGUIDLow()); m_removedAuras.pop_front(); delete (Aur); |