[9208] Big cleanup in UNIT_STAT_* use

* Re-number enums by function groups and use where possible new defined masks in code instead raw enum |-lists.
* Avoid use movement generator generic state markers like UNIT_STAT_CONFUSED for mark movement stoped.
  Add special shadow UNIT_STAT_CONFUSED_MOVE/etc states for like use.
  UNIT_STAT_CONFUSED in like case will be safe expect use for normal checks confused state presence
  And UNIT_STAT_CONFUSED_MOVE for check real move in this state
This commit is contained in:
VladimirMangos 2010-01-18 10:48:31 +03:00
parent 7d6b1b292e
commit 6a2e8064f1
25 changed files with 251 additions and 104 deletions

View file

@ -64,7 +64,7 @@ ConfusedMovementGenerator<T>::Initialize(T &unit)
}
unit.StopMoving();
unit.addUnitState(UNIT_STAT_CONFUSED);
unit.addUnitState(UNIT_STAT_CONFUSED|UNIT_STAT_CONFUSED_MOVE);
}
template<>
@ -88,6 +88,8 @@ ConfusedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bo
template<class T>
void ConfusedMovementGenerator<T>::Interrupt(T &unit)
{
// confused state still applied while movegen disabled
unit.clearUnitState(UNIT_STAT_CONFUSED_MOVE);
}
template<class T>
@ -97,6 +99,7 @@ void ConfusedMovementGenerator<T>::Reset(T &unit)
i_nextMoveTime.Reset(0);
i_destinationHolder.ResetUpdate();
unit.StopMoving();
unit.addUnitState(UNIT_STAT_CONFUSED|UNIT_STAT_CONFUSED_MOVE);
}
template<class T>
@ -105,12 +108,14 @@ bool ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
if(!&unit)
return true;
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
// ignore in case other no reaction state
if (unit.hasUnitState(UNIT_STAT_CAN_NOT_REACT & ~UNIT_STAT_CONFUSED))
return true;
if( i_nextMoveTime.Passed() )
if (i_nextMoveTime.Passed())
{
// currently moving, update location
unit.addUnitState(UNIT_STAT_CONFUSED_MOVE);
Traveller<T> traveller(unit);
if( i_destinationHolder.UpdateTraveller(traveller, diff, false))
{
@ -131,6 +136,7 @@ bool ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
if( i_nextMoveTime.Passed() )
{
// start moving
unit.addUnitState(UNIT_STAT_CONFUSED_MOVE);
assert( i_nextMove <= MAX_CONF_WAYPOINTS );
const float x = i_waypoints[i_nextMove][0];
const float y = i_waypoints[i_nextMove][1];
@ -145,13 +151,13 @@ bool ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
template<>
void ConfusedMovementGenerator<Player>::Finalize(Player &unit)
{
unit.clearUnitState(UNIT_STAT_CONFUSED);
unit.clearUnitState(UNIT_STAT_CONFUSED|UNIT_STAT_CONFUSED_MOVE);
}
template<>
void ConfusedMovementGenerator<Creature>::Finalize(Creature &unit)
{
unit.clearUnitState(UNIT_STAT_CONFUSED);
unit.clearUnitState(UNIT_STAT_CONFUSED|UNIT_STAT_CONFUSED_MOVE);
unit.AddMonsterMoveFlag(MONSTER_MOVE_WALK);
}

View file

@ -36,7 +36,7 @@ CanCastResult CreatureAI::CanCastSpell(Unit* pTarget, const SpellEntry *pSpell,
if (!isTriggered)
{
// State does not allow
if (m_creature->hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DIED))
if (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT))
return CAST_FAIL_STATE;
if (pSpell->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))

View file

@ -1343,8 +1343,8 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge
return false;
//Silenced so we can't cast
if (!Triggered && (m_creature->hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DIED)
|| m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)))
if (!Triggered && (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT) ||
m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)))
return false;
//Check for power

View file

