Created
January 9, 2026 21:43
-
-
Save Shauren/85302fcb850bb3a1ce2dffb01d4597fb to your computer and use it in GitHub Desktop.
Immediate MovementGenerator idea (for facing splines)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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