[8625] feign_death cleanups

use an extra function for setfeigndeath()
like it's done with setfeared already..
allow to apply feigndeath on creatures too
avoid moving of creatures with feign death applied
and start attacking last victim when feigndeath disappears
This commit is contained in:
balrok 2009-10-11 14:19:29 +02:00
parent f4081b2c6a
commit 02d45b4b54
16 changed files with 90 additions and 69 deletions

View file

@ -46,7 +46,7 @@ AggressorAI::MoveInLineOfSight(Unit *u)
if( !m_creature->canFly() && m_creature->GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
return;
if( !m_creature->hasUnitState(UNIT_STAT_STUNNED) && u->isTargetableForAttack() &&
if( !m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && u->isTargetableForAttack() &&
( m_creature->IsHostileTo( u ) /*|| u->getVictim() && m_creature->IsFriendlyTo( u->getVictim() )*/ ) &&
u->isInAccessablePlaceFor(m_creature) )
{

View file

@ -102,7 +102,7 @@ ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
if(!&unit)
return true;
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
return true;
if( i_nextMoveTime.Passed() )

View file

@ -994,7 +994,7 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who)
if (m_creature->isCivilian() || m_creature->IsNeutralToAll())
return;
if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && who->isTargetableForAttack() &&
if (!m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && who->isTargetableForAttack() &&
m_creature->IsHostileTo(who) && who->isInAccessablePlaceFor(m_creature))
{
if (!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)

View file

@ -33,7 +33,7 @@ FleeingMovementGenerator<T>::_setTargetLocation(T &owner)
if( !&owner )
return;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED) )
return;
if(!_setMoveData(owner))
@ -353,7 +353,7 @@ FleeingMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
{
if( !&owner || !owner.isAlive() )
return false;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED) )
return true;
Traveller<T> traveller(owner);
@ -409,7 +409,7 @@ bool TimedFleeingMovementGenerator::Update(Unit & owner, const uint32 & time_dif
if( !owner.isAlive() )
return false;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED) )
return true;
i_totalFleeTime.Update(time_diff);

View file

@ -719,7 +719,7 @@ namespace MaNGOS
bool operator()(Unit* u)
{
if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
(u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNNED) || u->hasUnitState(UNIT_STAT_CONFUSED)))
(u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_CONFUSED | UNIT_STAT_DIED)))
{
return true;
}

View file

@ -42,7 +42,7 @@ HomeMovementGenerator<Creature>::_setTargetLocation(Creature & owner)
if( !&owner )
return;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) )
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED) )
return;
float x, y, z;

View file

@ -76,7 +76,7 @@ MotionMaster::~MotionMaster()
void
MotionMaster::UpdateMotion(uint32 diff)
{
if( i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
if( i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED) )
return;
assert( !empty() );
m_cleanFlag |= MMCF_UPDATE;

View file

@ -1658,7 +1658,7 @@ namespace MaNGOS
float x,y,z;
if( !c->isAlive() || c->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) ||
if( !c->isAlive() || c->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED) ||
!c->GetMotionMaster()->GetDestination(x,y,z) )
{
x = c->GetPositionX();

View file

@ -42,7 +42,7 @@ bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
if(!&unit)
return false;
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED))
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED))
return true;
Traveller<T> traveller(unit);

View file

@ -129,7 +129,7 @@ template<>
bool
RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
{
i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer
creature.clearUnitState(UNIT_STAT_ROAMING);

View file

@ -3566,51 +3566,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
if(!Real)
return;
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
if( apply )
{
/*
WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
data<<m_target->GetGUID();
data<<uint8(0);
m_target->SendMessageToSet(&data,true);
*/
// blizz like 2.0.x
m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
// blizz like 2.0.x
m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
// blizz like 2.0.x
m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
m_target->addUnitState(UNIT_STAT_DIED);
m_target->CombatStop();
m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
// prevent interrupt message
if (m_caster_guid==m_target->GetGUID())
m_target->FinishSpell(CURRENT_GENERIC_SPELL,false);
m_target->InterruptNonMeleeSpells(true);
m_target->getHostilRefManager().deleteReferences();
}
else
{
/*
WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
data<<m_target->GetGUID();
data<<uint8(1);
m_target->SendMessageToSet(&data,true);
*/
// blizz like 2.0.x
m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
// blizz like 2.0.x
m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
// blizz like 2.0.x
m_target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
m_target->clearUnitState(UNIT_STAT_DIED);
}
m_target->SetFeignDeath(apply, GetCasterGUID(), GetId());
}
void Aura::HandleAuraModDisarm(bool apply, bool Real)

View file