@ -33,7 +33,8 @@ FleeingMovementGenerator<T>::_setTargetLocation(T &owner)
if( !&owner )
return;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED) )
// ignore in case other no reaction state
if (owner.hasUnitState(UNIT_STAT_CAN_NOT_REACT & ~UNIT_STAT_FLEEING))
return;
if(!_setMoveData(owner))
@ -43,7 +44,7 @@ FleeingMovementGenerator<T>::_setTargetLocation(T &owner)
if(!_getPoint(owner, x, y, z))
return;
owner.addUnitState(UNIT_STAT_FLEEING);
owner.addUnitState(UNIT_STAT_FLEEING_MOVE);
Traveller<T> traveller(owner);
i_destinationHolder.SetDestination(traveller, x, y, z);
}
@ -281,8 +282,7 @@ template<class T>
void
FleeingMovementGenerator<T>::Initialize(T &owner)
{
if(!&owner)
return;
owner.addUnitState(UNIT_STAT_FLEEING|UNIT_STAT_FLEEING_MOVE);
_Init(owner);
@ -310,9 +310,6 @@ template<>
void
FleeingMovementGenerator<Creature>::_Init(Creature &owner)
{
if(!&owner)
return;
owner.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK);
owner.SetTargetGUID(0);
is_water_ok = owner.canSwim();
@ -330,19 +327,21 @@ FleeingMovementGenerator<Player>::_Init(Player &)
template<>
void FleeingMovementGenerator<Player>::Finalize(Player &owner)
{
owner.clearUnitState(UNIT_STAT_FLEEING);
owner.clearUnitState(UNIT_STAT_FLEEING|UNIT_STAT_FLEEING_MOVE);
}
template<>
void FleeingMovementGenerator<Creature>::Finalize(Creature &owner)
{
owner.AddMonsterMoveFlag(MONSTER_MOVE_WALK);
owner.clearUnitState(UNIT_STAT_FLEEING);
owner.clearUnitState(UNIT_STAT_FLEEING|UNIT_STAT_FLEEING_MOVE);
}
template<class T>
void FleeingMovementGenerator<T>::Interrupt(T &owner)
{
// flee state still applied while movegen disabled
owner.clearUnitState(UNIT_STAT_FLEEING_MOVE);
}
template<class T>
@ -356,8 +355,13 @@ bool FleeingMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
{
if( !&owner || !owner.isAlive() )
return false;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED) )
// ignore in case other no reaction state
if (owner.hasUnitState(UNIT_STAT_CAN_NOT_REACT & ~UNIT_STAT_FLEEING))
{
owner.clearUnitState(UNIT_STAT_FLEEING_MOVE);
return true;
}
Traveller<T> traveller(owner);
@ -398,7 +402,7 @@ template bool FleeingMovementGenerator<Creature>::Update(Creature &, const uint3
void TimedFleeingMovementGenerator::Finalize(Unit &owner)
{
owner.clearUnitState(UNIT_STAT_FLEEING);
owner.clearUnitState(UNIT_STAT_FLEEING|UNIT_STAT_FLEEING_MOVE);
if (Unit* victim = owner.getVictim())
{
if (owner.isAlive())
@ -414,8 +418,12 @@ bool TimedFleeingMovementGenerator::Update(Unit & owner, const uint32 & time_dif
if( !owner.isAlive() )
return false;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED) )
// ignore in case other no reaction state
if (owner.hasUnitState(UNIT_STAT_CAN_NOT_REACT & ~UNIT_STAT_FLEEING))
{
owner.clearUnitState(UNIT_STAT_FLEEING_MOVE);
return true;
}
i_totalFleeTime.Update(time_diff);
if (i_totalFleeTime.Passed())

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 | UNIT_STAT_CONFUSED | UNIT_STAT_DIED)))
(u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_CAN_NOT_REACT)))
{
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 | UNIT_STAT_DIED) )
if( owner.hasUnitState(UNIT_STAT_NOT_MOVE) )
return;
float x, y, z;

View file

