aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2026-01-04 19:34:22 +0100
committerShauren <shauren.trinity@gmail.com>2026-01-04 19:34:22 +0100
commit0b85b1b0bc5743f65101b44abc6f5e6ca05b0632 (patch)
tree57fdc28f9f1e34b2b9db5e8d3ac42bb5ce8ec86c /src/server
parente8a702930e68caa0229040245a38da9669ea1469 (diff)
Core/Movement: Add forced speed and movement type parameters to random movement generator
Diffstat (limited to 'src/server')
-rw-r--r--src/server/game/Movement/MotionMaster.cpp5
-rw-r--r--src/server/game/Movement/MotionMaster.h3
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp129
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h5
-rw-r--r--src/server/scripts/Zandalar/Underrot/boss_cragmaw_the_infested.cpp2
5 files changed, 70 insertions, 74 deletions
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index af61fd0a27f..768d7004c97 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -593,13 +593,14 @@ void MotionMaster::MoveTargetedHome()
}
}
-void MotionMaster::MoveRandom(float wanderDistance /*= 0.0f*/, Optional<Milliseconds> duration /*= {}*/, MovementSlot slot /*= MOTION_SLOT_DEFAULT*/,
+void MotionMaster::MoveRandom(float wanderDistance /*= 0.0f*/, Optional<Milliseconds> duration /*= {}*/, Optional<float> speed /*= {}*/,
+ MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::ForceWalk*/, MovementSlot slot /*= MOTION_SLOT_DEFAULT*/,
Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
if (_owner->GetTypeId() == TYPEID_UNIT)
{
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveRandom: '{}', started random movement (spawnDist: {})", _owner->GetGUID(), wanderDistance);
- Add(new RandomMovementGenerator<Creature>(wanderDistance, duration, std::move(scriptResult)), slot);
+ Add(new RandomMovementGenerator<Creature>(wanderDistance, duration, speed, speedSelectionMode, std::move(scriptResult)), slot);
}
else if (scriptResult)
scriptResult->SetResult(MovementStopReason::Interrupted);
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index 1126b6a5cab..d8696cbb44a 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -157,7 +157,8 @@ class TC_GAME_API MotionMaster
void MoveIdle();
void MoveTargetedHome();
- void MoveRandom(float wanderDistance = 0.0f, Optional<Milliseconds> duration = {}, MovementSlot slot = MOTION_SLOT_DEFAULT,
+ void MoveRandom(float wanderDistance = 0.0f, Optional<Milliseconds> duration = {}, Optional<float> speed = {},
+ MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::ForceWalk, MovementSlot slot = MOTION_SLOT_DEFAULT,
Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
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 = {});
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
index ff705836a88..12dcb0dda19 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
@@ -25,8 +25,10 @@
#include "Random.h"
template<class T>
-RandomMovementGenerator<T>::RandomMovementGenerator(float distance, Optional<Milliseconds> duration,
- Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/) : _timer(0), _reference(), _wanderDistance(distance), _wanderSteps(0)
+RandomMovementGenerator<T>::RandomMovementGenerator(float distance, Optional<Milliseconds> duration, Optional<float> speed,
+ MovementWalkRunSpeedSelectionMode speedSelectionMode,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
+ : _timer(0), _speed(speed), _speedSelectionMode(speedSelectionMode), _wanderDistance(distance), _wanderSteps(0)
{
this->Mode = MOTION_MODE_DEFAULT;
this->Priority = MOTION_PRIORITY_NORMAL;
@@ -37,10 +39,6 @@ RandomMovementGenerator<T>::RandomMovementGenerator(float distance, Optional<Mil
_duration.emplace(*duration);
}
-template
-RandomMovementGenerator<Creature>::RandomMovementGenerator(float distance, Optional<Milliseconds> duration,
- Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult);
-
template<class T>
MovementGeneratorType RandomMovementGenerator<T>::GetMovementGeneratorType() const
{
@@ -72,26 +70,18 @@ void RandomMovementGenerator<T>::Resume(uint32 overrideTimer)
this->RemoveFlag(MOVEMENTGENERATOR_FLAG_PAUSED);
}
-template MovementGeneratorType RandomMovementGenerator<Creature>::GetMovementGeneratorType() const;
-
template<class T>
-void RandomMovementGenerator<T>::DoInitialize(T*) { }
-
-template<>
-void RandomMovementGenerator<Creature>::DoInitialize(Creature* owner)
+void RandomMovementGenerator<T>::DoInitialize(T* owner)
{
- RemoveFlag(MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING | MOVEMENTGENERATOR_FLAG_TRANSITORY | MOVEMENTGENERATOR_FLAG_DEACTIVATED | MOVEMENTGENERATOR_FLAG_TIMED_PAUSED);
- AddFlag(MOVEMENTGENERATOR_FLAG_INITIALIZED);
+ this->RemoveFlag(MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING | MOVEMENTGENERATOR_FLAG_TRANSITORY | MOVEMENTGENERATOR_FLAG_DEACTIVATED | MOVEMENTGENERATOR_FLAG_TIMED_PAUSED);
+ this->AddFlag(MOVEMENTGENERATOR_FLAG_INITIALIZED);
- if (!owner || !owner->IsAlive())
+ if (!owner->IsAlive())
return;
_reference = owner->GetPosition();
owner->StopMoving();
- if (_wanderDistance == 0.f)
- _wanderDistance = owner->GetWanderDistance();
-
// Retail seems to let a creature walk 2 up to 10 splines before triggering a pause
_wanderSteps = urand(2, 10);
@@ -100,28 +90,19 @@ void RandomMovementGenerator<Creature>::DoInitialize(Creature* owner)
}
template<class T>
-void RandomMovementGenerator<T>::DoReset(T*) { }
-
-template<>
-void RandomMovementGenerator<Creature>::DoReset(Creature* owner)
+void RandomMovementGenerator<T>::DoReset(T* owner)
{
- RemoveFlag(MOVEMENTGENERATOR_FLAG_TRANSITORY | MOVEMENTGENERATOR_FLAG_DEACTIVATED);
+ this->RemoveFlag(MOVEMENTGENERATOR_FLAG_TRANSITORY | MOVEMENTGENERATOR_FLAG_DEACTIVATED);
DoInitialize(owner);
}
template<class T>
-void RandomMovementGenerator<T>::SetRandomLocation(T*) { }
-
-template<>
-void RandomMovementGenerator<Creature>::SetRandomLocation(Creature* owner)
+void RandomMovementGenerator<T>::SetRandomLocation(T* owner)
{
- if (!owner)
- return;
-
if (owner->HasUnitState(UNIT_STATE_NOT_MOVE | UNIT_STATE_LOST_CONTROL) || owner->IsMovementPreventedByCasting())
{
- AddFlag(MOVEMENTGENERATOR_FLAG_INTERRUPTED);
+ this->AddFlag(MOVEMENTGENERATOR_FLAG_INTERRUPTED);
owner->StopMoving();
_path = nullptr;
return;
@@ -163,26 +144,30 @@ void RandomMovementGenerator<Creature>::SetRandomLocation(Creature* owner)
return;
}
- RemoveFlag(MOVEMENTGENERATOR_FLAG_TRANSITORY | MOVEMENTGENERATOR_FLAG_TIMED_PAUSED);
+ this->RemoveFlag(MOVEMENTGENERATOR_FLAG_TRANSITORY | MOVEMENTGENERATOR_FLAG_TIMED_PAUSED);
owner->AddUnitState(UNIT_STATE_ROAMING_MOVE);
- bool walk = true;
- switch (owner->GetMovementTemplate().GetRandom())
+ Movement::MoveSplineInit init(owner);
+ init.MovebyPath(_path->GetPath());
+
+ switch (_speedSelectionMode)
{
- case CreatureRandomMovementType::CanRun:
- walk = owner->IsWalking();
+ case MovementWalkRunSpeedSelectionMode::Default:
break;
- case CreatureRandomMovementType::AlwaysRun:
- walk = false;
+ case MovementWalkRunSpeedSelectionMode::ForceRun:
+ init.SetWalk(false);
+ break;
+ case MovementWalkRunSpeedSelectionMode::ForceWalk:
+ init.SetWalk(true);
break;
default:
break;
}
- Movement::MoveSplineInit init(owner);
- init.MovebyPath(_path->GetPath());
- init.SetWalk(walk);
+ if (_speed)
+ init.SetVelocity(*_speed);
+
int32 splineDuration = init.Launch();
--_wanderSteps;
@@ -200,18 +185,12 @@ void RandomMovementGenerator<Creature>::SetRandomLocation(Creature* owner)
}
template<class T>
-bool RandomMovementGenerator<T>::DoUpdate(T*, uint32)
+bool RandomMovementGenerator<T>::DoUpdate(T* owner, uint32 diff)
{
- return false;
-}
-
-template<>
-bool RandomMovementGenerator<Creature>::DoUpdate(Creature* owner, uint32 diff)
-{
- if (!owner || !owner->IsAlive())
+ if (!owner->IsAlive())
return true;
- if (HasFlag(MOVEMENTGENERATOR_FLAG_FINALIZED | MOVEMENTGENERATOR_FLAG_PAUSED))
+ if (this->HasFlag(MOVEMENTGENERATOR_FLAG_FINALIZED | MOVEMENTGENERATOR_FLAG_PAUSED))
return true;
if (_duration)
@@ -219,46 +198,40 @@ bool RandomMovementGenerator<Creature>::DoUpdate(Creature* owner, uint32 diff)
_duration->Update(diff);
if (_duration->Passed())
{
- RemoveFlag(MOVEMENTGENERATOR_FLAG_TRANSITORY);
- AddFlag(MOVEMENTGENERATOR_FLAG_INFORM_ENABLED);
+ this->RemoveFlag(MOVEMENTGENERATOR_FLAG_TRANSITORY);
+ this->AddFlag(MOVEMENTGENERATOR_FLAG_INFORM_ENABLED);
return false;
}
}
if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting())
{
- AddFlag(MOVEMENTGENERATOR_FLAG_INTERRUPTED);
+ this->AddFlag(MOVEMENTGENERATOR_FLAG_INTERRUPTED);
owner->StopMoving();
_path = nullptr;
return true;
}
else
- RemoveFlag(MOVEMENTGENERATOR_FLAG_INTERRUPTED);
+ this->RemoveFlag(MOVEMENTGENERATOR_FLAG_INTERRUPTED);
_timer.Update(diff);
- if ((HasFlag(MOVEMENTGENERATOR_FLAG_SPEED_UPDATE_PENDING) && !owner->movespline->Finalized()) || (_timer.Passed() && owner->movespline->Finalized()))
+ if ((this->HasFlag(MOVEMENTGENERATOR_FLAG_SPEED_UPDATE_PENDING) && !owner->movespline->Finalized()) || (_timer.Passed() && owner->movespline->Finalized()))
SetRandomLocation(owner);
return true;
}
template<class T>
-void RandomMovementGenerator<T>::DoDeactivate(T*) { }
-
-template<>
-void RandomMovementGenerator<Creature>::DoDeactivate(Creature* owner)
+void RandomMovementGenerator<T>::DoDeactivate(T* owner)
{
- AddFlag(MOVEMENTGENERATOR_FLAG_DEACTIVATED);
+ this->AddFlag(MOVEMENTGENERATOR_FLAG_DEACTIVATED);
owner->ClearUnitState(UNIT_STATE_ROAMING_MOVE);
}
template<class T>
-void RandomMovementGenerator<T>::DoFinalize(T*, bool, bool) { }
-
-template<>
-void RandomMovementGenerator<Creature>::DoFinalize(Creature* owner, bool active, bool movementInform)
+void RandomMovementGenerator<T>::DoFinalize(T* owner, bool active, bool movementInform)
{
- AddFlag(MOVEMENTGENERATOR_FLAG_FINALIZED);
+ this->AddFlag(MOVEMENTGENERATOR_FLAG_FINALIZED);
if (active)
{
owner->ClearUnitState(UNIT_STATE_ROAMING_MOVE);
@@ -268,15 +241,33 @@ void RandomMovementGenerator<Creature>::DoFinalize(Creature* owner, bool active,
owner->SetWalk(false);
}
- if (movementInform && HasFlag(MOVEMENTGENERATOR_FLAG_INFORM_ENABLED))
+ if (movementInform && this->HasFlag(MOVEMENTGENERATOR_FLAG_INFORM_ENABLED))
{
- SetScriptResult(MovementStopReason::Finished);
+ this->SetScriptResult(MovementStopReason::Finished);
if (owner->IsAIEnabled())
owner->AI()->MovementInform(RANDOM_MOTION_TYPE, 0);
}
}
-MovementGenerator* RandomMovementFactory::Create(Unit* /*object*/) const
+MovementGenerator* RandomMovementFactory::Create(Unit* object) const
{
- return new RandomMovementGenerator<Creature>();
+ Creature* owner = object->ToCreature();
+ MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default;
+ switch (owner->GetMovementTemplate().GetRandom())
+ {
+ case CreatureRandomMovementType::Walk:
+ speedSelectionMode = MovementWalkRunSpeedSelectionMode::ForceWalk;
+ break;
+ case CreatureRandomMovementType::CanRun:
+ break;
+ case CreatureRandomMovementType::AlwaysRun:
+ speedSelectionMode = MovementWalkRunSpeedSelectionMode::ForceRun;
+ break;
+ default:
+ break;
+ }
+
+ return new RandomMovementGenerator<Creature>(object->ToCreature()->GetWanderDistance(), {}, {}, speedSelectionMode);
}
+
+template class RandomMovementGenerator<Creature>;
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h
index f67b4096e70..51dcd19f8e8 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h
@@ -29,7 +29,8 @@ template<class T>
class RandomMovementGenerator : public MovementGeneratorMedium<T, RandomMovementGenerator<T>>
{
public:
- explicit RandomMovementGenerator(float distance = 0.0f, Optional<Milliseconds> duration = {},
+ explicit RandomMovementGenerator(float distance, Optional<Milliseconds> duration = {}, Optional<float> speed = {},
+ MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default,
Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
MovementGeneratorType GetMovementGeneratorType() const override;
@@ -51,6 +52,8 @@ class RandomMovementGenerator : public MovementGeneratorMedium<T, RandomMovement
std::unique_ptr<PathGenerator> _path;
TimeTracker _timer;
Optional<TimeTracker> _duration;
+ Optional<float> _speed;
+ MovementWalkRunSpeedSelectionMode _speedSelectionMode;
Position _reference;
float _wanderDistance;
uint8 _wanderSteps;
diff --git a/src/server/scripts/Zandalar/Underrot/boss_cragmaw_the_infested.cpp b/src/server/scripts/Zandalar/Underrot/boss_cragmaw_the_infested.cpp
index 4c174e055a3..163cc81128c 100644
--- a/src/server/scripts/Zandalar/Underrot/boss_cragmaw_the_infested.cpp
+++ b/src/server/scripts/Zandalar/Underrot/boss_cragmaw_the_infested.cpp
@@ -155,7 +155,7 @@ struct boss_cragmaw_the_infested : public BossAI
void MovementInform(uint32 /*type*/, uint32 id) override
{
if (id == POINT_TANTRUM_START_RND_MOVEMENT)
- me->GetMotionMaster()->MoveRandom(20.0f);
+ me->GetMotionMaster()->MoveRandom(20.0f, {}, {}, MovementWalkRunSpeedSelectionMode::ForceRun);
}
void OnChannelFinished(SpellInfo const* spell) override