diff options
4 files changed, 56 insertions, 22 deletions
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 00ec6f25de0..e305c584c99 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -865,7 +865,8 @@ void MotionMaster::MoveJump(float x, float y, float z, float o, float speedXY, f arrivalSpellTargetGuid = arrivalCast->Target; } - GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id, arrivalSpellId, arrivalSpellTargetGuid); + GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id, + { .ArrivalSpellId = arrivalSpellId, .ArrivalSpellTarget = arrivalSpellTargetGuid }); movement->Priority = MOTION_PRIORITY_HIGHEST; movement->BaseUnitState = UNIT_STATE_JUMPING; Add(movement); @@ -899,14 +900,17 @@ void MotionMaster::MoveJumpWithGravity(Position const& pos, float speedXY, float arrivalSpellTargetGuid = arrivalCast->Target; } - GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id, arrivalSpellId, arrivalSpellTargetGuid); + GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id, + { .ArrivalSpellId = arrivalSpellId, .ArrivalSpellTarget = arrivalSpellTargetGuid }); movement->Priority = MOTION_PRIORITY_HIGHEST; movement->BaseUnitState = UNIT_STATE_JUMPING; movement->AddFlag(MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH); Add(movement); } -void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount) +void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount, + Optional<Milliseconds> duration /*= {}*/, Optional<float> speed /*= {}*/, + MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/) { std::function<void(Movement::MoveSplineInit&)> initializer = [=, this](Movement::MoveSplineInit& init) { @@ -915,11 +919,11 @@ void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool float angle = pos.GetAbsoluteAngle(_owner->GetPositionX(), _owner->GetPositionY()); // add the owner's current position as starting point as it gets removed after entering the cycle - init.Path().push_back(G3D::Vector3(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ())); + init.Path().emplace_back(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); for (uint8 i = 0; i < stepCount; angle += step, ++i) { - G3D::Vector3 point; + G3D::Vector3& point = init.Path().emplace_back(); point.x = x + radius * cosf(angle); point.y = y + radius * sinf(angle); @@ -927,24 +931,34 @@ void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool point.z = z; else point.z = _owner->GetMapHeight(point.x, point.y, z) + _owner->GetHoverOffset(); - - init.Path().push_back(point); } + init.SetCyclic(); if (_owner->IsFlying()) { init.SetFly(); - init.SetCyclic(); init.SetAnimation(AnimTier::Hover); } else - { init.SetWalk(true); - init.SetCyclic(); + + switch (speedSelectionMode) + { + case MovementWalkRunSpeedSelectionMode::ForceRun: + init.SetWalk(false); + break; + case MovementWalkRunSpeedSelectionMode::ForceWalk: + init.SetWalk(true); + break; + case MovementWalkRunSpeedSelectionMode::Default: + default: + break; } + if (speed) + init.SetVelocity(*speed); }; - Add(new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, 0)); + Add(new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, 0, { .Duration = duration })); } void MotionMaster::MoveSmoothPath(uint32 pointId, Position const* pathPoints, size_t pathSize, bool walk, bool fly) diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index f991071c63c..9ecabd77b76 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -185,7 +185,9 @@ class TC_GAME_API MotionMaster void MoveJump(Position const& pos, float speedXY, float speedZ, uint32 id = EVENT_JUMP, bool hasOrientation = false, JumpArrivalCastArgs const* arrivalCast = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr); void MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint32 id = EVENT_JUMP, bool hasOrientation = false, JumpArrivalCastArgs const* arrivalCast = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr); void MoveJumpWithGravity(Position const& pos, float speedXY, float gravity, uint32 id = EVENT_JUMP, bool hasOrientation = false, JumpArrivalCastArgs const* arrivalCast = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr); - void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount); + void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount, + Optional<Milliseconds> duration = {}, Optional<float> speed = {}, + MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default); void MoveSmoothPath(uint32 pointId, Position const* pathPoints, size_t pathSize, bool walk = false, bool fly = false); // Walk along spline chain stored in DB (script_spline_chain_meta and script_spline_chain_waypoints) void MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk); diff --git a/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.cpp index ba61e180432..7bd9d084bc4 100644 --- a/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.cpp @@ -18,20 +18,28 @@ #include "GenericMovementGenerator.h" #include "Creature.h" #include "CreatureAI.h" -#include "MovementDefines.h" #include "MoveSpline.h" +#include "MovementDefines.h" #include "ObjectAccessor.h" #include "Unit.h" GenericMovementGenerator::GenericMovementGenerator(std::function<void(Movement::MoveSplineInit& init)>&& initializer, MovementGeneratorType type, uint32 id, - uint32 arrivalSpellId /*= 0*/, ObjectGuid const& arrivalSpellTargetGuid /*= ObjectGuid::Empty*/) - : _splineInit(std::move(initializer)), _type(type), _pointId(id), _duration(0), - _arrivalSpellId(arrivalSpellId), _arrivalSpellTargetGuid(arrivalSpellTargetGuid) + GenericMovementGeneratorArgs&& args) + : _splineInit(std::move(initializer)), _type(type), _pointId(id), _durationTracksSpline(true), _arrivalSpellId(0) { Mode = MOTION_MODE_DEFAULT; Priority = MOTION_PRIORITY_NORMAL; Flags = MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING; BaseUnitState = UNIT_STATE_ROAMING; + if (args.ArrivalSpellId) + _arrivalSpellId = *args.ArrivalSpellId; + if (args.ArrivalSpellTarget) + _arrivalSpellTargetGuid = *args.ArrivalSpellTarget; + if (args.Duration) + { + _duration.emplace(*args.Duration); + _durationTracksSpline = false; + } } void GenericMovementGenerator::Initialize(Unit* owner) @@ -48,7 +56,9 @@ void GenericMovementGenerator::Initialize(Unit* owner) Movement::MoveSplineInit init(owner); _splineInit(init); - _duration.Reset(init.Launch()); + int32 duration = init.Launch(); + if (_durationTracksSpline) + _duration.emplace(duration); } void GenericMovementGenerator::Reset(Unit* owner) @@ -62,10 +72,10 @@ bool GenericMovementGenerator::Update(Unit* owner, uint32 diff) return false; // Cyclic splines never expire, so update the duration only if it's not cyclic - if (!owner->movespline->isCyclic()) - _duration.Update(diff); + if (_duration) + _duration->Update(diff); - if (_duration.Passed() || owner->movespline->Finalized()) + if ((_duration && _duration->Passed()) || owner->movespline->Finalized()) { AddFlag(MOVEMENTGENERATOR_FLAG_INFORM_ENABLED); return false; diff --git a/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.h b/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.h index 6b3b984c468..f9c46515e6b 100644 --- a/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.h @@ -27,11 +27,18 @@ class Unit; enum MovementGeneratorType : uint8; +struct GenericMovementGeneratorArgs +{ + Optional<uint32> ArrivalSpellId; + Optional<ObjectGuid> ArrivalSpellTarget; + Optional<Milliseconds> Duration; +}; + class GenericMovementGenerator : public MovementGenerator { public: explicit GenericMovementGenerator(std::function<void(Movement::MoveSplineInit& init)>&& initializer, MovementGeneratorType type, uint32 id, - uint32 arrivalSpellId = 0, ObjectGuid const& arrivalSpellTargetGuid = ObjectGuid::Empty); + GenericMovementGeneratorArgs&& args = {}); void Initialize(Unit*) override; void Reset(Unit*) override; @@ -46,7 +53,8 @@ class GenericMovementGenerator : public MovementGenerator std::function<void(Movement::MoveSplineInit& init)> _splineInit; MovementGeneratorType _type; uint32 _pointId; - TimeTracker _duration; + Optional<TimeTracker> _duration; + bool _durationTracksSpline; uint32 _arrivalSpellId; ObjectGuid _arrivalSpellTargetGuid; |