@ -39,6 +39,17 @@ DistractMovementGenerator::Finalize(Unit& owner)
owner.clearUnitState(UNIT_STAT_DISTRACTED);
}
void
DistractMovementGenerator::Reset(Unit& owner)
{
Initialize(owner);
}
void
DistractMovementGenerator::Interrupt(Unit& owner)
{
}
bool
DistractMovementGenerator::Update(Unit& /*owner*/, const uint32& time_diff)
{

View file

@ -42,8 +42,8 @@ class MANGOS_DLL_SPEC DistractMovementGenerator : public MovementGenerator
void Initialize(Unit& owner);
void Finalize(Unit& owner);
void Interrupt(Unit& ) {}
void Reset(Unit& owner) { Initialize(owner); }
void Interrupt(Unit& );
void Reset(Unit& );
bool Update(Unit& owner, const uint32& time_diff);
MovementGeneratorType GetMovementGeneratorType() { return DISTRACT_MOTION_TYPE; }

View file

@ -76,7 +76,7 @@ MotionMaster::~MotionMaster()
void
MotionMaster::UpdateMotion(uint32 diff)
{
if( i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED) )
if( i_owner->hasUnitState(UNIT_STAT_CAN_NOT_MOVE) )
return;
assert( !empty() );
m_cleanFlag |= MMCF_UPDATE;
@ -232,7 +232,6 @@ MotionMaster::MoveTargetedHome()
Unit *target = ((Creature*)i_owner)->GetCharmerOrOwner();
if(target)
{
i_owner->addUnitState(UNIT_STAT_FOLLOW);
DEBUG_LOG("Following %s (GUID: %u)",
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
@ -268,7 +267,6 @@ MotionMaster::MoveChase(Unit* target, float dist, float angle)
if(!target)
return;
i_owner->clearUnitState(UNIT_STAT_FOLLOW);
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) chase to %s (GUID: %u)",
@ -296,7 +294,6 @@ MotionMaster::MoveFollow(Unit* target, float dist, float angle)
if(!target)
return;
i_owner->addUnitState(UNIT_STAT_FOLLOW);
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) follow to %s (GUID: %u)", i_owner->GetGUIDLow(),

View file

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

View file

@ -75,7 +75,6 @@ void PetAI::AttackStart(Unit *u)
if(m_creature->Attack(u,true))
{
m_creature->clearUnitState(UNIT_STAT_FOLLOW);
// TMGs call CreatureRelocation which via MoveInLineOfSight can call this function
// thus with the following clear the original TMG gets invalidated and crash, doh
// hope it doesn't start to leak memory without this :-/
@ -126,8 +125,7 @@ void PetAI::_stopAttack()
}
else
{
m_creature->clearUnitState(UNIT_STAT_FOLLOW);
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveIdle();
}
m_creature->AttackStop();
@ -163,7 +161,7 @@ void PetAI::UpdateAI(const uint32 diff)
// required to be stopped cases
if (m_creature->IsStopped() && m_creature->IsNonMeleeSpellCasted(false))
{
if (m_creature->hasUnitState(UNIT_STAT_FOLLOW))
if (m_creature->hasUnitState(UNIT_STAT_FOLLOW_MOVE))
m_creature->InterruptNonMeleeSpells(false);
else
return;

View file

@ -194,7 +194,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
return;
pet->clearUnitState(UNIT_STAT_FOLLOW);
pet->clearUnitState(UNIT_STAT_MOVING);
Spell *spell = new Spell(pet, spellInfo, false);
@ -633,7 +633,7 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
if (!targets.read(&recvPacket,pet))
return;
pet->clearUnitState(UNIT_STAT_FOLLOW);
pet->clearUnitState(UNIT_STAT_MOVING);
Spell *spell = new Spell(pet, spellInfo, false);
spell->m_cast_count = cast_count; // probably pending spell cast

View file

@ -28,7 +28,7 @@ template<class T>
void PointMovementGenerator<T>::Initialize(T &unit)
{
unit.StopMoving();
unit.addUnitState(UNIT_STAT_ROAMING);
unit.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
Traveller<T> traveller(unit);
i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z);
@ -36,17 +36,40 @@ void PointMovementGenerator<T>::Initialize(T &unit)
((Creature&)unit).AddMonsterMoveFlag(MONSTER_MOVE_FLY);
}
template<class T>
void PointMovementGenerator<T>::Finalize(T &unit)
{
unit.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
}
template<class T>
void PointMovementGenerator<T>::Interrupt(T &unit)
{
unit.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
}
template<class T>
void PointMovementGenerator<T>::Reset(T &unit)
{
unit.StopMoving();
unit.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
}
template<class T>
bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
{
if(!&unit)
return false;
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED))
if(unit.hasUnitState(UNIT_STAT_CAN_NOT_MOVE))
{
unit.clearUnitState(UNIT_STAT_ROAMING_MOVE);
return true;
}
unit.addUnitState(UNIT_STAT_ROAMING_MOVE);
Traveller<T> traveller(unit);
i_destinationHolder.UpdateTraveller(traveller, diff, false);
if(i_destinationHolder.HasArrived())
@ -78,6 +101,8 @@ template bool PointMovementGenerator<Creature>::Update(Creature&, const uint32 &
void AssistanceMovementGenerator::Finalize(Unit &unit)
{
unit.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
((Creature*)&unit)->SetNoCallAssistance(false);
((Creature*)&unit)->CallAssistance();
if (unit.isAlive())

View file

@ -33,9 +33,9 @@ class MANGOS_DLL_SPEC PointMovementGenerator
i_x(_x), i_y(_y), i_z(_z), i_nextMoveTime(0) {}
void Initialize(T &);
void Finalize(T &){}
void Interrupt(T &) {}
void Reset(T &unit){ unit.StopMoving(); }
void Finalize(T &);
void Interrupt(T &);
void Reset(T &unit);
bool Update(T &, const uint32 &diff);
void MovementInform(T &);

View file

@ -93,7 +93,7 @@ RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
creature.SetOrientation(creature.GetAngle(nx, ny));
i_destinationHolder.SetDestination(traveller, nx, ny, nz);
creature.addUnitState(UNIT_STAT_ROAMING);
creature.addUnitState(UNIT_STAT_ROAMING_MOVE);
if (is_air_ok)
{
@ -109,8 +109,7 @@ RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
}
template<>
void
RandomMovementGenerator<Creature>::Initialize(Creature &creature)
void RandomMovementGenerator<Creature>::Initialize(Creature &creature)
{
if (!creature.isAlive())
return;
@ -120,34 +119,47 @@ RandomMovementGenerator<Creature>::Initialize(Creature &creature)
else
creature.AddMonsterMoveFlag(MONSTER_MOVE_WALK);
creature.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
_setRandomLocation(creature);
}
template<>
void
RandomMovementGenerator<Creature>::Reset(Creature &creature)
void RandomMovementGenerator<Creature>::Reset(Creature &creature)
{
Initialize(creature);
}
template<>
void RandomMovementGenerator<Creature>::Interrupt(Creature &creature)
{
creature.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
}
template<>
void
RandomMovementGenerator<Creature>::Finalize(Creature &creature)
{
creature.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
}
template<>
bool
RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
if (creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
if (creature.hasUnitState(UNIT_STAT_NOT_MOVE))
{
i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer
creature.clearUnitState(UNIT_STAT_ROAMING);
creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
return true;
}
i_nextMoveTime.Update(diff);
if (i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())
creature.clearUnitState(UNIT_STAT_ROAMING);
creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
if (!i_destinationHolder.HasArrived() && creature.IsStopped())
creature.addUnitState(UNIT_STAT_ROAMING);
creature.addUnitState(UNIT_STAT_ROAMING_MOVE);
CreatureTraveller traveller(creature);

View file

@ -32,8 +32,8 @@ class MANGOS_DLL_SPEC RandomMovementGenerator
void _setRandomLocation(T &);
void Initialize(T &);
void Finalize(T &) {}
void Interrupt(T &) {}
void Finalize(T &);
void Interrupt(T &);
void Reset(T &);
bool Update(T &, const uint32 &);
void UpdateMapPosition(uint32 mapid, float &x ,float &y, float &z)

View file

@ -2925,7 +2925,7 @@ void Spell::update(uint32 difftime)
cancel();
// check for incapacitating player states
if( m_caster->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_CONFUSED))
if( m_caster->hasUnitState(UNIT_STAT_CAN_NOT_REACT))
cancel();
// check if player has turned if flag is set

View file

@ -1607,7 +1607,7 @@ void Spell::EffectDummy(uint32 i)
}
//Any effect which causes you to lose control of your character will supress the starfall effect.
if (m_caster->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_ROOT | UNIT_STAT_CONFUSED))
if (m_caster->hasUnitState(UNIT_STAT_NO_FREE_MOVE))
return;
switch(m_spellInfo->Id)
@ -3704,7 +3704,7 @@ void Spell::EffectDistract(uint32 /*i*/)
return;
// target must be OK to do this
if( unitTarget->hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING ) )
if( unitTarget->hasUnitState(UNIT_STAT_CAN_NOT_REACT) )
return;
float angle = unitTarget->GetAngle(m_targets.m_destX, m_targets.m_destY);

