fix(Core/Unit): rework Walk/Run mode (#22988)

Co-authored-by: sudlud <sudlud@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
killerwife
2025-10-14 22:54:19 +02:00
committed by GitHub
parent c28f635408
commit 10d5a3c553
104 changed files with 373 additions and 362 deletions

View File

@@ -387,6 +387,7 @@ void MotionMaster::MoveBackwards(Unit* target, float dist)
Movement::MoveSplineInit init(_owner);
init.MoveTo(point.x, point.y, point.z, false);
init.SetWalk(true);
init.SetFacing(target);
init.SetOrientationInversed();
init.Launch();
@@ -469,7 +470,7 @@ void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlo
*
* For transition movement between the ground and the air, use MoveLand or MoveTakeoff instead.
*/
void MotionMaster::MovePoint(uint32 id, float x, float y, float z, bool generatePath, bool forceDestination, MovementSlot slot, float orientation /* = 0.0f*/)
void MotionMaster::MovePoint(uint32 id, float x, float y, float z, ForcedMovement forcedMovement, float speed, float orientation, bool generatePath, bool forceDestination, MovementSlot slot)
{
if (_owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE))
return;
@@ -477,16 +478,16 @@ void MotionMaster::MovePoint(uint32 id, float x, float y, float z, bool generate
if (_owner->IsPlayer())
{
LOG_DEBUG("movement.motionmaster", "Player ({}) targeted point (Id: {} X: {} Y: {} Z: {})", _owner->GetGUID().ToString(), id, x, y, z);
Mutate(new PointMovementGenerator<Player>(id, x, y, z, 0.0f, orientation, nullptr, generatePath, forceDestination), slot);
Mutate(new PointMovementGenerator<Player>(id, x, y, z, forcedMovement, speed, orientation, nullptr, generatePath, forceDestination), slot);
}
else
{
LOG_DEBUG("movement.motionmaster", "Creature ({}) targeted point (ID: {} X: {} Y: {} Z: {})", _owner->GetGUID().ToString(), id, x, y, z);
Mutate(new PointMovementGenerator<Creature>(id, x, y, z, 0.0f, orientation, nullptr, generatePath, forceDestination), slot);
Mutate(new PointMovementGenerator<Creature>(id, x, y, z, forcedMovement, speed, orientation, nullptr, generatePath, forceDestination), slot);
}
}
void MotionMaster::MoveSplinePath(Movement::PointsArray* path)
void MotionMaster::MoveSplinePath(Movement::PointsArray* path, ForcedMovement forcedMovement)
{
// Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE
if (_owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE))
@@ -494,15 +495,15 @@ void MotionMaster::MoveSplinePath(Movement::PointsArray* path)
if (_owner->IsPlayer())
{
Mutate(new EscortMovementGenerator<Player>(path), MOTION_SLOT_ACTIVE);
Mutate(new EscortMovementGenerator<Player>(forcedMovement, path), MOTION_SLOT_ACTIVE);
}
else
{
Mutate(new EscortMovementGenerator<Creature>(path), MOTION_SLOT_ACTIVE);
Mutate(new EscortMovementGenerator<Creature>(forcedMovement, path), MOTION_SLOT_ACTIVE);
}
}
void MotionMaster::MoveSplinePath(uint32 path_id)
void MotionMaster::MoveSplinePath(uint32 path_id, ForcedMovement forcedMovement)
{
// convert the path id to a Movement::PointsArray*
Movement::PointsArray* points = new Movement::PointsArray();
@@ -514,7 +515,7 @@ void MotionMaster::MoveSplinePath(uint32 path_id)
}
// pass the new PointsArray* to the appropriate MoveSplinePath function
MoveSplinePath(points);
MoveSplinePath(points, forcedMovement);
}
/**
@@ -539,8 +540,8 @@ void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed /* = 0.0
}
init.SetAnimation(Movement::ToGround);
init.Launch();
Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
Mutate(new EffectMovementGenerator(init, id), MOTION_SLOT_ACTIVE);
}
/**
@@ -569,16 +570,12 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed /* =
init.MoveTo(x, y, z);
if (speed > 0.0f)
{
init.SetVelocity(speed);
}
if (!skipAnimation)
{
init.SetAnimation(Movement::ToFly);
}
init.Launch();
Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
Mutate(new EffectMovementGenerator(init, id), MOTION_SLOT_ACTIVE);
}
/**
@@ -612,8 +609,8 @@ void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, floa
init.SetParabolic(max_height, 0);
init.SetOrientationFixed(true);
init.SetVelocity(speedXY);
init.Launch();
Mutate(new EffectMovementGenerator(0), MOTION_SLOT_CONTROLLED);
Mutate(new EffectMovementGenerator(init, 0), MOTION_SLOT_CONTROLLED);
}
/**
@@ -652,8 +649,8 @@ void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float spee
init.SetVelocity(speedXY);
if (target)
init.SetFacing(target);
init.Launch();
Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED);
Mutate(new EffectMovementGenerator(init, id), MOTION_SLOT_CONTROLLED);
}
/**
@@ -695,8 +692,8 @@ void MotionMaster::MoveFall(uint32 id /*=0*/, bool addFlagForNPC)
Movement::MoveSplineInit init(_owner);
init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz + _owner->GetHoverHeight());
init.SetFall();
init.Launch();
Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED);
Mutate(new EffectMovementGenerator(init, id), MOTION_SLOT_CONTROLLED);
}
/**
@@ -713,12 +710,12 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id,
if (_owner->IsPlayer())
{
LOG_DEBUG("movement.motionmaster", "Player ({}) charge point (X: {} Y: {} Z: {})", _owner->GetGUID().ToString(), x, y, z);
Mutate(new PointMovementGenerator<Player>(id, x, y, z, speed, orientation, path, generatePath, generatePath, targetGUID), MOTION_SLOT_CONTROLLED);
Mutate(new PointMovementGenerator<Player>(id, x, y, z, FORCED_MOVEMENT_NONE, speed, orientation, path, generatePath, generatePath, targetGUID), MOTION_SLOT_CONTROLLED);
}
else
{
LOG_DEBUG("movement.motionmaster", "Creature ({}) charge point (X: {} Y: {} Z: {})", _owner->GetGUID().ToString(), x, y, z);
Mutate(new PointMovementGenerator<Creature>(id, x, y, z, speed, orientation, path, generatePath, generatePath, targetGUID), MOTION_SLOT_CONTROLLED);
Mutate(new PointMovementGenerator<Creature>(id, x, y, z, FORCED_MOVEMENT_NONE, speed, orientation, path, generatePath, generatePath, targetGUID), MOTION_SLOT_CONTROLLED);
}
}

View File

@@ -80,6 +80,15 @@ enum RotateDirection
ROTATE_DIRECTION_RIGHT
};
enum ForcedMovement
{
FORCED_MOVEMENT_NONE = 0,
FORCED_MOVEMENT_WALK = 1,
FORCED_MOVEMENT_RUN = 2,
FORCED_MOVEMENT_MAX
};
struct ChaseRange
{
ChaseRange(float range);
@@ -210,11 +219,11 @@ public:
void MoveForwards(Unit* target, float dist);
void MoveConfused();
void MoveFleeing(Unit* enemy, uint32 time = 0);
void MovePoint(uint32 id, const Position& pos, bool generatePath = true, bool forceDestination = true)
{ MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ, generatePath, forceDestination, MOTION_SLOT_ACTIVE, pos.GetOrientation()); }
void MovePoint(uint32 id, float x, float y, float z, bool generatePath = true, bool forceDestination = true, MovementSlot slot = MOTION_SLOT_ACTIVE, float orientation = 0.0f);
void MoveSplinePath(Movement::PointsArray* path);
void MoveSplinePath(uint32 path_id);
void MovePoint(uint32 id, const Position& pos, ForcedMovement forcedMovement = FORCED_MOVEMENT_NONE, float speed = 0.f, bool generatePath = true, bool forceDestination = true)
{ MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ, forcedMovement, speed, pos.GetOrientation(), generatePath, forceDestination, MOTION_SLOT_ACTIVE); }
void MovePoint(uint32 id, float x, float y, float z, ForcedMovement forcedMovement = FORCED_MOVEMENT_NONE, float speed = 0.f, float orientation = 0.0f, bool generatePath = true, bool forceDestination = true, MovementSlot slot = MOTION_SLOT_ACTIVE);
void MoveSplinePath(Movement::PointsArray* path, ForcedMovement forcedMovement = FORCED_MOVEMENT_NONE);
void MoveSplinePath(uint32 path_id, ForcedMovement forcedMovement = FORCED_MOVEMENT_NONE);
// These two movement types should only be used with creatures having landing/takeoff animations
void MoveLand(uint32 id, Position const& pos, float speed = 0.0f);

View File

@@ -146,6 +146,7 @@ bool ConfusedMovementGenerator<T>::DoUpdate(T* unit, uint32 diff)
float z = i_waypoints[i_nextMove][2];
Movement::MoveSplineInit init(unit);
init.MoveTo(x, y, z, true);
init.SetWalk(true);
init.Launch();
}
}

View File

@@ -36,6 +36,11 @@ void EscortMovementGenerator<T>::DoInitialize(T* unit)
else if (m_precomputedPath.size())
init.MovebyPath(m_precomputedPath);
if (_forcedMovement == FORCED_MOVEMENT_WALK)
init.SetWalk(true);
else if (_forcedMovement == FORCED_MOVEMENT_RUN)
init.SetWalk(false);
init.Launch();
_splineId = unit->movespline->GetId();
@@ -79,6 +84,11 @@ bool EscortMovementGenerator<T>::DoUpdate(T* unit, uint32 /*diff*/)
init.MoveTo(m_precomputedPath[1].x, m_precomputedPath[1].y, m_precomputedPath[1].z, true);
}
if (_forcedMovement == FORCED_MOVEMENT_WALK)
init.SetWalk(true);
else if (_forcedMovement == FORCED_MOVEMENT_RUN)
init.SetWalk(false);
init.Launch();
// Xinef: Override spline Id on recalculate launch
_splineId = unit->movespline->GetId();

