*Update to HG 957.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-01-23 14:23:25 -06:00
95 changed files with 5196 additions and 1229 deletions

View File

@@ -185,8 +185,17 @@ Unit::~Unit()
if(m_uint32Values)
{
sLog.outDetail("Deconstruct Unit Entry = %u", GetEntry());
if(m_scAuras.size())
/*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());*/
}
}
@@ -4001,7 +4010,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
@@ -4011,8 +4020,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;
}
}
}
}
}
@@ -4037,8 +4063,13 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
delete Aur;
if(caster_channeled)
RemoveAurasAtChanneledTarget (AurSpellInfo);
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();
@@ -9521,18 +9552,16 @@ 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);
//This function only useful once AI has been initialized
if (!((Creature*)this)->AI())
return false;
if (!AI())
return NULL;
Unit* target = NULL;
// First checking if we have some taunt on us
@@ -9543,7 +9572,7 @@ bool Unit::SelectHostilTarget()
// The last taunt aura caster is alive an we are happy to attack him
if ( (caster = tauntAuras.back()->GetCaster()) && caster->isAlive() )
return true;
return getVictim();
else if (tauntAuras.size() > 1)
{
// We do not have last taunt aura caster but we have more taunt auras,
@@ -9574,36 +9603,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();
}
}
}
@@ -9614,16 +9643,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;
}
//======================================================================
@@ -11555,23 +11584,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;
}