View file

@ -34,7 +34,7 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T &owner)
if (!i_target.isValid() || !i_target->IsInWorld())
return;
if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
if (owner.hasUnitState(UNIT_STAT_NOT_MOVE))
return;
// prevent redundant micro-movement for pets, other followers.
@ -71,7 +71,8 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T &owner)
*/
Traveller<T> traveller(owner);
i_destinationHolder.SetDestination(traveller, x, y, z);
owner.addUnitState(UNIT_STAT_CHASE);
D::_addUnitStateMove(owner);
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
((Creature&)owner).AddMonsterMoveFlag(MONSTER_MOVE_FLY);
}
@ -111,8 +112,11 @@ bool TargetedMovementGeneratorMedium<T,D>::Update(T &owner, const uint32 & time_
if (!owner.isAlive())
return true;
if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
if (owner.hasUnitState(UNIT_STAT_NOT_MOVE))
{
D::_clearUnitStateMove(owner);
return true;
}
// prevent movement while casting spells with cast time or channel time
if (owner.IsNonMeleeSpellCasted(false, false, true))
@ -123,8 +127,11 @@ bool TargetedMovementGeneratorMedium<T,D>::Update(T &owner, const uint32 & time_
}
// prevent crash after creature killed pet
if (!owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget())
if (static_cast<D*>(this)->_lostTarget(owner))
{
D::_clearUnitStateMove(owner);
return true;
}
Traveller<T> traveller(owner);
@ -132,7 +139,7 @@ bool TargetedMovementGeneratorMedium<T,D>::Update(T &owner, const uint32 & time_
_setTargetLocation(owner);
if (owner.IsStopped() && !i_destinationHolder.HasArrived())
{
owner.addUnitState(UNIT_STAT_CHASE);
D::_addUnitStateMove(owner);
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
((Creature&)owner).AddMonsterMoveFlag(MONSTER_MOVE_FLY);
@ -167,23 +174,31 @@ bool TargetedMovementGeneratorMedium<T,D>::Update(T &owner, const uint32 & time_
owner.SetInFront(i_target.getTarget());
owner.StopMoving();
if(owner.canReachWithAttack(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW))
owner.Attack(i_target.getTarget(),true);
static_cast<D*>(this)->_reachTarget(owner);
}
}
return true;
}
//-----------------------------------------------//
template<class T>
void ChaseMovementGenerator<T>::_reachTarget(T &owner)
{
if(owner.canReachWithAttack(i_target.getTarget()))
owner.Attack(i_target.getTarget(),true);
}
template<>
void ChaseMovementGenerator<Player>::Initialize(Player &owner)
{
owner.addUnitState(UNIT_STAT_CHASE|UNIT_STAT_CHASE_MOVE);
_setTargetLocation(owner);
}
template<>
void ChaseMovementGenerator<Creature>::Initialize(Creature &owner)
{
owner.addUnitState(UNIT_STAT_CHASE|UNIT_STAT_CHASE_MOVE);
owner.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK);
if (((Creature*)&owner)->canFly())
@ -195,12 +210,13 @@ void ChaseMovementGenerator<Creature>::Initialize(Creature &owner)
template<class T>
void ChaseMovementGenerator<T>::Finalize(T &owner)
{
owner.clearUnitState(UNIT_STAT_CHASE | UNIT_STAT_FOLLOW);
owner.clearUnitState(UNIT_STAT_CHASE|UNIT_STAT_CHASE_MOVE);
}
template<class T>
void ChaseMovementGenerator<T>::Interrupt(T &owner)
{
owner.clearUnitState(UNIT_STAT_CHASE|UNIT_STAT_CHASE_MOVE);
}
template<class T>
@ -213,12 +229,15 @@ void ChaseMovementGenerator<T>::Reset(T &owner)
template<>
void FollowMovementGenerator<Player>::Initialize(Player &owner)
{
owner.addUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE);
_setTargetLocation(owner);
}
template<>
void FollowMovementGenerator<Creature>::Initialize(Creature &owner)
{
owner.addUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE);
if (((Creature*)&owner)->canFly())
owner.AddMonsterMoveFlag(MONSTER_MOVE_FLY);
@ -228,12 +247,13 @@ void FollowMovementGenerator<Creature>::Initialize(Creature &owner)
template<class T>
void FollowMovementGenerator<T>::Finalize(T &owner)
{
owner.clearUnitState(UNIT_STAT_CHASE | UNIT_STAT_FOLLOW);
owner.clearUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE);
}
template<class T>
void FollowMovementGenerator<T>::Interrupt(T &owner)
{
owner.clearUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE);
}
template<class T>
@ -252,6 +272,8 @@ template bool TargetedMovementGeneratorMedium<Player,FollowMovementGenerator<Pla
template bool TargetedMovementGeneratorMedium<Creature,ChaseMovementGenerator<Creature> >::Update(Creature &, const uint32 &);
template bool TargetedMovementGeneratorMedium<Creature,FollowMovementGenerator<Creature> >::Update(Creature &, const uint32 &);
template void ChaseMovementGenerator<Player>::_reachTarget(Player &);
template void ChaseMovementGenerator<Creature>::_reachTarget(Creature &);
template void ChaseMovementGenerator<Player>::Finalize(Player &);
template void ChaseMovementGenerator<Creature>::Finalize(Creature &);
template void ChaseMovementGenerator<Player>::Interrupt(Player &);

