aboutsummaryrefslogtreecommitdiff
path: root/src/game/Unit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Unit.cpp')
-rw-r--r--src/game/Unit.cpp123
1 files changed, 80 insertions, 43 deletions
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 6d2eb1ec4cc..9d9b1fdc101 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -258,8 +258,21 @@ Unit::~Unit()
if(m_charmInfo) delete m_charmInfo;
- RemoveAllAuras();
- assert(m_Auras.begin() == m_Auras.end());
+ if(m_uint32Values)
+ {
+ sLog.outDetail("Deconstruct Unit Entry = %u", GetEntry());
+ /*for(int i = 0; i < TOTAL_AURAS; ++i)
+ {
+ if(m_modAuras[i].begin() != m_modAuras[i].end())
+ sLog.outError("Unit %u has mod auras during deconstruction", GetEntry());
+ }
+ if(m_scAuras.begin() != m_scAuras.end())
+ sLog.outError("Unit %u has sc auras during deconstruction", GetEntry());
+ if(m_interruptableAuras.begin() != m_interruptableAuras.end())
+ sLog.outError("Unit %u has interruptable auras during deconstruction", GetEntry());
+ if(m_ccAuras.begin() != m_ccAuras.end())
+ sLog.outError("Unit %u has cc auras during deconstruction", GetEntry());*/
+ }
}
void Unit::Update( uint32 p_time )
@@ -614,11 +627,16 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
}
}
}
- }
-
+ }
+ if (damagetype != NODAMAGE)
+ {
+ // interrupting auras with AURA_INTERRUPT_FLAG_DAMAGE before checking !damage (absorbed damage breaks that type of auras)
+ pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DAMAGE, spellProto ? spellProto->Id : 0);
+ pVictim->RemoveSpellbyDamageTaken(damage, spellProto ? spellProto->Id : 0);
+ }
- if(!damage) //when will zero damage? need interrupt aura?
+ if(!damage)
{
// Rage from physical damage received .
if(cleanDamage && cleanDamage->damage && (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL) && pVictim->GetTypeId() == TYPEID_PLAYER && (pVictim->getPowerType() == POWER_RAGE))
@@ -790,9 +808,6 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
if (damagetype != NODAMAGE && damage)// && pVictim->GetTypeId() == TYPEID_PLAYER)
{
- pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DAMAGE, spellProto ? spellProto->Id : 0);
- pVictim->RemoveSpellbyDamageTaken(damage, spellProto ? spellProto->Id : 0);
-
/*const SpellEntry *se = i->second->GetSpellProto();
next = i; ++next;
if (spellProto && spellProto->Id == se->Id) // Not drop auras added by self
@@ -4640,7 +4655,7 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
// Statue unsummoned at aura remove
Totem* statue = NULL;
- bool caster_channeled = false;
+ bool channeled = false;
if(IsChanneledSpell(AurSpellInfo))
{
if(!caster) // can be already located for IsSingleTargetSpell case
@@ -4650,8 +4665,25 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
{
if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE)
statue = ((Totem*)caster);
- else
- caster_channeled = caster==this;
+
+ // stop caster chanelling state
+ else if(caster->m_currentSpells[CURRENT_CHANNELED_SPELL]
+ //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
+ if (AurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()]!=SPELL_AURA_PERIODIC_DUMMY
+ && AurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()]!= SPELL_AURA_DUMMY)
+ //don't stop channeling of scripted spells (this is actually a hack)
+ {
+ caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel(false);
+ channeled = true;
+ }
+ }
+ }
}
}
@@ -4662,13 +4694,6 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
Aur->SetStackAmount(0);
Aur->_RemoveAura();
- delete Aur;
-
- if(caster_channeled)
- RemoveAurasAtChanneledTarget (AurSpellInfo);
-
- if(statue)
- statue->UnSummon();
if(mode != AURA_REMOVE_BY_STACK)
{
@@ -4684,6 +4709,19 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
}
}
+ delete Aur;
+
+ if(channeled)
+ {
+ //if target is not caster remove auras also on caster
+ if (caster!=this)
+ caster->RemoveAurasAtChanneledTarget (AurSpellInfo, caster);
+ RemoveAurasAtChanneledTarget (AurSpellInfo, caster);
+ }
+
+ if(statue)
+ statue->UnSummon();
+
// only way correctly remove all auras from list
if( m_Auras.empty() )
i = m_Auras.end();
@@ -10368,18 +10406,17 @@ void Unit::TauntFadeOut(Unit *taunter)
//======================================================================
-bool Unit::SelectHostilTarget()
+Unit* Creature::SelectHostilTarget()
{
//function provides main threat functionality
//next-victim-selection algorithm and evade mode are called
//threat list sorting etc.
- assert(GetTypeId()== TYPEID_UNIT);
Unit* target = NULL;
//This function only useful once AI has been initialized
- if (!((Creature*)this)->AI())
- return false;
+ if (!AI())
+ return NULL;
if(!m_ThreatManager.isThreatListEmpty())
{
@@ -10395,36 +10432,36 @@ bool Unit::SelectHostilTarget()
{
if(!hasUnitState(UNIT_STAT_STUNNED))
SetInFront(target);
- ((Creature*)this)->AI()->AttackStart(target);
- return true;
+ AI()->AttackStart(target);
+ return getVictim();
}
// no target but something prevent go to evade mode
if( !isInCombat() /*|| HasAuraType(SPELL_AURA_MOD_TAUNT)*/ )
- return false;
+ return NULL;
// last case when creature don't must go to evade mode:
// it in combat but attacker not make any damage and not enter to aggro radius to have record in threat list
// for example at owner command to pet attack some far away creature
// Note: creature not have targeted movement generator but have attacker in this case
- if( GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE )
+ /*if( GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE )
{
for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr)
{
if( (*itr)->IsInMap(this) && canAttack(*itr) && (*itr)->isInAccessiblePlaceFor((Creature*)this) )
return false;
}
- }
+ }*/
// search nearby enemy before enter evade mode
- if(((Creature*)this)->HasReactState(REACT_AGGRESSIVE))
+ if(HasReactState(REACT_AGGRESSIVE))
{
- if(Unit *target = ((Creature*)this)->SelectNearestTarget())
+ if(target = SelectNearestTarget())
{
- if(!((Creature*)this)->IsOutOfThreatArea(target))
+ if(!IsOutOfThreatArea(target))
{
- ((Creature*)this)->AI()->AttackStart(target);
- return true;
+ AI()->AttackStart(target);
+ return getVictim();
}
}
}
@@ -10435,16 +10472,16 @@ bool Unit::SelectHostilTarget()
for(Unit::AuraList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr)
if((*itr)->IsPermanent())
{
- ((Creature*)this)->AI()->EnterEvadeMode();
+ AI()->EnterEvadeMode();
break;
}
- return false;
+ return NULL;
}
// enter in evade mode in other case
- ((Creature*)this)->AI()->EnterEvadeMode();
+ AI()->EnterEvadeMode();
- return false;
+ return NULL;
}
//======================================================================
@@ -12548,23 +12585,23 @@ bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura )
return true;
}
-void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo)
+void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo, Unit * caster)
{
- uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT);
+/* uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT);
if(target_guid == GetGUID())
return;
if(!IS_UNIT_GUID(target_guid))
return;
- Unit* target = ObjectAccessor::GetUnit(*this, target_guid);
- if(!target)
+ Unit* target = ObjectAccessor::GetUnit(*this, target_guid);*/
+ if(!caster)
return;
- for (AuraMap::iterator iter = target->GetAuras().begin(); iter != target->GetAuras().end(); )
+ for (AuraMap::iterator iter = GetAuras().begin(); iter != GetAuras().end(); )
{
- if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID()==GetGUID())
- target->RemoveAura(iter);
+ if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID() == caster->GetGUID())
+ RemoveAura(iter);
else
++iter;
}