25#include "G3DPosition.hpp"
139 std::vector<MovementGeneratorInformation> list;
155 list.emplace_back(type, target->GetGUID(), target->GetName());
211 return (*
_generators.begin())->GetMovementGeneratorType();
247 auto itr = std::ranges::find_if(
_generators, std::ref(filter));
271 value = std::ranges::any_of(
_generators, std::ref(filter));
292 enum class InitState :
uint8
297 } initializationState = InitState::AlreadyInitialized;
303 initializationState = top->
Initialize(
_owner) ? InitState::Success : InitState::Failed;
306 initializationState = top->
Initialize(
_owner) ? InitState::Success : InitState::Failed;
308 initializationState = top->
Reset(
_owner) ? InitState::Success : InitState::Failed;
312 if (initializationState == InitState::Failed || !top->
Update(
_owner, initializationState == InitState::AlreadyInitialized ? diff : 0))
585 if (!target || target ==
_owner)
595 if (!target || target ==
_owner)
655 if (distanceToTravel > 0.0f)
668 init.SetFacing(target);
680 init.MoveTo(PositionToVector3(pos),
false);
683 init.SetVelocity(*velocity);
694 init.MoveTo(PositionToVector3(pos),
false);
697 init.SetVelocity(*velocity);
750 float dist = 2 * moveTimeHalf * speedXY;
759 init.SetParabolic(max_height, 0);
760 init.SetOrientationFixed(
true);
761 init.SetVelocity(speedXY);
779 float dist = 2 * moveTimeHalf * speedXY;
784 MoveJump(x, y, z, 0.0f, speedXY, speedZ);
803 init.MoveTo(x, y, z,
false);
804 init.SetParabolic(max_height, 0);
805 init.SetVelocity(speedXY);
821 float step = 2 * float(
M_PI) / stepCount * (clockwise ? -1.0f : 1.0f);
822 Position const& pos = { x, y, z, 0.0f };
828 for (
uint8 i = 0; i < stepCount; angle += step, ++i)
831 point.x = x + radius * cosf(angle);
832 point.y = y + radius * sinf(angle);
839 init.Path().push_back(point);
862 std::transform(pathPoints, pathPoints +
pathSize, std::back_inserter(path), [](
Position const& point)
869 init.MovebyPath(path);
888 std::vector<SplineChainLink>
const* chain =
sScriptSystemMgr->GetSplineChain(owner, dbChainId);
891 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::MoveAlongSplineChain: '{}', tried to walk along non-existing spline chain with DB Id: {}.",
_owner->
GetGUID().
ToString(), dbChainId);
918 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveFall: '{}', unable to retrieve a proper height at map Id: {} (X: {}, Y: {}, Z: {})",
955 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveSeekAssistance: '{}', seeks assistance (X: {}, Y: {}, Z: {})", creature->GetGUID().ToString(), x, y, z);
956 creature->AttackStop();
957 creature->CastStop();
958 creature->DoNotReacquireSpellFocusTarget();
970 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveSeekAssistanceDistract: '{}', is distracted after assistance call (Time: {})",
_owner->
GetGUID().
ToString(), time);
987 ASSERT(!hasExisting,
"Duplicate flight path movement generator");
994 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::MoveTaxiFlight: '{}', attempted taxi to non-existing path Id: {} (node: {})",
_owner->
GetGUID().
ToString(), path, pathnode);
997 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::MoveTaxiFlight: '{}', attempted taxi to path Id: {} (node: {})",
_owner->
GetGUID().
ToString(), path, pathnode);
1006 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveDistract: '{}', distracted (timer: {}, orientation: {})",
_owner->
GetGUID().
ToString(), timer, orientation);
1015 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MovePath: '{}', starts moving over path Id: {} (repeatable: {})",
_owner->
GetGUID().
ToString(), pathId, repeatable ?
"YES" :
"NO");
1021 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MovePath: '{}', starts moving over path Id: {} (repeatable: {})",
_owner->
GetGUID().
ToString(), path.
id, repeatable ?
"YES" :
"NO");
1030 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveRotate: '{}', starts rotate (time: {}, direction: {})",
_owner->
GetGUID().
ToString(), time, direction);
1049 init.MoveTo(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(),
false);
1050 if (owner->GetTransport())
1051 init.DisableTransportPathTransformations();
1052 init.SetFacing(orientation);
1067 init.MoveTo(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(),
false);
1068 init.SetFacing(owner->GetAbsoluteAngle(
object));
1078 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::LaunchMoveSpline: '{}', tried to launch a spline with an invalid MovementGeneratorType: {} (Id: {}, Priority: {})",
_owner->
GetGUID().
ToString(), type,
id, priority);
1082 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::LaunchMoveSpline: '{}', initiates spline Id: {} (Type: {}, Priority: {})",
_owner->
GetGUID().
ToString(),
id, type, priority);
1104 Delete(pointer, active, movementInform);
1111 Remove(itr, active, movementInform);
1149 Remove(itr, *itr == top,
false);
1175 if (replacesExisting)
1176 Remove(where, where == top,
false);
1177 else if (where == top)
1178 (*top)->Deactivate(
_owner);
1202 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::Delete: deleting generator (Priority: {}, Flags: {}, BaseUnitState: {}, Type: {}), owner: '{}'",
1212 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::DeleteDefault: deleting generator (Priority: {}, Flags: {}, BaseUnitState: {}, Type: {}), owner: '{}'",
1243 unitState |= itr->first;
TaxiPathNodesByPath sTaxiPathNodesByPath
#define TC_LOG_DEBUG(filterType__,...)
#define TC_LOG_ERROR(filterType__,...)
#define MAX_FALL_DISTANCE
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_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
bool IsInvalidMovementGeneratorType(uint8 const type)
@ MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING
@ MOVEMENTGENERATOR_FLAG_DEACTIVATED
@ MOVEMENTGENERATOR_FLAG_FINALIZED
@ MOVEMENTGENERATOR_FLAG_IMMEDIATE
@ MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH
#define sMovementGeneratorRegistry
std::optional< T > Optional
Optional helper class to wrap optional values within.
void LoadPath(Player *owner)
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 MoveSmoothPath(uint32 pointId, Position const *pathPoints, size_t pathSize, bool walk)
void ClearBaseUnitState(MovementGenerator const *movement)
void ResolveDelayedActions()
MovementGeneratorType GetCurrentMovementGeneratorType() const
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=EVENT_JUMP, bool hasOrientation=false)
std::vector< MovementGeneratorInformation > GetMovementGeneratorsInformation() const
void Pop(bool active, bool movementInform)
void PropagateSpeedChange()
void Delete(MovementGenerator *movement, bool active, bool movementInform)
void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ)
void MoveChase(Unit *target, Optional< ChaseRange > dist={}, Optional< ChaseAngle > angle={})
void MoveFormation(Unit *leader, float range, float angle, uint32 point1, uint32 point2)
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={})
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, bool generatePath=false)
void InterruptOnTeleport()
void MoveTakeoff(uint32 id, Position const &pos, Optional< float > velocity={})
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 MoveSeekAssistance(float x, float y, float z)
void MoveSeekAssistanceDistract(uint32 timer)
void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount)
void MovePath(uint32 pathId, bool repeatable)
void DirectClearDefault()
MotionMasterUnitStatesContainer _baseUnitStatesMap
void ResumeSplineChain(SplineChainResumeInfo const &info)
void RemoveFlag(uint8 const flag)
void Add(MovementGenerator *movement, MovementSlot slot=MOTION_SLOT_ACTIVE)
bool GetDestination(float &x, float &y, float &z)
std::function< void()> DelayedActionDefine
MovementGenerator * GetCurrentMovementGenerator() const
std::deque< DelayedAction > _delayedActions
void MoveFollow(Unit *target, float dist, ChaseAngle angle, MovementSlot slot=MOTION_SLOT_ACTIVE)
MovementSlot GetCurrentSlot() const
MovementGeneratorPointer _defaultGenerator
void MoveCloserAndStop(uint32 id, Unit *target, float distance)
void MoveRotate(uint32 id, uint32 time, RotateDirection direction)
void MoveJumpTo(float angle, float speedXY, float speedZ)
void MoveFall(uint32 id=0)
void MoveDistract(uint32 time, float orientation)
void MoveLand(uint32 id, Position const &pos, Optional< float > velocity={})
MovementGenerator * GetMovementGenerator(std::function< bool(MovementGenerator const *)> const &filter, MovementSlot slot=MOTION_SLOT_ACTIVE) const
void Remove(MovementGenerator *movement, MovementSlot slot=MOTION_SLOT_ACTIVE)
void MoveFace(float orientation, uint32 id=EVENT_FACE)
MotionMasterContainer _generators
void AddBaseUnitState(MovementGenerator const *movement)
void MoveFleeing(Unit *enemy, uint32 time=0)
void MoveRandom(float wanderDistance=0.0f)
void AddFlag(uint16 const flag)
virtual bool Update(Unit *, uint32 diff)=0
bool HasFlag(uint16 const flag) const
virtual void UnitSpeedChanged()
virtual bool Initialize(Unit *)=0
virtual bool Reset(Unit *)=0
virtual MovementGeneratorType GetMovementGeneratorType() const =0
virtual void Finalize(Unit *, bool, bool)=0
void SetVelocity(float velocity)
void MovebyPath(PointsArray const &path, int32 pointId=0)
Vector3 FinalDestination() const
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)
Movement::MoveSpline * movespline
bool SetFall(bool enable)
void StopMoving(bool force=false)
void AddUnitState(uint32 f)
Unit * GetCharmerOrOwner() const
float GetHoverOffset() const
bool HasUnitState(const uint32 f) 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)
TC_GAME_API float gravity
std::vector< Vector3 > PointsArray
float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity=0.0f)
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)
float GetExactDist2d(const float x, const float y) const
float GetRelativeAngle(float x, float y) const
float GetPositionZ() const
float GetOrientation() const
float GetAbsoluteAngle(float x, float y) const
float GetPositionX() const
void GetPosition(float &x, float &y) const
float GetPositionY() const