View file

@ -62,7 +62,6 @@ class MANGOS_DLL_SPEC TargetedMovementGeneratorMedium
void UpdateFinalDistance(float fDistance);
protected:
void _setTargetLocation(T &);
float i_offset;
@ -87,6 +86,11 @@ class MANGOS_DLL_SPEC ChaseMovementGenerator : public TargetedMovementGeneratorM
void Finalize(T &);
void Interrupt(T &);
void Reset(T &);
static void _clearUnitStateMove(T &u) { u.clearUnitState(UNIT_STAT_CHASE_MOVE); }
static void _addUnitStateMove(T &u) { u.addUnitState(UNIT_STAT_CHASE_MOVE); }
bool _lostTarget(T &u) const { return u.getVictim() != i_target.getTarget(); }
void _reachTarget(T &);
};
template<class T>
@ -105,6 +109,11 @@ class MANGOS_DLL_SPEC FollowMovementGenerator : public TargetedMovementGenerator
void Finalize(T &);
void Interrupt(T &);
void Reset(T &);
static void _clearUnitStateMove(T &u) { u.clearUnitState(UNIT_STAT_FOLLOW_MOVE); }
static void _addUnitStateMove(T &u) { u.addUnitState(UNIT_STAT_FOLLOW_MOVE); }
bool _lostTarget(T &) const { return false; }
void _reachTarget(T &) {}
};
#endif