@ -46,7 +46,7 @@ TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
if (!i_target.isValid() || !i_target->IsInWorld())
return;
if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
return;
// prevent redundant micro-movement for pets, other followers.
@ -132,7 +132,7 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
if (!owner.isAlive())
return true;
if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED))
if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
return true;
// prevent movement while casting spells with cast time or channel time

View file

@ -2042,7 +2042,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool extra )
{
if(hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) )
if(hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DIED) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) )
return;
if (!pVictim->isAlive())
@ -11609,7 +11609,7 @@ void Unit::StopMoving()
SendMessageToSet(&data,false);
}
void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID, uint32 time)
void Unit::SetFeared(bool apply, uint64 const& casterGUID, uint32 spellID, uint32 time)
{
if( apply )
{
@ -11650,7 +11650,7 @@ void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID, uint32 time)
((Player*)this)->SetClientControl(this, !apply);
}
void Unit::SetConfused(bool apply, uint64 casterGUID, uint32 spellID)
void Unit::SetConfused(bool apply, uint64 const& casterGUID, uint32 spellID)
{
if( apply )
{
@ -11666,11 +11666,13 @@ void Unit::SetConfused(bool apply, uint64 casterGUID, uint32 spellID)
GetMotionMaster()->MovementExpired(false);
if (GetTypeId() == TYPEID_UNIT)
if (GetTypeId() != TYPEID_PLAYER && isAlive())
{
// if in combat restore movement generator
// restore appropriate movement generator
if(getVictim())
GetMotionMaster()->MoveChase(getVictim());
else
GetMotionMaster()->Initialize();
}
}
@ -11678,6 +11680,68 @@ void Unit::SetConfused(bool apply, uint64 casterGUID, uint32 spellID)
((Player*)this)->SetClientControl(this, !apply);
}
void Unit::SetFeignDeath(bool apply, uint64 const& casterGUID, uint32 spellID)
{
if( apply )
{
/*
WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
data<<GetGUID();
data<<uint8(0);
SendMessageToSet(&data,true);
*/
if(GetTypeId() != TYPEID_PLAYER)
StopMoving();
else
((Player*)this)->m_movementInfo.SetMovementFlags(MOVEMENTFLAG_NONE);
// blizz like 2.0.x
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
// blizz like 2.0.x
SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
// blizz like 2.0.x
SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
addUnitState(UNIT_STAT_DIED);
CombatStop();
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
// prevent interrupt message
if (casterGUID == GetGUID())
FinishSpell(CURRENT_GENERIC_SPELL,false);
InterruptNonMeleeSpells(true);
getHostilRefManager().deleteReferences();
}
else
{
/*
WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
data<<GetGUID();
data<<uint8(1);
SendMessageToSet(&data,true);
*/
// blizz like 2.0.x
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
// blizz like 2.0.x
RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
// blizz like 2.0.x
RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
clearUnitState(UNIT_STAT_DIED);
if (GetTypeId() != TYPEID_PLAYER && isAlive())
{
// restore appropriate movement generator
if(getVictim())
GetMotionMaster()->MoveChase(getVictim());
else
GetMotionMaster()->Initialize();
}
}
}
bool Unit::IsSitState() const
{
uint8 s = getStandState();

View file

@ -936,7 +936,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
bool CanFreeMove() const
{
return !hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_IN_FLIGHT |
UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED ) && GetOwnerGUID()==0;
UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED ) && GetOwnerGUID()==0;
}
uint32 getLevel() const { return GetUInt32Value(UNIT_FIELD_LEVEL); }
@ -1488,8 +1488,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
bool IsStopped() const { return !(hasUnitState(UNIT_STAT_MOVING)); }
void StopMoving();
void SetFeared(bool apply, uint64 casterGUID = 0, uint32 spellID = 0, uint32 time = 0);
void SetConfused(bool apply, uint64 casterGUID = 0, uint32 spellID = 0);
void SetFeared(bool apply, uint64 const& casterGUID = 0, uint32 spellID = 0, uint32 time = 0);
void SetConfused(bool apply, uint64 const& casterGUID = 0, uint32 spellID = 0);
void SetFeignDeath(bool apply, uint64 const& casterGUID = 0, uint32 spellID = 0);
void AddComboPointHolder(uint32 lowguid) { m_ComboPointHolders.insert(lowguid); }
void RemoveComboPointHolder(uint32 lowguid) { m_ComboPointHolders.erase(lowguid); }

View file

@ -83,7 +83,7 @@ bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint3
// Waypoint movement can be switched on/off
// This is quite handy for escort quests and other stuff
if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
return true;
// prevent a crash at empty waypoint path.

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8624"
#define REVISION_NR "8625"
#endif // __REVISION_NR_H__