View File

@@ -24,7 +24,7 @@ template<class T>
class EscortMovementGenerator : public MovementGeneratorMedium< T, EscortMovementGenerator<T> >
{
public:
EscortMovementGenerator(Movement::PointsArray* _path = nullptr) : i_recalculateSpeed(false)
EscortMovementGenerator(ForcedMovement forcedMovement, Movement::PointsArray* _path = nullptr) : i_recalculateSpeed(false), _forcedMovement(forcedMovement)
{
if (_path)
m_precomputedPath = *_path;
@@ -46,6 +46,7 @@ private:
Movement::PointsArray m_precomputedPath;
uint32 _splineId;
ForcedMovement _forcedMovement;
};
#endif

View File

@@ -31,8 +31,6 @@ void HomeMovementGenerator<Creature>::DoFinalize(Creature* owner)
owner->ClearUnitState(UNIT_STATE_EVADE);
if (arrived)
{
// Xinef: npc run by default
//owner->SetWalk(true);
owner->LoadCreaturesAddon(true);
owner->AI()->JustReachedHome();
}

View File

@@ -84,6 +84,11 @@ void PointMovementGenerator<T>::DoInitialize(T* unit)
if (speed > 0.0f)
init.SetVelocity(speed);
if (_forcedMovement == FORCED_MOVEMENT_WALK)
init.SetWalk(true);
else if (_forcedMovement == FORCED_MOVEMENT_RUN)
init.SetWalk(false);
if (i_orientation > 0.0f)
{
init.SetFacing(i_orientation);
@@ -142,6 +147,11 @@ bool PointMovementGenerator<T>::DoUpdate(T* unit, uint32 /*diff*/)
if (speed > 0.0f) // Default value for point motion type is 0.0, if 0.0 spline will use GetSpeed on unit
init.SetVelocity(speed);
if (_forcedMovement == FORCED_MOVEMENT_WALK)
init.SetWalk(true);
else if (_forcedMovement == FORCED_MOVEMENT_RUN)
init.SetWalk(false);
if (i_orientation > 0.0f)
{
init.SetFacing(i_orientation);
@@ -228,6 +238,11 @@ bool EffectMovementGenerator::Update(Unit* unit, uint32)
return !unit->movespline->Finalized();
}
void EffectMovementGenerator::Initialize(Unit*)
{
i_spline.Launch();
}
void EffectMovementGenerator::Finalize(Unit* unit)
{
if (!unit->IsCreature())

View File

@@ -20,15 +20,16 @@
#include "Creature.h"
#include "MovementGenerator.h"
#include "MoveSplineInit.h"
template<class T>
class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementGenerator<T> >
{
public:
PointMovementGenerator(uint32 _id, float _x, float _y, float _z, float _speed = 0.0f, float orientation = 0.0f, const Movement::PointsArray* _path = nullptr,
bool generatePath = false, bool forceDestination = false, ObjectGuid chargeTargetGUID = ObjectGuid::Empty)
: id(_id), i_x(_x), i_y(_y), i_z(_z), speed(_speed), i_orientation(orientation), _generatePath(generatePath), _forceDestination(forceDestination),
_chargeTargetGUID(chargeTargetGUID)
PointMovementGenerator(uint32 _id, float _x, float _y, float _z, ForcedMovement forcedMovement, float _speed = 0.0f, float orientation = 0.0f, const Movement::PointsArray* _path = nullptr,
bool generatePath = false, bool forceDestination = false, ObjectGuid chargeTargetGUID = ObjectGuid::Empty, bool reverseOrientation = false, ObjectGuid facingTargetGuid = ObjectGuid())
: id(_id), i_x(_x), i_y(_y), i_z(_z), speed(_speed), i_orientation(orientation), _generatePath(generatePath), _forceDestination(forceDestination), _reverseOrientation(reverseOrientation),
_chargeTargetGUID(chargeTargetGUID), _forcedMovement(forcedMovement), _facingTargetGuid(facingTargetGuid)
{
if (_path)
m_precomputedPath = *_path;
@@ -55,14 +56,17 @@ private:
Movement::PointsArray m_precomputedPath;
bool _generatePath;
bool _forceDestination;
bool _reverseOrientation;
ObjectGuid _chargeTargetGUID;
ForcedMovement _forcedMovement;
ObjectGuid _facingTargetGuid;
};
class AssistanceMovementGenerator : public PointMovementGenerator<Creature>
{
public:
AssistanceMovementGenerator(float _x, float _y, float _z) :
PointMovementGenerator<Creature>(0, _x, _y, _z) {}
PointMovementGenerator<Creature>(0, _x, _y, _z, FORCED_MOVEMENT_NONE) {}
MovementGeneratorType GetMovementGeneratorType() { return ASSISTANCE_MOTION_TYPE; }
void Finalize(Unit*);
@@ -72,14 +76,15 @@ public:
class EffectMovementGenerator : public MovementGenerator
{
public:
explicit EffectMovementGenerator(uint32 Id) : m_Id(Id) {}
void Initialize(Unit*) override {}
explicit EffectMovementGenerator(Movement::MoveSplineInit& spline, uint32 Id) : m_Id(Id), i_spline(spline) {}
void Initialize(Unit*) override;
void Finalize(Unit*) override;
void Reset(Unit*) override {}
bool Update(Unit*, uint32) override;
MovementGeneratorType GetMovementGeneratorType() override { return EFFECT_MOTION_TYPE; }
private:
uint32 m_Id;
Movement::MoveSplineInit i_spline;
};
#endif

View File

@@ -51,7 +51,21 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)
creature->AddUnitState(UNIT_STATE_ROAMING_MOVE);
Movement::MoveSplineInit init(creature);
init.MoveTo(_currDestPosition.GetPositionX(), _currDestPosition.GetPositionY(), _currDestPosition.GetPositionZ());
init.SetWalk(true);
bool walk = true;
switch (creature->GetMovementTemplate().GetRandom())
{
case CreatureRandomMovementType::CanRun:
walk = creature->IsWalking();
break;
case CreatureRandomMovementType::AlwaysRun:
walk = false;
break;
default:
break;
}
init.SetWalk(walk);
init.Launch();
if (creature->GetFormation() && creature->GetFormation()->GetLeader() == creature)
creature->GetFormation()->LeaderMoveTo(_currDestPosition.GetPositionX(), _currDestPosition.GetPositionY(), _currDestPosition.GetPositionZ(), 0);
@@ -270,7 +284,6 @@ template<>
void RandomMovementGenerator<Creature>::DoFinalize(Creature* creature)
{
creature->ClearUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE);
creature->SetWalk(false);
}
template<>

View File

@@ -365,7 +365,6 @@ void ChaseMovementGenerator<Creature>::DoInitialize(Creature* owner)
_lastTargetPosition.reset();
i_recheckDistance.Reset(0);
i_leashExtensionTimer.Reset(owner->GetAttackTime(BASE_ATTACK));
owner->SetWalk(false);
owner->AddUnitState(UNIT_STATE_CHASE);
}

View File

@@ -56,7 +56,6 @@ void WaypointMovementGenerator<Creature>::DoInitialize(Creature* creature)
void WaypointMovementGenerator<Creature>::DoFinalize(Creature* creature)
{
creature->ClearUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE);
creature->SetWalk(false);
}
void WaypointMovementGenerator<Creature>::DoReset(Creature* creature)