View file

@ -2159,7 +2159,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 | UNIT_STAT_DIED) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) )
if(hasUnitState(UNIT_STAT_CAN_NOT_REACT) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) )
return;
if (!pVictim->isAlive())

View file

@ -405,25 +405,63 @@ enum DeathState
DEAD_FALLING= 5
};
// internal state flags for some auras and movement generators, other.
enum UnitState
{
UNIT_STAT_DIED = 0x0001,
UNIT_STAT_MELEE_ATTACKING = 0x0002, // player is melee attacking someone
//UNIT_STAT_MELEE_ATTACK_BY = 0x0004, // player is melee attack by someone
UNIT_STAT_STUNNED = 0x0008,
UNIT_STAT_ROAMING = 0x0010,
UNIT_STAT_CHASE = 0x0020,
//UNIT_STAT_SEARCHING = 0x0040,
UNIT_STAT_FLEEING = 0x0080,
UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE | UNIT_STAT_FLEEING),
UNIT_STAT_IN_FLIGHT = 0x0100, // player is in flight mode
UNIT_STAT_FOLLOW = 0x0200,
UNIT_STAT_ROOT = 0x0400,
UNIT_STAT_CONFUSED = 0x0800,
UNIT_STAT_DISTRACTED = 0x1000,
UNIT_STAT_ISOLATED = 0x2000, // area auras do not affect other players
UNIT_STAT_ATTACK_PLAYER = 0x4000,
UNIT_STAT_ALL_STATE = 0xffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT)
// persistent state (applied by aura/etc until expire)
UNIT_STAT_MELEE_ATTACKING = 0x00000001, // unit is melee attacking someone Unit::Attack
UNIT_STAT_ATTACK_PLAYER = 0x00000002, // unit attack player or player's controlled unit and have contested pvpv timer setup, until timer expire, combat end and etc
UNIT_STAT_DIED = 0x00000004, // Unit::SetFeignDeath
UNIT_STAT_STUNNED = 0x00000008, // Aura::HandleAuraModStun
UNIT_STAT_ROOT = 0x00000010, // Aura::HandleAuraModRoot
UNIT_STAT_ISOLATED = 0x00000020, // area auras do not affect other players, Aura::HandleAuraModSchoolImmunity
// persistent movement generator state (all time while movement generator applied to unit (independent from top state of movegen)
UNIT_STAT_IN_FLIGHT = 0x00000040, // player is in flight mode
UNIT_STAT_DISTRACTED = 0x00000080, // DistractedMovementGenerator active
// persistent movement generator state with non-persistent mirror states for stop support
// (can be removed temporary by stop command or another movement generator apply)
// not use _MOVE versions for generic movegen state, it can be removed temporary for unit stop and etc
UNIT_STAT_CONFUSED = 0x00000100, // ConfusedMovementGenerator active/onstack
UNIT_STAT_CONFUSED_MOVE = 0x00000200,
UNIT_STAT_ROAMING = 0x00000400, // RandomMovementGenerator/PointMovementGenerator/WaypointMovementGenerator active (now always set)
UNIT_STAT_ROAMING_MOVE = 0x00000800,
UNIT_STAT_CHASE = 0x00001000, // ChaseMovementGenerator active
UNIT_STAT_CHASE_MOVE = 0x00002000,
UNIT_STAT_FOLLOW = 0x00004000, // FollowMovementGenerator active
UNIT_STAT_FOLLOW_MOVE = 0x00008000,
UNIT_STAT_FLEEING = 0x00010000, // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack
UNIT_STAT_FLEEING_MOVE = 0x00020000,
// masks (only for check)
// can't move currently
UNIT_STAT_CAN_NOT_MOVE = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED,
// stay by different reasons
UNIT_STAT_NOT_MOVE = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED |
UNIT_STAT_DISTRACTED,
// stay or scripted movement for effect( = in player case you can't move by client command)
UNIT_STAT_NO_FREE_MOVE = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED |
UNIT_STAT_IN_FLIGHT |
UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING,
UNIT_STAT_MOVE_INTERRUPRED= UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED |
UNIT_STAT_IN_FLIGHT | UNIT_STAT_DISTRACTED |
UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING,
// not react at move in sight or other
UNIT_STAT_CAN_NOT_REACT = UNIT_STAT_STUNNED | UNIT_STAT_DIED |
UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING,
// masks (for check or reset)
// for real move using movegen check and stop (except unstoppable flight)
UNIT_STAT_MOVING = UNIT_STAT_ROAMING_MOVE | UNIT_STAT_CHASE_MOVE | UNIT_STAT_FOLLOW_MOVE | UNIT_STAT_FLEEING_MOVE,
UNIT_STAT_ALL_STATE = 0xFFFFFFFF
};
enum UnitMoveType
@ -944,12 +982,11 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void SendMeleeAttackStart(Unit* pVictim);
void addUnitState(uint32 f) { m_state |= f; }
bool hasUnitState(const uint32 f) const { return (m_state & f); }
bool hasUnitState(uint32 f) const { return (m_state & f); }
void clearUnitState(uint32 f) { m_state &= ~f; }
bool CanFreeMove() const
{
return !hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_IN_FLIGHT |
UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED ) && GetOwnerGUID()==0;
return !hasUnitState(UNIT_STAT_NO_FREE_MOVE) && GetOwnerGUID()==0;
}
uint32 getLevel() const { return GetUInt32Value(UNIT_FIELD_LEVEL); }

