aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQAston <none@none>2009-04-20 23:08:03 +0200
committerQAston <none@none>2009-04-20 23:08:03 +0200
commit7139aa19d825928fc44e093ff662d1ccb520ec22 (patch)
tree60dbb76a189a585d2457b8b22e5a1448bebd981c
parent0faac2574245df5b32757a933a836959323c6fcb (diff)
*Move unsummon statue and pet code to spell::finish
*Move m_formalCaster from Aura to AuraEffect *Interrupt channeled spells in spell::update instead of unit::_deleteauras --HG-- branch : trunk
-rw-r--r--src/game/Spell.cpp64
-rw-r--r--src/game/Spell.h2
-rw-r--r--src/game/SpellAuras.cpp34
-rw-r--r--src/game/SpellAuras.h7
-rw-r--r--src/game/Unit.cpp50
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);