mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-19 00:48:56 +01:00
Merge pull request #18053 from ccrs/motion
Core/MotionMaster: cleanup, reordering and renaming
This commit is contained in:
@@ -20,7 +20,6 @@
|
||||
#include "CreatureAISelector.h"
|
||||
#include "Creature.h"
|
||||
#include "ScriptSystem.h"
|
||||
|
||||
#include "ConfusedMovementGenerator.h"
|
||||
#include "FleeingMovementGenerator.h"
|
||||
#include "HomeMovementGenerator.h"
|
||||
@@ -33,9 +32,21 @@
|
||||
#include "MoveSpline.h"
|
||||
#include "MoveSplineInit.h"
|
||||
|
||||
inline bool isStatic(MovementGenerator *mv)
|
||||
inline bool IsStatic(MovementGenerator* movement)
|
||||
{
|
||||
return (mv == &si_idleMovement);
|
||||
return (movement == &si_idleMovement);
|
||||
}
|
||||
|
||||
MotionMaster::~MotionMaster()
|
||||
{
|
||||
// clear ALL movement generators (including default)
|
||||
while (!empty())
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
pop();
|
||||
if (curr && !IsStatic(curr))
|
||||
delete curr; // Skip finalizing on delete, it might launch new movement
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::Initialize()
|
||||
@@ -66,18 +77,6 @@ void MotionMaster::InitDefault()
|
||||
}
|
||||
}
|
||||
|
||||
MotionMaster::~MotionMaster()
|
||||
{
|
||||
// clear ALL movement generators (including default)
|
||||
while (!empty())
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
pop();
|
||||
if (curr && !isStatic(curr))
|
||||
delete curr; // Skip finalizing on delete, it might launch new movement
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::UpdateMotion(uint32 diff)
|
||||
{
|
||||
if (!_owner)
|
||||
@@ -97,20 +96,20 @@ void MotionMaster::UpdateMotion(uint32 diff)
|
||||
else
|
||||
_cleanFlag &= ~MMCF_UPDATE;
|
||||
|
||||
if (_expList)
|
||||
if (_expireList)
|
||||
{
|
||||
for (size_t i = 0; i < _expList->size(); ++i)
|
||||
for (size_t i = 0; i < _expireList->size(); ++i)
|
||||
{
|
||||
MovementGenerator* mg = (*_expList)[i];
|
||||
MovementGenerator* mg = (*_expireList)[i];
|
||||
DirectDelete(mg);
|
||||
}
|
||||
|
||||
delete _expList;
|
||||
_expList = NULL;
|
||||
delete _expireList;
|
||||
_expireList = nullptr;
|
||||
|
||||
if (empty())
|
||||
Initialize();
|
||||
else if (needInitTop())
|
||||
else if (NeedInitTop())
|
||||
InitTop();
|
||||
else if (_cleanFlag & MMCF_RESET)
|
||||
top()->Reset(_owner);
|
||||
@@ -122,84 +121,84 @@ void MotionMaster::UpdateMotion(uint32 diff)
|
||||
_owner->UpdateUnderwaterState(_owner->GetMap(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ());
|
||||
}
|
||||
|
||||
void MotionMaster::DirectClean(bool reset)
|
||||
void MotionMaster::Clear(bool reset /*= true*/)
|
||||
{
|
||||
while (size() > 1)
|
||||
if (_cleanFlag & MMCF_UPDATE)
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
pop();
|
||||
if (curr) DirectDelete(curr);
|
||||
if (reset)
|
||||
_cleanFlag |= MMCF_RESET;
|
||||
else
|
||||
_cleanFlag &= ~MMCF_RESET;
|
||||
DelayedClean();
|
||||
}
|
||||
else
|
||||
DirectClean(reset);
|
||||
}
|
||||
|
||||
void MotionMaster::MovementExpired(bool reset /*= true*/)
|
||||
{
|
||||
if (_cleanFlag & MMCF_UPDATE)
|
||||
{
|
||||
if (reset)
|
||||
_cleanFlag |= MMCF_RESET;
|
||||
else
|
||||
_cleanFlag &= ~MMCF_RESET;
|
||||
DelayedExpire();
|
||||
}
|
||||
else
|
||||
DirectExpire(reset);
|
||||
}
|
||||
|
||||
MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const
|
||||
{
|
||||
if (empty())
|
||||
return;
|
||||
return IDLE_MOTION_TYPE;
|
||||
|
||||
if (needInitTop())
|
||||
InitTop();
|
||||
else if (reset)
|
||||
top()->Reset(_owner);
|
||||
return top()->GetMovementGeneratorType();
|
||||
}
|
||||
|
||||
void MotionMaster::DelayedClean()
|
||||
MovementGeneratorType MotionMaster::GetMotionSlotType(int slot) const
|
||||
{
|
||||
while (size() > 1)
|
||||
if (!_slot[slot])
|
||||
return NULL_MOTION_TYPE;
|
||||
else
|
||||
return _slot[slot]->GetMovementGeneratorType();
|
||||
}
|
||||
|
||||
MovementGenerator* MotionMaster::GetMotionSlot(int slot) const
|
||||
{
|
||||
ASSERT(slot >= 0);
|
||||
return _slot[slot];
|
||||
}
|
||||
|
||||
void MotionMaster::propagateSpeedChange()
|
||||
{
|
||||
for (int i = 0; i <= _top; ++i)
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
pop();
|
||||
if (curr)
|
||||
DelayedDelete(curr);
|
||||
if (_slot[i])
|
||||
_slot[i]->unitSpeedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::DirectExpire(bool reset)
|
||||
bool MotionMaster::GetDestination(float &x, float &y, float &z)
|
||||
{
|
||||
if (size() > 1)
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
pop();
|
||||
DirectDelete(curr);
|
||||
}
|
||||
if (_owner->movespline->Finalized())
|
||||
return false;
|
||||
|
||||
while (!empty() && !top())
|
||||
--_top;
|
||||
|
||||
if (empty())
|
||||
Initialize();
|
||||
else if (needInitTop())
|
||||
InitTop();
|
||||
else if (reset)
|
||||
top()->Reset(_owner);
|
||||
}
|
||||
|
||||
void MotionMaster::DelayedExpire()
|
||||
{
|
||||
if (size() > 1)
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
pop();
|
||||
DelayedDelete(curr);
|
||||
}
|
||||
|
||||
while (!empty() && !top())
|
||||
--_top;
|
||||
G3D::Vector3 const& dest = _owner->movespline->FinalDestination();
|
||||
x = dest.x;
|
||||
y = dest.y;
|
||||
z = dest.z;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MotionMaster::MoveIdle()
|
||||
{
|
||||
//! Should be preceded by MovementExpired or Clear if there's an overlying movementgenerator active
|
||||
if (empty() || !isStatic(top()))
|
||||
if (empty() || !IsStatic(top()))
|
||||
Mutate(&si_idleMovement, MOTION_SLOT_IDLE);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveRandom(float spawndist)
|
||||
{
|
||||
if (_owner->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Creature (GUID: %u) started random movement.", _owner->GetGUID().GetCounter());
|
||||
Mutate(new RandomMovementGenerator<Creature>(spawndist), MOTION_SLOT_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::MoveTargetedHome()
|
||||
{
|
||||
Clear(false);
|
||||
@@ -225,18 +224,36 @@ void MotionMaster::MoveTargetedHome()
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::MoveConfused()
|
||||
void MotionMaster::MoveRandom(float spawndist)
|
||||
{
|
||||
if (_owner->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Creature (GUID: %u) started random movement.", _owner->GetGUID().GetCounter());
|
||||
Mutate(new RandomMovementGenerator<Creature>(spawndist), MOTION_SLOT_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlot slot)
|
||||
{
|
||||
// ignore movement request if target not exist
|
||||
if (!target || target == _owner)
|
||||
return;
|
||||
|
||||
//_owner->AddUnitState(UNIT_STATE_FOLLOW);
|
||||
if (_owner->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Player (GUID: %u) move confused", _owner->GetGUID().GetCounter());
|
||||
Mutate(new ConfusedMovementGenerator<Player>(), MOTION_SLOT_CONTROLLED);
|
||||
TC_LOG_DEBUG("misc", "Player (GUID: %u) follows %s (GUID: %u).", _owner->GetGUID().GetCounter(),
|
||||
target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
|
||||
target->GetTypeId() == TYPEID_PLAYER ? target->GetGUID().GetCounter() : target->ToCreature()->GetSpawnId());
|
||||
Mutate(new FollowMovementGenerator<Player>(target, dist, angle), slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) move confused",
|
||||
_owner->GetEntry(), _owner->GetGUID().GetCounter());
|
||||
Mutate(new ConfusedMovementGenerator<Creature>(), MOTION_SLOT_CONTROLLED);
|
||||
TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) follows %s (GUID: %u).",
|
||||
_owner->GetEntry(), _owner->GetGUID().GetCounter(),
|
||||
target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
|
||||
target->GetTypeId() == TYPEID_PLAYER ? target->GetGUID().GetCounter() : target->ToCreature()->GetSpawnId());
|
||||
Mutate(new FollowMovementGenerator<Creature>(target, dist, angle), slot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,27 +282,44 @@ void MotionMaster::MoveChase(Unit* target, float dist, float angle)
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlot slot)
|
||||
void MotionMaster::MoveConfused()
|
||||
{
|
||||
// ignore movement request if target not exist
|
||||
if (!target || target == _owner)
|
||||
return;
|
||||
|
||||
//_owner->AddUnitState(UNIT_STATE_FOLLOW);
|
||||
if (_owner->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Player (GUID: %u) follows %s (GUID: %u).", _owner->GetGUID().GetCounter(),
|
||||
target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
|
||||
target->GetTypeId() == TYPEID_PLAYER ? target->GetGUID().GetCounter() : target->ToCreature()->GetSpawnId());
|
||||
Mutate(new FollowMovementGenerator<Player>(target, dist, angle), slot);
|
||||
TC_LOG_DEBUG("misc", "Player (GUID: %u) move confused", _owner->GetGUID().GetCounter());
|
||||
Mutate(new ConfusedMovementGenerator<Player>(), MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) follows %s (GUID: %u).",
|
||||
TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) move confused",
|
||||
_owner->GetEntry(), _owner->GetGUID().GetCounter());
|
||||
Mutate(new ConfusedMovementGenerator<Creature>(), MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::MoveFleeing(Unit* enemy, uint32 time)
|
||||
{
|
||||
if (!enemy)
|
||||
return;
|
||||
|
||||
if (_owner->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Player (GUID: %u) flees from %s (GUID: %u).", _owner->GetGUID().GetCounter(),
|
||||
enemy->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
|
||||
enemy->GetTypeId() == TYPEID_PLAYER ? enemy->GetGUID().GetCounter() : enemy->ToCreature()->GetSpawnId());
|
||||
Mutate(new FleeingMovementGenerator<Player>(enemy->GetGUID()), MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) flees from %s (GUID: %u)%s.",
|
||||
_owner->GetEntry(), _owner->GetGUID().GetCounter(),
|
||||
target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
|
||||
target->GetTypeId() == TYPEID_PLAYER ? target->GetGUID().GetCounter() : target->ToCreature()->GetSpawnId());
|
||||
Mutate(new FollowMovementGenerator<Creature>(target, dist, angle), slot);
|
||||
enemy->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
|
||||
enemy->GetTypeId() == TYPEID_PLAYER ? enemy->GetGUID().GetCounter() : enemy->ToCreature()->GetSpawnId(),
|
||||
time ? " for a limited time" : "");
|
||||
if (time)
|
||||
Mutate(new TimedFleeingMovementGenerator(enemy->GetGUID(), time), MOTION_SLOT_CONTROLLED);
|
||||
else
|
||||
Mutate(new FleeingMovementGenerator<Creature>(enemy->GetGUID()), MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,6 +387,37 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos)
|
||||
Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveCharge(float x, float y, float z, float speed /*= SPEED_CHARGE*/, uint32 id /*= EVENT_CHARGE*/, bool generatePath /*= false*/)
|
||||
{
|
||||
if (_slot[MOTION_SLOT_CONTROLLED] && _slot[MOTION_SLOT_CONTROLLED]->GetMovementGeneratorType() != DISTRACT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (_owner->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Player (GUID: %u) charged point (X: %f Y: %f Z: %f).", _owner->GetGUID().GetCounter(), x, y, z);
|
||||
Mutate(new PointMovementGenerator<Player>(id, x, y, z, generatePath, speed), MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) charged point (X: %f Y: %f Z: %f).",
|
||||
_owner->GetEntry(), _owner->GetGUID().GetCounter(), x, y, z);
|
||||
Mutate(new PointMovementGenerator<Creature>(id, x, y, z, generatePath, speed), MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::MoveCharge(PathGenerator const& path, float speed /*= SPEED_CHARGE*/)
|
||||
{
|
||||
G3D::Vector3 dest = path.GetActualEndPosition();
|
||||
|
||||
MoveCharge(dest.x, dest.y, dest.z, speed, EVENT_CHARGE_PREPATH);
|
||||
|
||||
// Charge movement is not started when using EVENT_CHARGE_PREPATH
|
||||
Movement::MoveSplineInit init(_owner);
|
||||
init.MovebyPath(path.GetPath());
|
||||
init.SetVelocity(speed);
|
||||
init.Launch();
|
||||
}
|
||||
|
||||
void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ)
|
||||
{
|
||||
//this function may make players fall below map
|
||||
@@ -531,37 +596,6 @@ void MotionMaster::MoveFall(uint32 id /*=0*/)
|
||||
Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveCharge(float x, float y, float z, float speed /*= SPEED_CHARGE*/, uint32 id /*= EVENT_CHARGE*/, bool generatePath /*= false*/)
|
||||
{
|
||||
if (Impl[MOTION_SLOT_CONTROLLED] && Impl[MOTION_SLOT_CONTROLLED]->GetMovementGeneratorType() != DISTRACT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (_owner->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Player (GUID: %u) charged point (X: %f Y: %f Z: %f).", _owner->GetGUID().GetCounter(), x, y, z);
|
||||
Mutate(new PointMovementGenerator<Player>(id, x, y, z, generatePath, speed), MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) charged point (X: %f Y: %f Z: %f).",
|
||||
_owner->GetEntry(), _owner->GetGUID().GetCounter(), x, y, z);
|
||||
Mutate(new PointMovementGenerator<Creature>(id, x, y, z, generatePath, speed), MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::MoveCharge(PathGenerator const& path, float speed /*= SPEED_CHARGE*/)
|
||||
{
|
||||
G3D::Vector3 dest = path.GetActualEndPosition();
|
||||
|
||||
MoveCharge(dest.x, dest.y, dest.z, speed, EVENT_CHARGE_PREPATH);
|
||||
|
||||
// Charge movement is not started when using EVENT_CHARGE_PREPATH
|
||||
Movement::MoveSplineInit init(_owner);
|
||||
init.MovebyPath(path.GetPath());
|
||||
init.SetVelocity(speed);
|
||||
init.Launch();
|
||||
}
|
||||
|
||||
void MotionMaster::MoveSeekAssistance(float x, float y, float z)
|
||||
{
|
||||
if (_owner->GetTypeId() == TYPEID_PLAYER)
|
||||
@@ -593,32 +627,6 @@ void MotionMaster::MoveSeekAssistanceDistract(uint32 time)
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::MoveFleeing(Unit* enemy, uint32 time)
|
||||
{
|
||||
if (!enemy)
|
||||
return;
|
||||
|
||||
if (_owner->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Player (GUID: %u) flees from %s (GUID: %u).", _owner->GetGUID().GetCounter(),
|
||||
enemy->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
|
||||
enemy->GetTypeId() == TYPEID_PLAYER ? enemy->GetGUID().GetCounter() : enemy->ToCreature()->GetSpawnId());
|
||||
Mutate(new FleeingMovementGenerator<Player>(enemy->GetGUID()), MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) flees from %s (GUID: %u)%s.",
|
||||
_owner->GetEntry(), _owner->GetGUID().GetCounter(),
|
||||
enemy->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
|
||||
enemy->GetTypeId() == TYPEID_PLAYER ? enemy->GetGUID().GetCounter() : enemy->ToCreature()->GetSpawnId(),
|
||||
time ? " for a limited time" : "");
|
||||
if (time)
|
||||
Mutate(new TimedFleeingMovementGenerator(enemy->GetGUID(), time), MOTION_SLOT_CONTROLLED);
|
||||
else
|
||||
Mutate(new FleeingMovementGenerator<Creature>(enemy->GetGUID()), MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode)
|
||||
{
|
||||
if (_owner->GetTypeId() == TYPEID_PLAYER)
|
||||
@@ -645,7 +653,7 @@ void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode)
|
||||
|
||||
void MotionMaster::MoveDistract(uint32 timer)
|
||||
{
|
||||
if (Impl[MOTION_SLOT_CONTROLLED])
|
||||
if (_slot[MOTION_SLOT_CONTROLLED])
|
||||
return;
|
||||
|
||||
if (_owner->GetTypeId() == TYPEID_PLAYER)
|
||||
@@ -662,48 +670,11 @@ void MotionMaster::MoveDistract(uint32 timer)
|
||||
Mutate(mgen, MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
|
||||
void MotionMaster::Mutate(MovementGenerator *m, MovementSlot slot)
|
||||
{
|
||||
if (MovementGenerator *curr = Impl[slot])
|
||||
{
|
||||
Impl[slot] = NULL; // in case a new one is generated in this slot during directdelete
|
||||
if (_top == slot && (_cleanFlag & MMCF_UPDATE))
|
||||
DelayedDelete(curr);
|
||||
else
|
||||
DirectDelete(curr);
|
||||
}
|
||||
else if (_top < slot)
|
||||
{
|
||||
_top = slot;
|
||||
}
|
||||
|
||||
Impl[slot] = m;
|
||||
if (_top > slot)
|
||||
_needInit[slot] = true;
|
||||
else
|
||||
{
|
||||
_needInit[slot] = false;
|
||||
m->Initialize(_owner);
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::MovePath(uint32 path_id, bool repeatable)
|
||||
{
|
||||
if (!path_id)
|
||||
return;
|
||||
//We set waypoint movement as new default movement generator
|
||||
// clear ALL movement generators (including default)
|
||||
/*while (!empty())
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
curr->Finalize(*_owner);
|
||||
pop();
|
||||
if (!isStatic(curr))
|
||||
delete curr;
|
||||
}*/
|
||||
|
||||
//_owner->GetTypeId() == TYPEID_PLAYER ?
|
||||
//Mutate(new WaypointMovementGenerator<Player>(path_id, repeatable)):
|
||||
Mutate(new WaypointMovementGenerator<Creature>(path_id, repeatable), MOTION_SLOT_IDLE);
|
||||
|
||||
TC_LOG_DEBUG("misc", "%s (GUID: %u) starts moving over path(Id:%u, repeatable: %s).",
|
||||
@@ -719,68 +690,132 @@ void MotionMaster::MoveRotate(uint32 time, RotateDirection direction)
|
||||
Mutate(new RotateMovementGenerator(time, direction), MOTION_SLOT_ACTIVE);
|
||||
}
|
||||
|
||||
void MotionMaster::propagateSpeedChange()
|
||||
/******************** Private methods ********************/
|
||||
|
||||
void MotionMaster::pop()
|
||||
{
|
||||
/*Impl::container_type::iterator it = Impl::c.begin();
|
||||
for (; it != end(); ++it)
|
||||
{
|
||||
(*it)->unitSpeedChanged();
|
||||
}*/
|
||||
for (int i = 0; i <= _top; ++i)
|
||||
{
|
||||
if (Impl[i])
|
||||
Impl[i]->unitSpeedChanged();
|
||||
}
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
_slot[_top] = nullptr;
|
||||
while (!empty() && !top())
|
||||
--_top;
|
||||
}
|
||||
|
||||
MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const
|
||||
bool MotionMaster::NeedInitTop() const
|
||||
{
|
||||
if (empty())
|
||||
return IDLE_MOTION_TYPE;
|
||||
|
||||
return top()->GetMovementGeneratorType();
|
||||
}
|
||||
|
||||
MovementGeneratorType MotionMaster::GetMotionSlotType(int slot) const
|
||||
{
|
||||
if (!Impl[slot])
|
||||
return NULL_MOTION_TYPE;
|
||||
else
|
||||
return Impl[slot]->GetMovementGeneratorType();
|
||||
if (empty())
|
||||
return false;
|
||||
return _initialize[_top];
|
||||
}
|
||||
|
||||
void MotionMaster::InitTop()
|
||||
{
|
||||
top()->Initialize(_owner);
|
||||
_needInit[_top] = false;
|
||||
_initialize[_top] = false;
|
||||
}
|
||||
|
||||
void MotionMaster::DirectDelete(_Ty curr)
|
||||
void MotionMaster::Mutate(MovementGenerator *m, MovementSlot slot)
|
||||
{
|
||||
if (isStatic(curr))
|
||||
if (MovementGenerator *curr = _slot[slot])
|
||||
{
|
||||
_slot[slot] = nullptr; // in case a new one is generated in this slot during directdelete
|
||||
if (_top == slot && (_cleanFlag & MMCF_UPDATE))
|
||||
DelayedDelete(curr);
|
||||
else
|
||||
DirectDelete(curr);
|
||||
}
|
||||
else if (_top < slot)
|
||||
{
|
||||
_top = slot;
|
||||
}
|
||||
|
||||
_slot[slot] = m;
|
||||
if (_top > slot)
|
||||
_initialize[slot] = true;
|
||||
else
|
||||
{
|
||||
_initialize[slot] = false;
|
||||
m->Initialize(_owner);
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::DirectClean(bool reset)
|
||||
{
|
||||
while (size() > 1)
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
pop();
|
||||
if (curr) DirectDelete(curr);
|
||||
}
|
||||
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
if (NeedInitTop())
|
||||
InitTop();
|
||||
else if (reset)
|
||||
top()->Reset(_owner);
|
||||
}
|
||||
|
||||
void MotionMaster::DelayedClean()
|
||||
{
|
||||
while (size() > 1)
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
pop();
|
||||
if (curr)
|
||||
DelayedDelete(curr);
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::DirectExpire(bool reset)
|
||||
{
|
||||
if (size() > 1)
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
pop();
|
||||
DirectDelete(curr);
|
||||
}
|
||||
|
||||
while (!empty() && !top())
|
||||
--_top;
|
||||
|
||||
if (empty())
|
||||
Initialize();
|
||||
else if (NeedInitTop())
|
||||
InitTop();
|
||||
else if (reset)
|
||||
top()->Reset(_owner);
|
||||
}
|
||||
|
||||
void MotionMaster::DelayedExpire()
|
||||
{
|
||||
if (size() > 1)
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
pop();
|
||||
DelayedDelete(curr);
|
||||
}
|
||||
|
||||
while (!empty() && !top())
|
||||
--_top;
|
||||
}
|
||||
|
||||
void MotionMaster::DirectDelete(MovementGenerator* curr)
|
||||
{
|
||||
if (IsStatic(curr))
|
||||
return;
|
||||
curr->Finalize(_owner);
|
||||
delete curr;
|
||||
}
|
||||
|
||||
void MotionMaster::DelayedDelete(_Ty curr)
|
||||
void MotionMaster::DelayedDelete(MovementGenerator* curr)
|
||||
{
|
||||
TC_LOG_FATAL("misc", "Unit (Entry %u) is trying to delete its updating Movement Generator (Type %u)!", _owner->GetEntry(), curr->GetMovementGeneratorType());
|
||||
if (isStatic(curr))
|
||||
if (IsStatic(curr))
|
||||
return;
|
||||
if (!_expList)
|
||||
_expList = new ExpireList();
|
||||
_expList->push_back(curr);
|
||||
}
|
||||
|
||||
bool MotionMaster::GetDestination(float &x, float &y, float &z)
|
||||
{
|
||||
if (_owner->movespline->Finalized())
|
||||
return false;
|
||||
|
||||
G3D::Vector3 const& dest = _owner->movespline->FinalDestination();
|
||||
x = dest.x;
|
||||
y = dest.y;
|
||||
z = dest.z;
|
||||
return true;
|
||||
if (!_expireList)
|
||||
_expireList = new ExpireList();
|
||||
_expireList->push_back(curr);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_MOTIONMASTER_H
|
||||
#define TRINITY_MOTIONMASTER_H
|
||||
#ifndef MOTIONMASTER_H
|
||||
#define MOTIONMASTER_H
|
||||
|
||||
#include "Common.h"
|
||||
#include <vector>
|
||||
@@ -32,31 +32,32 @@ class PathGenerator;
|
||||
|
||||
// Creature Entry ID used for waypoints show, visible only for GMs
|
||||
#define VISUAL_WAYPOINT 1
|
||||
// assume it is 25 yard per 0.6 second
|
||||
#define SPEED_CHARGE 42.0f
|
||||
|
||||
// values 0 ... MAX_DB_MOTION_TYPE-1 used in DB
|
||||
enum MovementGeneratorType
|
||||
{
|
||||
IDLE_MOTION_TYPE = 0, // IdleMovementGenerator.h
|
||||
RANDOM_MOTION_TYPE = 1, // RandomMovementGenerator.h
|
||||
WAYPOINT_MOTION_TYPE = 2, // WaypointMovementGenerator.h
|
||||
MAX_DB_MOTION_TYPE = 3, // *** this and below motion types can't be set in DB.
|
||||
ANIMAL_RANDOM_MOTION_TYPE = MAX_DB_MOTION_TYPE, // AnimalRandomMovementGenerator.h
|
||||
CONFUSED_MOTION_TYPE = 4, // ConfusedMovementGenerator.h
|
||||
CHASE_MOTION_TYPE = 5, // TargetedMovementGenerator.h
|
||||
HOME_MOTION_TYPE = 6, // HomeMovementGenerator.h
|
||||
FLIGHT_MOTION_TYPE = 7, // WaypointMovementGenerator.h
|
||||
POINT_MOTION_TYPE = 8, // PointMovementGenerator.h
|
||||
FLEEING_MOTION_TYPE = 9, // FleeingMovementGenerator.h
|
||||
DISTRACT_MOTION_TYPE = 10, // IdleMovementGenerator.h
|
||||
ASSISTANCE_MOTION_TYPE= 11, // PointMovementGenerator.h (first part of flee for assistance)
|
||||
ASSISTANCE_DISTRACT_MOTION_TYPE = 12, // IdleMovementGenerator.h (second part of flee for assistance)
|
||||
TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h (alt.second part of flee for assistance)
|
||||
FOLLOW_MOTION_TYPE = 14,
|
||||
ROTATE_MOTION_TYPE = 15,
|
||||
EFFECT_MOTION_TYPE = 16,
|
||||
NULL_MOTION_TYPE = 17,
|
||||
SPLINE_CHAIN_MOTION_TYPE = 18, // SplineChainMovementGenerator.h
|
||||
MAX_MOTION_TYPE // limit
|
||||
IDLE_MOTION_TYPE = 0, // IdleMovementGenerator.h
|
||||
RANDOM_MOTION_TYPE = 1, // RandomMovementGenerator.h
|
||||
WAYPOINT_MOTION_TYPE = 2, // WaypointMovementGenerator.h
|
||||
MAX_DB_MOTION_TYPE = 3, // Below motion types can't be set in DB.
|
||||
ANIMAL_RANDOM_MOTION_TYPE = MAX_DB_MOTION_TYPE, // AnimalRandomMovementGenerator.h
|
||||
CONFUSED_MOTION_TYPE = 4, // ConfusedMovementGenerator.h
|
||||
CHASE_MOTION_TYPE = 5, // TargetedMovementGenerator.h
|
||||
HOME_MOTION_TYPE = 6, // HomeMovementGenerator.h
|
||||
FLIGHT_MOTION_TYPE = 7, // WaypointMovementGenerator.h
|
||||
POINT_MOTION_TYPE = 8, // PointMovementGenerator.h
|
||||
FLEEING_MOTION_TYPE = 9, // FleeingMovementGenerator.h
|
||||
DISTRACT_MOTION_TYPE = 10, // IdleMovementGenerator.h
|
||||
ASSISTANCE_MOTION_TYPE = 11, // PointMovementGenerator.h (first part of flee for assistance)
|
||||
ASSISTANCE_DISTRACT_MOTION_TYPE = 12, // IdleMovementGenerator.h (second part of flee for assistance)
|
||||
TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h (alt.second part of flee for assistance)
|
||||
FOLLOW_MOTION_TYPE = 14,
|
||||
ROTATE_MOTION_TYPE = 15,
|
||||
EFFECT_MOTION_TYPE = 16,
|
||||
NULL_MOTION_TYPE = 17,
|
||||
SPLINE_CHAIN_MOTION_TYPE = 18, // SplineChainMovementGenerator.h
|
||||
MAX_MOTION_TYPE // limit
|
||||
};
|
||||
|
||||
enum MovementSlot
|
||||
@@ -80,91 +81,41 @@ enum RotateDirection
|
||||
ROTATE_DIRECTION_RIGHT
|
||||
};
|
||||
|
||||
// assume it is 25 yard per 0.6 second
|
||||
#define SPEED_CHARGE 42.0f
|
||||
|
||||
class TC_GAME_API MotionMaster //: private std::stack<MovementGenerator *>
|
||||
class TC_GAME_API MotionMaster
|
||||
{
|
||||
private:
|
||||
//typedef std::stack<MovementGenerator *> Impl;
|
||||
typedef MovementGenerator* _Ty;
|
||||
typedef std::vector<MovementGenerator*> ExpireList;
|
||||
|
||||
void pop()
|
||||
{
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
Impl[_top] = NULL;
|
||||
while (!empty() && !top())
|
||||
--_top;
|
||||
}
|
||||
void push(_Ty _Val) { ++_top; Impl[_top] = _Val; }
|
||||
|
||||
bool needInitTop() const
|
||||
{
|
||||
if (empty())
|
||||
return false;
|
||||
return _needInit[_top];
|
||||
}
|
||||
void InitTop();
|
||||
public:
|
||||
|
||||
explicit MotionMaster(Unit* unit) : _expList(NULL), _top(-1), _owner(unit), _cleanFlag(MMCF_NONE)
|
||||
explicit MotionMaster(Unit* unit) : _expireList(nullptr), _top(-1), _owner(unit), _cleanFlag(MMCF_NONE)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i)
|
||||
{
|
||||
Impl[i] = NULL;
|
||||
_needInit[i] = true;
|
||||
_slot[i] = nullptr;
|
||||
_initialize[i] = true;
|
||||
}
|
||||
}
|
||||
~MotionMaster();
|
||||
|
||||
bool empty() const { return (_top < 0); }
|
||||
int size() const { return _top + 1; }
|
||||
MovementGenerator* top() const { ASSERT(!empty()); return _slot[_top]; }
|
||||
|
||||
void Initialize();
|
||||
void InitDefault();
|
||||
|
||||
bool empty() const { return (_top < 0); }
|
||||
int size() const { return _top + 1; }
|
||||
_Ty top() const
|
||||
{
|
||||
ASSERT(!empty());
|
||||
return Impl[_top];
|
||||
}
|
||||
_Ty GetMotionSlot(int slot) const
|
||||
{
|
||||
ASSERT(slot >= 0);
|
||||
return Impl[slot];
|
||||
}
|
||||
|
||||
void DirectDelete(_Ty curr);
|
||||
void DelayedDelete(_Ty curr);
|
||||
|
||||
void UpdateMotion(uint32 diff);
|
||||
void Clear(bool reset = true)
|
||||
{
|
||||
if (_cleanFlag & MMCF_UPDATE)
|
||||
{
|
||||
if (reset)
|
||||
_cleanFlag |= MMCF_RESET;
|
||||
else
|
||||
_cleanFlag &= ~MMCF_RESET;
|
||||
DelayedClean();
|
||||
}
|
||||
else
|
||||
DirectClean(reset);
|
||||
}
|
||||
void MovementExpired(bool reset = true)
|
||||
{
|
||||
if (_cleanFlag & MMCF_UPDATE)
|
||||
{
|
||||
if (reset)
|
||||
_cleanFlag |= MMCF_RESET;
|
||||
else
|
||||
_cleanFlag &= ~MMCF_RESET;
|
||||
DelayedExpire();
|
||||
}
|
||||
else
|
||||
DirectExpire(reset);
|
||||
}
|
||||
|
||||
void Clear(bool reset = true);
|
||||
void MovementExpired(bool reset = true);
|
||||
|
||||
MovementGeneratorType GetCurrentMovementGeneratorType() const;
|
||||
MovementGeneratorType GetMotionSlotType(int slot) const;
|
||||
MovementGenerator* GetMotionSlot(int slot) const;
|
||||
|
||||
void propagateSpeedChange();
|
||||
|
||||
bool GetDestination(float &x, float &y, float &z);
|
||||
|
||||
void MoveIdle();
|
||||
void MoveTargetedHome();
|
||||
@@ -174,7 +125,9 @@ class TC_GAME_API MotionMaster //: private std::stack<MovementGenerator *>
|
||||
void MoveConfused();
|
||||
void MoveFleeing(Unit* enemy, uint32 time = 0);
|
||||
void MovePoint(uint32 id, Position const& pos, bool generatePath = true)
|
||||
{ MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ, generatePath); }
|
||||
{
|
||||
MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ, generatePath);
|
||||
}
|
||||
void MovePoint(uint32 id, float x, float y, float z, bool generatePath = true);
|
||||
|
||||
/* Makes the unit move toward the target until it is at a certain distance from it. The unit then stops.
|
||||
@@ -212,27 +165,27 @@ class TC_GAME_API MotionMaster //: private std::stack<MovementGenerator *>
|
||||
void MovePath(uint32 path_id, bool repeatable);
|
||||
void MoveRotate(uint32 time, RotateDirection direction);
|
||||
|
||||
MovementGeneratorType GetCurrentMovementGeneratorType() const;
|
||||
MovementGeneratorType GetMotionSlotType(int slot) const;
|
||||
|
||||
void propagateSpeedChange();
|
||||
|
||||
bool GetDestination(float &x, float &y, float &z);
|
||||
private:
|
||||
void Mutate(MovementGenerator *m, MovementSlot slot); // use Move* functions instead
|
||||
void pop();
|
||||
|
||||
bool NeedInitTop() const;
|
||||
void InitTop();
|
||||
|
||||
void Mutate(MovementGenerator *m, MovementSlot slot);
|
||||
|
||||
void DirectClean(bool reset);
|
||||
void DelayedClean();
|
||||
|
||||
void DirectExpire(bool reset);
|
||||
void DelayedExpire();
|
||||
void DirectDelete(MovementGenerator* curr);
|
||||
void DelayedDelete(MovementGenerator* curr);
|
||||
|
||||
typedef std::vector<_Ty> ExpireList;
|
||||
ExpireList* _expList;
|
||||
_Ty Impl[MAX_MOTION_SLOT];
|
||||
ExpireList* _expireList;
|
||||
MovementGenerator* _slot[MAX_MOTION_SLOT];
|
||||
int _top;
|
||||
Unit* _owner;
|
||||
bool _needInit[MAX_MOTION_SLOT];
|
||||
bool _initialize[MAX_MOTION_SLOT];
|
||||
uint8 _cleanFlag;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // MOTIONMASTER_H
|
||||
|
||||
Reference in New Issue
Block a user