View file

@ -74,6 +74,32 @@ void WaypointMovementGenerator<Creature>::ClearWaypoints()
i_path = NULL;
}
void WaypointMovementGenerator<Creature>::Initialize( Creature &u )
{
i_nextMoveTime.Reset(0); // TODO: check the lower bound (0 is probably too small)
u.StopMoving();
LoadPath(u);
u.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING);
}
void WaypointMovementGenerator<Creature>::Finalize( Creature &u )
{
u.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING);
}
void WaypointMovementGenerator<Creature>::Interrupt( Creature &u )
{
u.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING);
}
void WaypointMovementGenerator<Creature>::Reset( Creature &u )
{
ReloadPath(u);
b_StoppedByPlayer = false;
i_nextMoveTime.Reset(0);
u.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING);
}
bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
if (!&creature)
@ -81,12 +107,18 @@ 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 | UNIT_STAT_DIED))
if (creature.hasUnitState(UNIT_STAT_NOT_MOVE))
{
creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
return true;
}
// prevent a crash at empty waypoint path.
if (!i_path || i_path->empty())
{
creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
return true;
}
// i_path was modified by chat commands for example
if (i_path->size() != i_hasDone.size())
@ -108,7 +140,7 @@ bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint3
{
SetStoppedByPlayer(false);
creature.addUnitState(UNIT_STAT_ROAMING);
creature.addUnitState(UNIT_STAT_ROAMING_MOVE);
if (creature.canFly())
creature.AddMonsterMoveFlag(MONSTER_MOVE_FLY);
@ -183,7 +215,7 @@ bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint3
// If stopped then begin a new move segment
if (creature.IsStopped())
{
creature.addUnitState(UNIT_STAT_ROAMING);
creature.addUnitState(UNIT_STAT_ROAMING_MOVE);
if (creature.canFly())
creature.AddMonsterMoveFlag(MONSTER_MOVE_FLY);

View file

@ -76,20 +76,10 @@ public PathMovementBase<Creature, WaypointPath*>
public:
WaypointMovementGenerator(Creature &) : i_nextMoveTime(0), b_StoppedByPlayer(false) {}
~WaypointMovementGenerator() { ClearWaypoints(); }
void Initialize(Creature &u)
{
i_nextMoveTime.Reset(0); // TODO: check the lower bound (0 is probably too small)
u.StopMoving();
LoadPath(u);
}
void Interrupt(Creature &) {}
void Finalize(Creature &) {}
void Reset(Creature &u)
{
ReloadPath(u);
b_StoppedByPlayer = false;
i_nextMoveTime.Reset(0);
}
void Initialize(Creature &u);
void Interrupt(Creature &);
void Finalize(Creature &);
void Reset(Creature &u);
bool Update(Creature &u, const uint32 &diff);
void MovementInform(Creature &);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9207"
#define REVISION_NR "9208"
#endif // __REVISION_NR_H__