23#include "G3DPosition.hpp"
141 std::vector<MovementGeneratorInformation> list;
157 list.emplace_back(type, target->GetGUID(), target->GetName());
213 return (*
_generators.begin())->GetMovementGeneratorType();
377 auto itr = std::find(bounds.first, bounds.second, movement);
416 return a->GetMovementGeneratorType() == type;
492 return a->Mode == mode;
514 return a->Priority == priority;
575 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::MoveTargetedHome: '{}', attempted to move towards target home.",
_owner->
GetGUID());
599 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveRandom: '{}', started random movement (spawnDist: {})",
_owner->
GetGUID(), wanderDistance);
602 else if (scriptResult)
610 if (!target || target ==
_owner)
624 if (!target || target ==
_owner)
635 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveConfused: '{}', started confused movement.",
_owner->
GetGUID());
640 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveConfused: '{}', started confused movement.",
_owner->
GetGUID());
673 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MovePoint: '{}', targeted point Id: {} (X: {}, Y: {}, Z: {})",
_owner->
GetGUID(),
id, x, y, z);
674 Add(
new PointMovementGenerator(
id, x, y, z, generatePath, speed, finalOrient,
nullptr,
nullptr, speedSelectionMode, closeEnoughDistance, std::move(scriptResult)));
680 if (distanceToTravel > 0.0f)
694 init.SetFacing(refreshedTarget);
708 init.MoveTo(PositionToVector3(pos),
false);
712 switch (speedSelectionMode)
725 init.SetVelocity(*velocity);
738 init.MoveTo(PositionToVector3(pos),
false);
739 init.SetAnimation(
AnimTier::Fly, tierTransitionId.value_or(2));
741 switch (speedSelectionMode)
754 init.SetVelocity(*velocity);
766 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveCharge: '{}', charging point Id: {} (X: {}, Y: {}, Z: {})",
_owner->
GetGUID(),
id, x, y, z);
788 if (spellEffectExtraData)
804 float dist = 2 * moveTimeHalf * speedXY;
835 float dist = 2 * moveTimeHalf * speedXY;
848 spellEffectExtraData, std::move(scriptResult));
855 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveJump: '{}', jumps to point Id: {} (X: {}, Y: {}, Z: {})",
_owner->
GetGUID(),
id, x, y, z);
868 init.
MoveTo(x, y, z,
false);
877 uint32 arrivalSpellId = 0;
881 arrivalSpellId = arrivalCast->
SpellId;
882 arrivalSpellTargetGuid = arrivalCast->
Target;
886 { .ArrivalSpellId = arrivalSpellId, .ArrivalSpellTarget = arrivalSpellTargetGuid, .ScriptResult = std::move(scriptResult) });
917 uint32 arrivalSpellId = 0;
921 arrivalSpellId = arrivalCast->
SpellId;
922 arrivalSpellTargetGuid = arrivalCast->
Target;
926 { .ArrivalSpellId = arrivalSpellId, .ArrivalSpellTarget = arrivalSpellTargetGuid, .ScriptResult = std::move(scriptResult) });
940 float step = 2 * float(
M_PI) / stepCount * (clockwise ? -1.0f : 1.0f);
941 Position const& pos = { x, y, z, 0.0f };
947 for (
uint8 i = 0; i < stepCount; angle += step, ++i)
949 G3D::Vector3& point = init.Path().emplace_back();
950 point.x = x + radius * cosf(angle);
951 point.y = y + radius * sinf(angle);
968 switch (speedSelectionMode)
981 init.SetVelocity(*speed);
992 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::MoveAlongSplineChain: '{}', tried to walk along DB spline chain. Ignoring.",
_owner->
GetGUID());
995 std::vector<SplineChainLink>
const* chain =
sScriptSystemMgr->GetSplineChain(owner, dbChainId);
998 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::MoveAlongSplineChain: '{}', tried to walk along non-existing spline chain with DB Id: {}.",
_owner->
GetGUID(), dbChainId);
1013 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::ResumeSplineChain: '{}', tried to resume a spline chain from empty info.",
_owner->
GetGUID());
1024 if (opt->has_value())
1032 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveFall: '{}', unable to retrieve a proper height at map Id: {} (X: {}, Y: {}, Z: {})",
1069 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveSeekAssistance: '{}', seeks assistance (X: {}, Y: {}, Z: {})", creature->GetGUID(), x, y, z);
1070 creature->AttackStop();
1071 creature->CastStop();
1072 creature->DoNotReacquireSpellFocusTarget();
1077 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::MoveSeekAssistance: '{}', attempted to seek assistance.",
_owner->
GetGUID());
1084 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveSeekAssistanceDistract: '{}', is distracted after assistance call (Time: {})",
_owner->
GetGUID(), time);
1088 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::MoveSeekAssistanceDistract: '{}', attempted to call distract assistance.",
_owner->
GetGUID());
1098 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveTaxiFlight: '{}', taxi to path Id: {} (node {})",
_owner->
GetGUID(), path, pathnode);
1102 ASSERT(!hasExisting,
"Duplicate flight path movement generator");
1109 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::MoveTaxiFlight: '{}', attempted taxi to non-existing path Id: {} (node: {})",
_owner->
GetGUID(), path, pathnode);
1112 TC_LOG_ERROR(
"movement.motionmaster",
"MotionMaster::MoveTaxiFlight: '{}', attempted taxi to path Id: {} (node: {})",
_owner->
GetGUID(), path, pathnode);
1121 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveDistract: '{}', distracted (timer: {}, orientation: {})",
_owner->
GetGUID(), timer, orientation);
1127 Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd ,
1139 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MovePath: '{}', starts moving over path Id: {} (repeatable: {})",
1142 wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, exactSplinePath, generatePath, std::move(scriptResult)),
MOTION_SLOT_DEFAULT);
1147 Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd ,
1152 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MovePath: '{}', starts moving over path Id: {} (repeatable: {})",
1155 wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, exactSplinePath, generatePath, std::move(scriptResult)),
MOTION_SLOT_DEFAULT);
1162 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveRotate: '{}', starts rotate (time: {}ms, turnSpeed: {}, totalTurnAngle: {}, direction: {})",
1163 _owner->
GetGUID(), time.value_or(0ms).count(), turnSpeed, totalTurnAngle, direction);
1172 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::MoveFormation: '{}', started to move in a formation with leader {}",
_owner->
GetGUID(), leader->
GetGUID());
1181 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::LaunchMoveSpline: '{}', tried to launch a spline with an invalid MovementGeneratorType: {} (Id: {}, Priority: {})",
_owner->
GetGUID(), type,
id, priority);
1185 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::LaunchMoveSpline: '{}', initiates spline Id: {} (Type: {}, Priority: {})",
_owner->
GetGUID(),
id, type, priority);
1196 baseSpeed *= creature->GetCreatureTemplate()->speed_run;
1198 speedXY = std::min(baseSpeed * 3.0f * speedMultiplier, std::max(28.0f,
_owner->
GetSpeed(moveType) * 4.0f));
1200 float duration = dist / speedXY;
1201 float durationSqr = duration * duration;
1228 Delete(pointer, active, movementInform);
1278 Delete(movement, movement == top,
false);
1332 if (movement->
Priority == (*itr)->Priority)
1333 Remove(itr,
true,
false);
1335 (*itr)->Deactivate(
_owner);
1341 return a->Priority == movement->Priority;
1345 Remove(itr,
false,
false);
1361 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::Delete: deleting generator (Priority: {}, Flags: {}, BaseUnitState: {}, Type: {}), owner: '{}'",
1371 TC_LOG_DEBUG(
"movement.motionmaster",
"MotionMaster::DeleteDefault: deleting generator (Priority: {}, Flags: {}, BaseUnitState: {}, Type: {}), owner: '{}'",
1402 unitState |= itr->first;
TaxiPathNodesByPath sTaxiPathNodesByPath
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
#define MAX_FALL_DISTANCE
#define TC_LOG_DEBUG(filterType__, message__,...)
#define TC_LOG_ERROR(filterType__, message__,...)
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
std::variant< std::monostate, Position, Unit const *, float > MovementFacingTarget
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 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 ClearBaseUnitState(MovementGenerator const *movement)
void ResolveDelayedActions()
MovementGeneratorType GetCurrentMovementGeneratorType() const
void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount, Optional< Milliseconds > duration={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
void MoveTakeoff(uint32 id, Position const &pos, Optional< int32 > tierTransitionId={}, Optional< float > velocity={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
std::vector< MovementGeneratorInformation > GetMovementGeneratorsInformation() const
void MoveFleeing(Unit *enemy, Milliseconds time=0ms, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
void MoveFall(uint32 id=0, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
void CalculateJumpSpeeds(float dist, UnitMoveType moveType, float speedMultiplier, float minHeight, float maxHeight, float &speedXY, float &speedZ) const
void Pop(bool active, bool movementInform)
void MoveLand(uint32 id, Position const &pos, Optional< int32 > tierTransitionId={}, Optional< float > velocity={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
void PropagateSpeedChange()
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 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={}, Optional< bool > exactSplinePath={}, bool generatePath=true, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
void MoveTaxiFlight(uint32 path, uint32 pathnode, Optional< float > speed={}, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
void MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk)
void DirectAdd(MovementGenerator *movement, MovementSlot slot)
void MoveJumpWithGravity(Position const &pos, float speedXY, float gravity, uint32 id=EVENT_JUMP, MovementFacingTarget const &facing={}, bool orientationFixed=false, JumpArrivalCastArgs const *arrivalCast=nullptr, Movement::SpellEffectExtraData const *spellEffectExtraData=nullptr, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
std::unique_ptr< MovementGenerator, MovementGeneratorDeleter > MovementGeneratorPointer
void AddFlag(uint8 const flag)
void MoveSeekAssistance(float x, float y, float z)
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 RemoveFlag(uint8 const flag)
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={}, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
void Add(MovementGenerator *movement, MovementSlot slot=MOTION_SLOT_ACTIVE)
bool GetDestination(float &x, float &y, float &z)
void MoveFollow(Unit *target, float dist, Optional< ChaseAngle > angle={}, Optional< Milliseconds > duration={}, bool ignoreTargetWalk=false, MovementSlot slot=MOTION_SLOT_ACTIVE, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
std::function< void()> DelayedActionDefine
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 MoveRandom(float wanderDistance=0.0f, Optional< Milliseconds > duration={}, MovementSlot slot=MOTION_SLOT_DEFAULT, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
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 MoveRotate(uint32 id, RotateDirection direction, Optional< Milliseconds > time={}, Optional< float > turnSpeed={}, Optional< float > totalTurnAngle={}, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
Makes the Unit turn in place.
void AddBaseUnitState(MovementGenerator const *movement)
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=EVENT_JUMP, MovementFacingTarget const &facing={}, bool orientationFixed=false, JumpArrivalCastArgs const *arrivalCast=nullptr, Movement::SpellEffectExtraData const *spellEffectExtraData=nullptr, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
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 SetJumpOrientationFixed(bool enable)
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
constexpr uint32 GetMapId() 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 GetNearPoint2D(WorldObject const *searcher, float &x, float &y, float distance, float absAngle) const
void MovePositionToFirstCollision(Position &pos, float dist, float angle) const
MovementGenerator * SelectMovementGenerator(Unit *unit)
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 &multimap, typename M::key_type const &key, typename M::mapped_type const &value)
std::unique_ptr< T, Impl::stateful_unique_ptr_deleter< Ptr, Del > > make_unique_ptr_with_deleter(Ptr ptr, Del deleter)
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