diff options
Diffstat (limited to 'src/game/Spell.cpp')
-rw-r--r-- | src/game/Spell.cpp | 64 |
1 files changed, 61 insertions, 3 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; |