Skip to content

Commit 2d5430e

Browse files
committed
Core/Movement: Added new immediate movement generator that handles movement without delaying anything to next update tick (for use with instant "movement" like facing changes)
1 parent d37fba1 commit 2d5430e

5 files changed

Lines changed: 72 additions & 4 deletions

File tree

src/server/game/Entities/Unit/Unit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1918,7 +1918,7 @@ class TC_GAME_API Unit : public WorldObject
19181918
virtual void AtDisengage() {}
19191919

19201920
private:
1921-
1921+
friend class ImmediateMovementGenerator; // for UpdateSplineMovement
19221922
void UpdateSplineMovement(uint32 t_diff);
19231923
void UpdateSplinePosition();
19241924
void InterruptMovementBasedAuras();

src/server/game/Movement/MotionMaster.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,15 @@ void MotionMaster::Add(MovementGenerator* movement, MovementSlot slot/* = MOTION
344344
return;
345345
}
346346

347+
if (movement->HasFlag(MOVEMENTGENERATOR_FLAG_IMMEDIATE) && movement->HasFlag(MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING))
348+
{
349+
if (!movement->Initialize(_owner))
350+
{
351+
delete movement;
352+
return;
353+
}
354+
}
355+
347356
if (HasFlag(MOTIONMASTER_FLAG_DELAYED))
348357
{
349358
DelayedActionDefine action = [this, movement, slot]()
@@ -1189,7 +1198,7 @@ void MotionMaster::DirectAdd(MovementGenerator* movement, MovementSlot slot/* =
11891198
}
11901199
else
11911200
{
1192-
auto itr = std::find_if(_generators.begin(), _generators.end(), [movement](MovementGenerator const* a) -> bool
1201+
auto itr = std::ranges::find_if(_generators, [movement](MovementGenerator const* a) -> bool
11931202
{
11941203
return a->Priority == movement->Priority && a->Mode == movement->Mode;
11951204
});
@@ -1201,8 +1210,16 @@ void MotionMaster::DirectAdd(MovementGenerator* movement, MovementSlot slot/* =
12011210
else
12021211
_defaultGenerator->Deactivate(_owner);
12031212

1204-
_generators.emplace(movement);
1205-
AddBaseUnitState(movement);
1213+
if (!movement->HasFlag(MOVEMENTGENERATOR_FLAG_IMMEDIATE))
1214+
{
1215+
_generators.emplace(movement);
1216+
AddBaseUnitState(movement);
1217+
}
1218+
else
1219+
{
1220+
movement->Finalize(_owner, true, true);
1221+
delete movement;
1222+
}
12061223
break;
12071224
default:
12081225
break;

src/server/game/Movement/MovementGenerator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ enum MovementGeneratorFlags : uint16
4040
MOVEMENTGENERATOR_FLAG_INFORM_ENABLED = 0x080,
4141
MOVEMENTGENERATOR_FLAG_FINALIZED = 0x100,
4242
MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH = 0x200,
43+
MOVEMENTGENERATOR_FLAG_IMMEDIATE = 0x400,
4344

4445
MOVEMENTGENERATOR_FLAG_TRANSITORY = MOVEMENTGENERATOR_FLAG_SPEED_UPDATE_PENDING | MOVEMENTGENERATOR_FLAG_INTERRUPTED
4546
};

src/server/game/Movement/MovementGenerators/GenericMovementGenerator.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,34 @@ void GenericMovementGenerator::MovementInform(Unit* owner)
9191
creature->AI()->MovementInform(_type, _pointId);
9292
}
9393
}
94+
95+
ImmediateMovementGenerator::ImmediateMovementGenerator(std::function<void(Movement::MoveSplineInit& init)>&& initializer, MovementGeneratorType type, uint32 id)
96+
: _splineInit(std::move(initializer)), _type(type), _pointId(id)
97+
{
98+
Mode = MOTION_MODE_DEFAULT;
99+
Priority = MOTION_PRIORITY_NORMAL;
100+
Flags = MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING | MOVEMENTGENERATOR_FLAG_IMMEDIATE;
101+
BaseUnitState = 0;
102+
}
103+
104+
bool ImmediateMovementGenerator::Initialize(Unit* owner)
105+
{
106+
RemoveFlag(MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING);
107+
AddFlag(MOVEMENTGENERATOR_FLAG_INITIALIZED);
108+
109+
Movement::MoveSplineInit init(owner);
110+
_splineInit(init);
111+
int32 duration = init.Launch();
112+
if (duration <= 0)
113+
return false;
114+
115+
owner->UpdateSplineMovement(duration); // immediately consume the entire spline
116+
return true;
117+
}
118+
119+
void ImmediateMovementGenerator::Finalize(Unit* owner, bool /*active*/, bool /*movementInform*/)
120+
{
121+
if (Creature* creature = owner->ToCreature())
122+
if (creature->AI())
123+
creature->AI()->MovementInform(_type, _pointId);
124+
}

src/server/game/Movement/MovementGenerators/GenericMovementGenerator.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,23 @@ class GenericMovementGenerator : public MovementGenerator
4848
TimeTracker _duration;
4949
};
5050

51+
class ImmediateMovementGenerator : public MovementGenerator
52+
{
53+
public:
54+
explicit ImmediateMovementGenerator(std::function<void(Movement::MoveSplineInit& init)>&& initializer, MovementGeneratorType type, uint32 id);
55+
56+
bool Initialize(Unit* owner) override;
57+
58+
bool Reset(Unit* /*owner*/) override { return true; }
59+
bool Update(Unit* /*owner*/, uint32 /*diff*/) override { return true; }
60+
void Deactivate(Unit* /*owner*/) override { }
61+
void Finalize(Unit* owner, bool active, bool movementInform) override;
62+
MovementGeneratorType GetMovementGeneratorType() const override { return _type; }
63+
64+
private:
65+
std::function<void(Movement::MoveSplineInit& init)> _splineInit;
66+
MovementGeneratorType _type;
67+
uint32 _pointId;
68+
};
69+
5170
#endif

0 commit comments

Comments
 (0)