25#include "G3DPosition.hpp"
146 std::vector<MovementGeneratorInformation> list;
162 list.emplace_back(type, target->GetGUID(), target->GetName());
218 return (*
_generators.begin())->GetMovementGeneratorType();
382 auto itr = std::find(bounds.first, bounds.second, movement);
421 return a->GetMovementGeneratorType() == type;
497 return a->Mode == mode;
519 return a->Priority == priority;
611 if (!target || target ==
_owner)
621 if (!target || target ==
_owner)
664 Add(
new PointMovementGenerator(
id, x, y, z, generatePath, speed, finalOrient,
nullptr,
nullptr, speedSelectionMode, closeEnoughDistance));
670 if (distanceToTravel > 0.0f)
684 init.SetFacing(refreshedTarget);
697 init.MoveTo(PositionToVector3(pos),
false);
699 switch (speedSelectionMode)
712 init.SetVelocity(*velocity);
724 init.MoveTo(PositionToVector3(pos),
false);
726 switch (speedSelectionMode)
739 init.SetVelocity(*velocity);
773 if (spellEffectExtraData)
789 float dist = 2 * moveTimeHalf * speedXY;
820 float dist = 2 * moveTimeHalf * speedXY;
825 MoveJump(x, y, z, 0.0f, speedXY, speedZ);
846 init.
MoveTo(x, y, z,
false);
855 uint32 arrivalSpellId = 0;
859 arrivalSpellId = arrivalCast->
SpellId;
860 arrivalSpellTargetGuid = arrivalCast->
Target;
864 { .ArrivalSpellId = arrivalSpellId, .ArrivalSpellTarget = arrivalSpellTargetGuid });
890 uint32 arrivalSpellId = 0;
894 arrivalSpellId = arrivalCast->
SpellId;
895 arrivalSpellTargetGuid = arrivalCast->
Target;
899 { .ArrivalSpellId = arrivalSpellId, .ArrivalSpellTarget = arrivalSpellTargetGuid });
912 float step = 2 * float(
M_PI) / stepCount * (clockwise ? -1.0f : 1.0f);
913 Position const& pos = { x, y, z, 0.0f };
919 for (
uint8 i = 0; i < stepCount; angle += step, ++i)
921 G3D::Vector3& point = init.Path().emplace_back();
922 point.x = x + radius * cosf(angle);
923 point.y = y + radius * sinf(angle);
940 switch (speedSelectionMode)
953 init.SetVelocity(*speed);
963 std::transform(pathPoints, pathPoints +
pathSize, std::back_inserter(path), [](
Position const& point)
969 init.MovebyPath(path);
974 init.SetUncompressed();
993 std::vector<SplineChainLink>
const* chain =
sScriptSystemMgr->GetSplineChain(owner, dbChainId);
996 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::MoveAlongSplineChain: '{}', tried to walk along non-existing spline chain with DB Id: {}.",
_owner->
GetGUID().
ToString(), dbChainId);
1023 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveFall: '{}', unable to retrieve a proper height at map Id: {} (X: {}, Y: {}, Z: {})",
1060 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveSeekAssistance: '{}', seeks assistance (X: {}, Y: {}, Z: {})", creature->GetGUID().ToString(), x, y, z);
1061 creature->AttackStop();
1062 creature->CastStop();
1063 creature->DoNotReacquireSpellFocusTarget();
1075 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveSeekAssistanceDistract: '{}', is distracted after assistance call (Time: {})",
_owner->
GetGUID().
ToString(), time);
1092 ASSERT(!hasExisting,
"Duplicate flight path movement generator");
1099 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::MoveTaxiFlight: '{}', attempted taxi to non-existing path Id: {} (node: {})",
_owner->
GetGUID().
ToString(), path, pathnode);
1102 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::MoveTaxiFlight: '{}', attempted taxi to path Id: {} (node: {})",
_owner->
GetGUID().
ToString(), path, pathnode);
1111 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveDistract: '{}', distracted (timer: {}, orientation: {})",
_owner->
GetGUID().
ToString(), timer, orientation);
1122 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MovePath: '{}', starts moving over path Id: {} (repeatable: {})",
1125 wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, generatePath),
MOTION_SLOT_DEFAULT);
1132 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MovePath: '{}', starts moving over path Id: {} (repeatable: {})",
1135 wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, generatePath),
MOTION_SLOT_DEFAULT);
1141 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveRotate: '{}', starts rotate (time: {}ms, turnSpeed: {}, totalTurnAngle: {}, direction: {})",
1160 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::LaunchMoveSpline: '{}', tried to launch a spline with an invalid MovementGeneratorType: {} (Id: {}, Priority: {})",
_owner->
GetGUID().
ToString(), type,
id, priority);
1164 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::LaunchMoveSpline: '{}', initiates spline Id: {} (Type: {}, Priority: {})",
_owner->
GetGUID().
ToString(),
id, type, priority);
1175 baseSpeed *= creature->GetCreatureTemplate()->speed_run;
1177 speedXY = std::min(baseSpeed * 3.0f * speedMultiplier, std::max(28.0f,
_owner->
GetSpeed(moveType) * 4.0f));
1179 float duration = dist / speedXY;
1180 float durationSqr = duration * duration;
1207 Delete(pointer, active, movementInform);
1257 Delete(movement, movement == top,
false);
1311 if (movement->
Priority == (*itr)->Priority)
1312 Remove(itr,
true,
false);
1314 (*itr)->Deactivate(
_owner);
1320 return a->Priority == movement->Priority;
1324 Remove(itr,
false,
false);
1340 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::Delete: deleting generator (Priority: {}, Flags: {}, BaseUnitState: {}, Type: {}), owner: '{}'",
1350 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::DeleteDefault: deleting generator (Priority: {}, Flags: {}, BaseUnitState: {}, Type: {}), owner: '{}'",
1381 unitState |= itr->first;
TaxiPathNodesByPath sTaxiPathNodesByPath
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
#define MAX_FALL_DISTANCE
#define TC_LOG_DEBUG(filterType__,...)
#define TC_LOG_ERROR(filterType__,...)
void MovementGeneratorPointerDeleter(MovementGenerator *a)
MovementGenerator * GetIdleMovementGenerator()
bool IsStatic(MovementGenerator *movement)
@ MOTIONMASTER_DELAYED_ADD
@ MOTIONMASTER_DELAYED_REMOVE
@ MOTIONMASTER_DELAYED_REMOVE_TYPE
@ MOTIONMASTER_DELAYED_INITIALIZE
@ MOTIONMASTER_DELAYED_CLEAR_PRIORITY
@ MOTIONMASTER_DELAYED_CLEAR
@ MOTIONMASTER_DELAYED_CLEAR_SLOT
@ MOTIONMASTER_DELAYED_CLEAR_MODE
@ MOTIONMASTER_FLAG_DELAYED
@ MOTIONMASTER_FLAG_INITIALIZING
@ MOTIONMASTER_FLAG_UPDATE
@ MOTIONMASTER_FLAG_INITIALIZATION_PENDING
@ MOTIONMASTER_FLAG_STATIC_INITIALIZATION_PENDING
bool IsInvalidMovementSlot(uint8 const slot)
MovementGeneratorPriority
@ MOTION_PRIORITY_HIGHEST
MovementWalkRunSpeedSelectionMode
bool IsInvalidMovementGeneratorType(uint8 const type)
@ MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING
@ MOVEMENTGENERATOR_FLAG_DEACTIVATED
@ MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH
#define sMovementGeneratorRegistry
std::optional< T > Optional
Optional helper class to wrap optional values within.
float baseMoveSpeed[MAX_MOVE_TYPE]
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
void LoadPath(Player *owner, uint32 startNode=0)
bool HasMovementGenerator(std::function< bool(MovementGenerator const *)> const &filter, MovementSlot slot=MOTION_SLOT_ACTIVE) const
void ClearBaseUnitStates()
void DeleteDefault(bool active, bool movementInform)
void MoveTaxiFlight(uint32 path, uint32 pathnode)
void LaunchMoveSpline(std::function< void(Movement::MoveSplineInit &init)> &&initializer, uint32 id=0, MovementGeneratorPriority priority=MOTION_PRIORITY_NORMAL, MovementGeneratorType type=EFFECT_MOTION_TYPE)
bool HasFlag(uint8 const flag) const
void MoveJumpWithGravity(Position const &pos, float speedXY, float gravity, uint32 id=EVENT_JUMP, bool hasOrientation=false, JumpArrivalCastArgs const *arrivalCast=nullptr, Movement::SpellEffectExtraData const *spellEffectExtraData=nullptr)
void MoveRotate(uint32 id, RotateDirection direction, Optional< Milliseconds > time={}, Optional< float > turnSpeed={}, Optional< float > totalTurnAngle={})
Makes the Unit turn in place.
void ClearBaseUnitState(MovementGenerator const *movement)
void ResolveDelayedActions()
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=EVENT_JUMP, bool hasOrientation=false, JumpArrivalCastArgs const *arrivalCast=nullptr, Movement::SpellEffectExtraData const *spellEffectExtraData=nullptr)
void MovePath(uint32 pathId, bool repeatable, Optional< Milliseconds > duration={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< std::pair< Milliseconds, Milliseconds > > waitTimeRangeAtPathEnd={}, Optional< float > wanderDistanceAtPathEnds={}, Optional< bool > followPathBackwardsFromEndToStart={}, bool generatePath=true)
MovementGeneratorType GetCurrentMovementGeneratorType() const
void MoveFleeing(Unit *enemy, Milliseconds time=0ms)
std::vector< MovementGeneratorInformation > GetMovementGeneratorsInformation() const
void CalculateJumpSpeeds(float dist, UnitMoveType moveType, float speedMultiplier, float minHeight, float maxHeight, float &speedXY, float &speedZ) const
void Pop(bool active, bool movementInform)
void PropagateSpeedChange()
void MoveSmoothPath(uint32 pointId, Position const *pathPoints, size_t pathSize, bool walk=false, bool fly=false)
void Delete(MovementGenerator *movement, bool active, bool movementInform)
void MoveChase(Unit *target, Optional< ChaseRange > dist={}, Optional< ChaseAngle > angle={})
void MoveFormation(Unit *leader, float range, float angle, uint32 point1, uint32 point2)
void MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk)
void DirectAdd(MovementGenerator *movement, MovementSlot slot)
std::unique_ptr< MovementGenerator, MovementGeneratorDeleter > MovementGeneratorPointer
void AddFlag(uint8 const flag)
void MoveTakeoff(uint32 id, Position const &pos, Optional< int32 > tierTransitionId={}, Optional< float > velocity={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default)
void MoveSeekAssistance(float x, float y, float z)
void MoveRandom(float wanderDistance=0.0f, Optional< Milliseconds > duration={}, MovementSlot slot=MOTION_SLOT_DEFAULT)
void MoveKnockbackFrom(Position const &origin, float speedXY, float speedZ, Movement::SpellEffectExtraData const *spellEffectExtraData=nullptr)
void MoveSeekAssistanceDistract(uint32 timer)
void DirectClearDefault()
MotionMasterUnitStatesContainer _baseUnitStatesMap
void ResumeSplineChain(SplineChainResumeInfo const &info)
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={})
void RemoveFlag(uint8 const flag)
void MoveLand(uint32 id, Position const &pos, Optional< int32 > tierTransitionId={}, Optional< float > velocity={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default)
void Add(MovementGenerator *movement, MovementSlot slot=MOTION_SLOT_ACTIVE)
bool GetDestination(float &x, float &y, float &z)
std::function< void()> DelayedActionDefine
void MoveFollow(Unit *target, float dist, ChaseAngle angle, Optional< Milliseconds > duration={}, MovementSlot slot=MOTION_SLOT_ACTIVE)
MovementGenerator * GetCurrentMovementGenerator() const
std::deque< DelayedAction > _delayedActions
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, bool generatePath=false, Unit const *target=nullptr, Movement::SpellEffectExtraData const *spellEffectExtraData=nullptr)
MovementSlot GetCurrentSlot() const
MovementGeneratorPointer _defaultGenerator
void MoveCloserAndStop(uint32 id, Unit *target, float distance)
void MoveJumpTo(float angle, float speedXY, float speedZ)
void MoveFall(uint32 id=0)
void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount, Optional< Milliseconds > duration={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default)
void MoveDistract(uint32 time, float orientation)
MovementGenerator * GetMovementGenerator(std::function< bool(MovementGenerator const *)> const &filter, MovementSlot slot=MOTION_SLOT_ACTIVE) const
void Remove(MovementGenerator *movement, MovementSlot slot=MOTION_SLOT_ACTIVE)
MotionMasterContainer _generators
void AddBaseUnitState(MovementGenerator const *movement)
virtual void Initialize(Unit *owner)=0
virtual bool Update(Unit *owner, uint32 diff)=0
void AddFlag(uint16 const flag)
virtual void Finalize(Unit *owner, bool active, bool movementInform)=0
bool HasFlag(uint16 const flag) const
virtual void Reset(Unit *owner)=0
virtual void UnitSpeedChanged()
virtual MovementGeneratorType GetMovementGeneratorType() const =0
void MoveTo(Vector3 const &destination, bool generatePath=true, bool forceDestination=false)
void SetParabolic(float amplitude, float start_time)
void SetVelocity(float velocity)
void SetFacing(float angle)
void SetSpellEffectExtraData(SpellEffectExtraData const &spellEffectExtraData)
void MovebyPath(PointsArray const &path, int32 pointId=0)
void SetParabolicVerticalAcceleration(float vertical_acceleration, float time_shift)
void SetOrientationFixed(bool enable)
static ObjectGuid const Empty
std::string ToString() const
static Creature * ToCreature(Object *o)
static ObjectGuid GetGUID(Object const *o)
static Player * ToPlayer(Object *o)
Movement::PointsArray const & GetPath() const
G3D::Vector3 const & GetActualEndPosition() const
void SetFallInformation(uint32 time, float z)
void ClearUnitState(uint32 f)
float GetSpeed(UnitMoveType mtype) const
bool SetFall(bool enable)
void AddUnitState(uint32 f)
Unit * GetCharmerOrOwner() const
float GetHoverOffset() const
bool HasUnitState(const uint32 f) const
std::unique_ptr< Movement::MoveSpline > movespline
bool IsControlledByPlayer() const
ObjectGuid GetTarget() const
void UpdateAllowedPositionZ(float x, float y, float &z, float *groundZ=nullptr) const
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
void GetNearPoint2D(WorldObject const *searcher, float &x, float &y, float distance, float absAngle) const
MovementGenerator * SelectMovementGenerator(Unit *unit)
std::vector< Vector3 > PointsArray
float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity=0.0f)
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
void MultimapErasePair(M< K, V, Rest... > &multimap, K const &key, V const &value)
bool operator()(MovementGenerator const *a, MovementGenerator const *b) const
void operator()(MovementGenerator *a)
constexpr float GetPositionX() const
constexpr float GetPositionY() const
float GetExactDist2d(const float x, const float y) const
float GetRelativeAngle(float x, float y) const
std::string ToString() const
float GetAbsoluteAngle(float x, float y) const
constexpr void GetPosition(float &x, float &y) const
constexpr float GetOrientation() const
constexpr float GetPositionZ() const