Core/Movement: Move facing splines into MotionMaster

(cherry picked from commit fa4d4550b30dfdf70296a9958263f290b860d450)
This commit is contained in:
ccrs
2026-06-30 13:59:56 +02:00
committed by Shauren
parent 7350b76756
commit edf486ad16
6 changed files with 45 additions and 24 deletions
+4 -21
View File
@@ -13307,39 +13307,22 @@ void Unit::SetInFront(WorldObject const* target)
SetOrientation(GetAbsoluteAngle(target));
}
void Unit::SetFacingTo(float ori, bool force)
void Unit::SetFacingTo(float ori, bool force /*= true*/, uint32 movementId /*= EVENT_FACE*/)
{
// do not face when already moving
if (!force && (!IsStopped() || !movespline->Finalized()))
return;
Movement::MoveSplineInit init(this);
init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZ(), false);
if (GetTransport())
init.DisableTransportPathTransformations(); // It makes no sense to target global orientation
init.SetFacing(ori);
//GetMotionMaster()->LaunchMoveSpline(std::move(init), EVENT_FACE, MOTION_PRIORITY_HIGHEST);
UpdateSplineMovement(init.Launch());
if (Creature* creature = ToCreature())
creature->AI()->MovementInform(EFFECT_MOTION_TYPE, EVENT_FACE);
GetMotionMaster()->MoveFace(ori, movementId);
}
void Unit::SetFacingToObject(WorldObject const* object, bool force)
void Unit::SetFacingToObject(WorldObject const* object, bool force /*= true*/, uint32 movementId /*= EVENT_FACE*/)
{
// do not face when already moving
if (!force && (!IsStopped() || !movespline->Finalized()))
return;
/// @todo figure out under what conditions creature will move towards object instead of facing it where it currently is.
Movement::MoveSplineInit init(this);
init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZ(), false);
init.SetFacing(GetAbsoluteAngle(object)); // when on transport, GetAbsoluteAngle will still return global coordinates (and angle) that needs transforming
//GetMotionMaster()->LaunchMoveSpline(std::move(init), EVENT_FACE, MOTION_PRIORITY_HIGHEST);
UpdateSplineMovement(init.Launch());
if (Creature* creature = ToCreature())
creature->AI()->MovementInform(EFFECT_MOTION_TYPE, EVENT_FACE);
GetMotionMaster()->MoveFace(object, movementId);
}
void Unit::SetFacingToPoint(Position const& point, bool force)
+2 -2
View File
@@ -1177,8 +1177,8 @@ class TC_GAME_API Unit : public WorldObject
void UpdateMovementForcesModMagnitude();
void SetInFront(WorldObject const* target);
void SetFacingTo(float const ori, bool force = true);
void SetFacingToObject(WorldObject const* object, bool force = true);
void SetFacingTo(float ori, bool force = true, uint32 movementId = EVENT_FACE);
void SetFacingToObject(WorldObject const* object, bool force = true, uint32 movementId = EVENT_FACE);
void SetFacingToPoint(Position const& point, bool force = true);
bool IsAlive() const { return (m_deathState == ALIVE); }
+31
View File
@@ -1159,6 +1159,37 @@ void MotionMaster::MoveFormation(Unit* leader, float range, float angle, uint32
}
}
void MotionMaster::MoveFace(float orientation, uint32 id /*= EVENT_FACE*/)
{
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveFace: '{}', faces '{}'", _owner->GetGUID(), orientation);
std::function<void(Movement::MoveSplineInit&)> initializer = [owner = _owner, orientation](Movement::MoveSplineInit& init)
{
init.MoveTo(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), false);
if (owner->GetTransport())
init.DisableTransportPathTransformations(); // It makes no sense to target global orientation
init.SetFacing(orientation);
};
Add(new ImmediateMovementGenerator(std::move(initializer), FACE_MOTION_TYPE, id));
}
void MotionMaster::MoveFace(WorldObject const* object, uint32 id /*= EVENT_FACE*/)
{
if (!object)
return;
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveFace: '{}', faces '{}'", _owner->GetGUID(), object->GetGUID());
std::function<void(Movement::MoveSplineInit&)> initializer = [owner = _owner, object](Movement::MoveSplineInit& init)
{
init.MoveTo(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), false);
init.SetFacing(owner->GetAbsoluteAngle(object)); // when on transport, GetAbsoluteAngle will still return global coordinates (and angle) that needs transforming
};
Add(new ImmediateMovementGenerator(std::move(initializer), FACE_MOTION_TYPE, id));
}
void MotionMaster::LaunchMoveSpline(std::function<void(Movement::MoveSplineInit& init)>&& initializer, uint32 id/*= 0*/, MovementGeneratorPriority priority/* = MOTION_PRIORITY_NORMAL*/, MovementGeneratorType type/*= EFFECT_MOTION_TYPE*/, Scripting::v2::ActionResultSetter<MovementStopReason>&& scriptResult /*= {}*/)
{
if (IsInvalidMovementGeneratorType(type))
+3
View File
@@ -33,6 +33,7 @@
class PathGenerator;
class Unit;
class WorldObject;
struct Position;
struct SplineChainLink;
struct SplineChainResumeInfo;
@@ -237,6 +238,8 @@ class TC_GAME_API MotionMaster
Optional<float> turnSpeed = {}, Optional<float> totalTurnAngle = {},
Scripting::v2::ActionResultSetter<MovementStopReason>&& scriptResult = {});
void MoveFormation(Unit* leader, float range, float angle, uint32 point1, uint32 point2);
void MoveFace(float orientation, uint32 id = EVENT_FACE);
void MoveFace(WorldObject const* object, uint32 id = EVENT_FACE);
void LaunchMoveSpline(std::function<void(Movement::MoveSplineInit& init)>&& initializer, uint32 id = 0, MovementGeneratorPriority priority = MOTION_PRIORITY_NORMAL, MovementGeneratorType type = EFFECT_MOTION_TYPE, Scripting::v2::ActionResultSetter<MovementStopReason>&& scriptResult = {});
@@ -51,6 +51,7 @@ enum MovementGeneratorType : uint8
EFFECT_MOTION_TYPE = 16,
SPLINE_CHAIN_MOTION_TYPE = 17, // SplineChainMovementGenerator.h
FORMATION_MOTION_TYPE = 18, // FormationMovementGenerator.h
FACE_MOTION_TYPE = 19,
MAX_MOTION_TYPE // SKIP
};
@@ -50,12 +50,13 @@ TC_API_EXPORT EnumText EnumUtils<MovementGeneratorType>::ToString(MovementGenera
case EFFECT_MOTION_TYPE: return { "EFFECT_MOTION_TYPE", "EFFECT_MOTION_TYPE", "" };
case SPLINE_CHAIN_MOTION_TYPE: return { "SPLINE_CHAIN_MOTION_TYPE", "SPLINE_CHAIN_MOTION_TYPE", "SplineChainMovementGenerator.h" };
case FORMATION_MOTION_TYPE: return { "FORMATION_MOTION_TYPE", "FORMATION_MOTION_TYPE", "FormationMovementGenerator.h" };
case FACE_MOTION_TYPE: return { "FACE_MOTION_TYPE", "FACE_MOTION_TYPE", "" };
default: throw std::out_of_range("value");
}
}
template <>
TC_API_EXPORT size_t EnumUtils<MovementGeneratorType>::Count() { return 19; }
TC_API_EXPORT size_t EnumUtils<MovementGeneratorType>::Count() { return 20; }
template <>
TC_API_EXPORT MovementGeneratorType EnumUtils<MovementGeneratorType>::FromIndex(size_t index)
@@ -81,6 +82,7 @@ TC_API_EXPORT MovementGeneratorType EnumUtils<MovementGeneratorType>::FromIndex(
case 16: return EFFECT_MOTION_TYPE;
case 17: return SPLINE_CHAIN_MOTION_TYPE;
case 18: return FORMATION_MOTION_TYPE;
case 19: return FACE_MOTION_TYPE;
default: throw std::out_of_range("index");
}
}
@@ -109,6 +111,7 @@ TC_API_EXPORT size_t EnumUtils<MovementGeneratorType>::ToIndex(MovementGenerator
case EFFECT_MOTION_TYPE: return 16;
case SPLINE_CHAIN_MOTION_TYPE: return 17;
case FORMATION_MOTION_TYPE: return 18;
case FACE_MOTION_TYPE: return 19;
default: throw std::out_of_range("value");
}
}