Skip to content

Instantly share code, notes, and snippets.

@Shauren
Created January 9, 2026 21:43
Show Gist options
  • Select an option

  • Save Shauren/85302fcb850bb3a1ce2dffb01d4597fb to your computer and use it in GitHub Desktop.

Select an option

Save Shauren/85302fcb850bb3a1ce2dffb01d4597fb to your computer and use it in GitHub Desktop.
Immediate MovementGenerator idea (for facing splines)
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 1c7b362176..1a60e0f91c 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -336,6 +336,9 @@ void MotionMaster::Add(MovementGenerator* movement, MovementSlot slot/* = MOTION
return;
}
+ if (movement->HasFlag(MOVEMENTGENERATOR_FLAG_IMMEDIATE) && movement->HasFlag(MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING))
+ movement->Initialize(_owner);
+
if (HasFlag(MOTIONMASTER_FLAG_DELAYED))
{
DelayedActionDefine action = [this, movement, slot]()
@@ -1186,6 +1189,69 @@ void MotionMaster::MoveFormation(Unit* leader, float range, float angle, uint32
}
}
+class ImmediateMovementGenerator : public MovementGenerator
+{
+public:
+ explicit ImmediateMovementGenerator(std::function<void(Movement::MoveSplineInit& init)>&& initializer, uint32 id) : _splineInit(std::move(initializer)), _pointId(id)
+ {
+ Mode = MOTION_MODE_DEFAULT;
+ Priority = MOTION_PRIORITY_NORMAL;
+ Flags = MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING | MOVEMENTGENERATOR_FLAG_IMMEDIATE;
+ BaseUnitState = 0;
+ }
+
+ void Initialize(Unit* owner) override
+ {
+ RemoveFlag(MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING);
+ AddFlag(MOVEMENTGENERATOR_FLAG_INITIALIZED);
+
+ Movement::MoveSplineInit init(owner);
+ _splineInit(init);
+ owner->UpdateSplineMovement(init.Launch()); // immediately consume the entire spline
+ }
+
+ void Reset(Unit*) override { }
+ bool Update(Unit*, uint32) override { return true; }
+ void Deactivate(Unit*) override { }
+ void Finalize(Unit* owner, bool, bool) override
+ {
+ SetScriptResult(MovementStopReason::Finished);
+
+ if (Creature* creature = owner->ToCreature())
+ if (creature->AI())
+ creature->AI()->MovementInform(EFFECT_MOTION_TYPE, _pointId);
+ }
+
+ MovementGeneratorType GetMovementGeneratorType() const override { return EFFECT_MOTION_TYPE; }
+
+private:
+ std::function<void(Movement::MoveSplineInit& init)> _splineInit;
+ uint32 _pointId;
+};
+
+void MotionMaster::MoveFace(MovementFacingTarget const& facing, uint32 id)
+{
+ std::function<void(Movement::MoveSplineInit& init)> splineInit = [& /*safe, invoked imediately*/](Movement::MoveSplineInit& init)
+ {
+ bool transport = _owner->GetTransport() != nullptr;
+
+ if (!_owner->movespline->Finalized() && _owner->movespline->onTransport == transport)
+ init.MoveTo(_owner->movespline->ComputePosition(), false);
+ else if (!transport)
+ init.MoveTo(PositionToVector3(_owner->GetPosition()), false);
+ else
+ init.MoveTo(PositionToVector3(_owner->m_movementInfo.transport.pos), false);
+
+ if (transport)
+ init.DisableTransportPathTransformations(); // It makes no sense to target global orientation
+
+ std::visit(Movement::MoveSplineInitFacingVisitor(init), facing);
+ };
+
+ // new MovementGenerator object is created to ensure proper lifecycle of the previous generator, deactivating/reactivating it
+ Add(new ImmediateMovementGenerator(std::move(splineInit), id));
+}
+
void MotionMaster::LaunchMoveSpline(std::function<void(Movement::MoveSplineInit& init)>&& initializer, uint32 id/*= 0*/, MovementGeneratorPriority priority/* = MOTION_PRIORITY_NORMAL*/, MovementGeneratorType type/*= EFFECT_MOTION_TYPE*/)
{
if (IsInvalidMovementGeneratorType(type))
@@ -1339,8 +1405,17 @@ void MotionMaster::DirectAdd(MovementGenerator* movement, MovementSlot slot/* =
else
_defaultGenerator->Deactivate(_owner);
- _generators.emplace(movement);
- AddBaseUnitState(movement);
+ if (!movement->HasFlag(MOVEMENTGENERATOR_FLAG_IMMEDIATE))
+ {
+ _generators.emplace(movement);
+ AddBaseUnitState(movement);
+ }
+ else
+ {
+ movement->Finalize(_owner, true, true);
+ delete movement;
+ }
+
break;
default:
break;
diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h
index e677d65bb3..51cc7eb648 100755
--- a/src/server/game/Movement/MovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerator.h
@@ -42,6 +42,7 @@ enum MovementGeneratorFlags : uint16
MOVEMENTGENERATOR_FLAG_INFORM_ENABLED = 0x080,
MOVEMENTGENERATOR_FLAG_FINALIZED = 0x100,
MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH = 0x200,
+ MOVEMENTGENERATOR_FLAG_IMMEDIATE = 0x400,
MOVEMENTGENERATOR_FLAG_TRANSITORY = MOVEMENTGENERATOR_FLAG_SPEED_UPDATE_PENDING | MOVEMENTGENERATOR_FLAG_INTERRUPTED
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment