diff options
Diffstat (limited to 'src')
13 files changed, 170 insertions, 123 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 6827bb29cd4..0864a9e6260 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -390,7 +390,7 @@ bool Creature::IsFormationLeader() const      return m_formation->IsLeader(this);  } -void Creature::SignalFormationMovement(Position const& destination, uint32 id/* = 0*/, uint32 moveType/* = 0*/, bool orientation/* = false*/) +void Creature::SignalFormationMovement()  {      if (!m_formation)          return; @@ -398,7 +398,7 @@ void Creature::SignalFormationMovement(Position const& destination, uint32 id/*      if (!m_formation->IsLeader(this))          return; -    m_formation->LeaderMoveTo(destination, id, moveType, orientation); +    m_formation->LeaderStartedMoving();  }  bool Creature::IsFormationLeaderMoveAllowed() const diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index aa34ad2edfc..f3b084d52dd 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -322,7 +322,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma          CreatureGroup* GetFormation() { return m_formation; }          void SetFormation(CreatureGroup* formation) { m_formation = formation; }          bool IsFormationLeader() const; -        void SignalFormationMovement(Position const& destination, uint32 id = 0, uint32 moveType = 0, bool orientation = false); +        void SignalFormationMovement();          bool IsFormationLeaderMoveAllowed() const;          void SetDisableReputationGain(bool disable) { DisableReputationGain = disable; } diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp index e54e3f33ec6..5b0e76dc084 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.cpp +++ b/src/server/game/Entities/Creature/CreatureGroups.cpp @@ -23,6 +23,7 @@  #include "Log.h"  #include "Map.h"  #include "MotionMaster.h" +#include "MovementGenerator.h"  #include "ObjectMgr.h"  #define MAX_DESYNC 5.0f @@ -275,51 +276,23 @@ void CreatureGroup::FormationReset(bool dismiss)      _formed = !dismiss;  } -void CreatureGroup::LeaderMoveTo(Position const& destination, uint32 id /*= 0*/, uint32 moveType /*= 0*/, bool orientation /*= false*/) +void CreatureGroup::LeaderStartedMoving()  { -    //! To do: This should probably get its own movement generator or use WaypointMovementGenerator. -    //! If the leader's path is known, member's path can be plotted as well using formation offsets.      if (!_leader)          return; -    Position pos(destination); -    float pathangle = std::atan2(_leader->GetPositionY() - pos.GetPositionY(), _leader->GetPositionX() - pos.GetPositionX()); -      for (auto const& pair : _members)      {          Creature* member = pair.first;          if (member == _leader || !member->IsAlive() || member->IsEngaged() || !(pair.second->GroupAI & FLAG_IDLE_IN_FORMATION))              continue; -        if (pair.second->LeaderWaypointIDs[0]) -        { -            for (uint8 i = 0; i < 2; ++i) -            { -                if (_leader->GetCurrentWaypointInfo().first == pair.second->LeaderWaypointIDs[i]) -                { -                    pair.second->FollowAngle = float(M_PI) * 2.f - pair.second->FollowAngle; -                    break; -                } -            } -        } - -        float angle = pair.second->FollowAngle; +        float angle = pair.second->FollowAngle + float(M_PI); // for some reason, someone thought it was a great idea to invert relativ angles...          float dist = pair.second->FollowDist; -        float dx = pos.GetPositionX() + std::cos(angle + pathangle) * dist; -        float dy = pos.GetPositionY() + std::sin(angle + pathangle) * dist; -        float dz = pos.GetPositionZ(); - -        Trinity::NormalizeMapCoord(dx); -        Trinity::NormalizeMapCoord(dy); - -        if (!member->IsFlying()) -            member->UpdateGroundPositionZ(dx, dy, dz); - -        member->SetHomePosition(dx, dy, dz, pathangle); - -        Position point(dx, dy, dz, destination.GetOrientation()); -        member->GetMotionMaster()->MoveFormation(id, point, moveType, !member->IsWithinDist(_leader, dist + MAX_DESYNC), orientation); +        MovementGenerator const* moveGen = member->GetMotionMaster()->GetMovementGenerator([](MovementGenerator const* movement)->bool { return movement->GetMovementGeneratorType() == FORMATION_MOTION_TYPE; }, MOTION_SLOT_DEFAULT); +        if (!moveGen) +            member->GetMotionMaster()->MoveFormation(_leader, dist, angle, pair.second->LeaderWaypointIDs[0], pair.second->LeaderWaypointIDs[1]);      }  } diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h index 2b4924774ec..748df579251 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.h +++ b/src/server/game/Entities/Creature/CreatureGroups.h @@ -92,7 +92,7 @@ class TC_GAME_API CreatureGroup          void RemoveMember(Creature* member);          void FormationReset(bool dismiss); -        void LeaderMoveTo(Position const& destination, uint32 id = 0, uint32 moveType = 0, bool orientation = false); +        void LeaderStartedMoving();          void MemberEngagingTarget(Creature* member, Unit* target);          bool CanLeaderStartMoving() const;  }; diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 3b21d0b4dec..d77ce6e9a73 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -1068,12 +1068,12 @@ void MotionMaster::MoveRotate(uint32 id, uint32 time, RotateDirection direction)      Add(new RotateMovementGenerator(id, time, direction));  } -void MotionMaster::MoveFormation(uint32 id, Position destination, uint32 moveType, bool forceRun /*= false*/, bool forceOrientation /*= false*/) +void MotionMaster::MoveFormation(Unit* leader, float range, float angle, uint32 point1, uint32 point2)  { -    if (_owner->GetTypeId() == TYPEID_UNIT) +    if (_owner->GetTypeId() == TYPEID_UNIT && leader)      { -        TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveFormation: '%s', targeted point Id: %u (X: %f, Y: %f, Z: %f)", _owner->GetGUID().ToString().c_str(), id, destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ()); -        Add(new FormationMovementGenerator(id, destination, moveType, forceRun, forceOrientation)); +        TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveFormation: '%s', started to move in a formation with leader %s", _owner->GetGUID().ToString().c_str(), leader->GetGUID().ToString().c_str()); +        Add(new FormationMovementGenerator(leader, range, angle, point1, point2), MOTION_SLOT_DEFAULT);      }  } diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index a72a5d70079..830d6ca8628 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -192,7 +192,7 @@ class TC_GAME_API MotionMaster          void MovePath(uint32 pathId, bool repeatable);          void MovePath(WaypointPath& path, bool repeatable);          void MoveRotate(uint32 id, uint32 time, RotateDirection direction); -        void MoveFormation(uint32 id, Position destination, uint32 moveType, bool forceRun = false, bool forceOrientation = false); +        void MoveFormation(Unit* leader, float range, float angle, uint32 point1, uint32 point2);          void LaunchMoveSpline(Movement::MoveSplineInit&& init, uint32 id = 0, MovementGeneratorPriority priority = MOTION_PRIORITY_NORMAL, MovementGeneratorType type = EFFECT_MOTION_TYPE);      private: diff --git a/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.cpp index cebfc8bc449..9bc79afcee0 100644 --- a/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.cpp @@ -18,11 +18,14 @@  #include "FormationMovementGenerator.h"  #include "Creature.h"  #include "CreatureAI.h" +#include "CreatureGroups.h" +#include "G3DPosition.hpp"  #include "MovementDefines.h"  #include "MoveSpline.h"  #include "MoveSplineInit.h" -FormationMovementGenerator::FormationMovementGenerator(uint32 id, Position destination, uint32 moveType, bool run, bool orientation) : _movementId(id), _destination(destination), _moveType(moveType), _run(run), _orientation(orientation) +FormationMovementGenerator::FormationMovementGenerator(Unit* leader, float range, float angle, uint32 point1, uint32 point2) : AbstractFollower(ASSERT_NOTNULL(leader)), +    _range(range), _angle(angle), _point1(point1), _point2(point2), _lastLeaderSplineID(0), _hasPredictedDestination(false)  {      Mode = MOTION_MODE_DEFAULT;      Priority = MOTION_PRIORITY_NORMAL; @@ -47,33 +50,7 @@ void FormationMovementGenerator::DoInitialize(Creature* owner)          return;      } -    owner->AddUnitState(UNIT_STATE_ROAMING_MOVE); - -    Movement::MoveSplineInit init(owner); -    init.MoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ()); -    if (_orientation) -        init.SetFacing(_destination.GetOrientation()); - -    switch (_moveType) -    { -        case 2: // WAYPOINT_MOVE_TYPE_LAND -            init.SetAnimation(Movement::ToGround); -            break; -        case 3: // WAYPOINT_MOVE_TYPE_TAKEOFF -            init.SetAnimation(Movement::ToFly); -            break; -        case 1: // WAYPOINT_MOVE_TYPE_RUN -            init.SetWalk(false); -            break; -        case 0: // WAYPOINT_MOVE_TYPE_WALK -            init.SetWalk(true); -            break; -    } - -    if (_run) -        init.SetWalk(false); - -    init.Launch(); +    _nextMoveTimer.Reset(0);  }  void FormationMovementGenerator::DoReset(Creature* owner) @@ -83,59 +60,154 @@ void FormationMovementGenerator::DoReset(Creature* owner)      DoInitialize(owner);  } -bool FormationMovementGenerator::DoUpdate(Creature* owner, uint32 /*diff*/) +bool FormationMovementGenerator::DoUpdate(Creature* owner, uint32 diff)  { -    if (!owner) +    Unit* target = GetTarget(); + +    if (!owner || !target)          return false; +    // Owner cannot move. Reset all fields and wait for next action      if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting())      {          AddFlag(MOVEMENTGENERATOR_FLAG_INTERRUPTED); +        owner->ClearUnitState(UNIT_STATE_ROAMING_MOVE);          owner->StopMoving();          return true;      } -    if ((HasFlag(MOVEMENTGENERATOR_FLAG_INTERRUPTED) && owner->movespline->Finalized()) || (HasFlag(MOVEMENTGENERATOR_FLAG_SPEED_UPDATE_PENDING) && !owner->movespline->Finalized())) +    // Leader has stopped moving, so do we as well +    if (target->movespline->Finalized() && target->movespline->GetId() == _lastLeaderSplineID && _hasPredictedDestination)      { -        RemoveFlag(MOVEMENTGENERATOR_FLAG_INTERRUPTED | MOVEMENTGENERATOR_FLAG_SPEED_UPDATE_PENDING); +        owner->ClearUnitState(UNIT_STATE_ROAMING_MOVE); +        owner->StopMoving(); +        _nextMoveTimer.Reset(0); +        _hasPredictedDestination = false; +        return true; +    } -        owner->AddUnitState(UNIT_STATE_ROAMING_MOVE); +    // Update home position +    owner->SetHomePosition(owner->GetPosition()); +    if (HasFlag(MOVEMENTGENERATOR_FLAG_INTERRUPTED)) +        RemoveFlag(MOVEMENTGENERATOR_FLAG_INTERRUPTED); -        Movement::MoveSplineInit init(owner); -        init.MoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ()); -        if (_orientation) -            init.SetFacing(_destination.GetOrientation()); +    // Leader has stopped moving, so do we as well +    if (owner->HasUnitState(UNIT_STATE_ROAMING_MOVE) && _hasPredictedDestination && target->movespline->Finalized() && target->movespline->GetId() == _lastLeaderSplineID) +    { +        owner->StopMoving(); +        _nextMoveTimer.Reset(0); +        _hasPredictedDestination = false; +        return true; +    } -        switch (_moveType) +    // Formation leader has launched a new spline, launch a new one for our member as well +    // This action does not reset the regular movement launch cycle interval +    if (!target->movespline->Finalized() && target->movespline->GetId() != _lastLeaderSplineID) +    { +        // Update formation angle +        if (_point1 && target->GetTypeId() == TYPEID_UNIT)          { -            case 2: // WAYPOINT_MOVE_TYPE_LAND -                init.SetAnimation(Movement::ToGround); -                break; -            case 3: // WAYPOINT_MOVE_TYPE_TAKEOFF -                init.SetAnimation(Movement::ToFly); -                break; -            case 1: // WAYPOINT_MOVE_TYPE_RUN -                init.SetWalk(false); -                break; -            case 0: // WAYPOINT_MOVE_TYPE_WALK -                init.SetWalk(true); -                break; +            if (CreatureGroup* formation = target->ToCreature()->GetFormation()) +            { +                if (Creature* leader = formation->GetLeader()) +                { +                    uint8 currentWaypoint = leader->GetCurrentWaypointInfo().first; +                    if (currentWaypoint == _point1 || currentWaypoint == _point2) +                        _angle = float(M_PI) * 2 - _angle; +                } +            }          } -        if (_run) -            init.SetWalk(false); -        init.Launch(); +        LaunchMovement(owner, target); +        _lastLeaderSplineID = target->movespline->GetId(); +        return true;      } -    if (owner->movespline->Finalized()) +    _nextMoveTimer.Update(diff); +    if (_nextMoveTimer.Passed())      { -        RemoveFlag(MOVEMENTGENERATOR_FLAG_TRANSITORY); -        AddFlag(MOVEMENTGENERATOR_FLAG_INFORM_ENABLED); -        return false; +        _nextMoveTimer.Reset(FORMATION_MOVEMENT_INTERVAL); + +        // Our leader has a different position than on our last check, launch movement. +        if (_lastLeaderPosition != target->GetPosition()) +        { +            LaunchMovement(owner, target); +            return true; +        }      } + +    // We have reached our destination before launching a new movement. Alling facing with leader +    if (owner->HasUnitState(UNIT_STATE_ROAMING_MOVE) && owner->movespline->Finalized()) +    { +        owner->ClearUnitState(UNIT_STATE_ROAMING_MOVE); +        owner->SetFacingTo(target->GetOrientation()); +        MovementInform(owner); +    } +      return true;  } +void FormationMovementGenerator::LaunchMovement(Creature* owner, Unit* target) +{ +    float relativeAngle = 0.f; + +    // Determine our relative angle to our current spline destination point +    if (!target->movespline->Finalized()) +        relativeAngle = target->GetRelativeAngle(Vector3ToPosition(target->movespline->CurrentDestination())); + +    // Destination calculation +    /* +        According to sniff data, formation members have a periodic move interal of 1,2s. +        Each of these splines has a exact duration of 1650ms +- 1ms when no pathfinding is involved. +        To get a representative result like that we have to predict our formation leader's path +        and apply our formation shape based on that destination. +    */ +    Position dest = target->GetPosition(); +    float velocity = 0.f; + +    // Formation leader is moving. Predict our destination +    if (!target->movespline->Finalized()) +    { +        // Pick up leader's spline velocity +        velocity = target->movespline->Velocity(); + +        // Calculate travel distance to get a 1650ms result +        float travelDist = velocity * 1.65f; + +        // Move destination ahead... +        target->MovePositionToFirstCollision(dest, travelDist, relativeAngle); +        // ... and apply formation shape +        target->MovePositionToFirstCollision(dest, _range, _angle + relativeAngle); + +        float distance = owner->GetExactDist(dest); + +        // Calculate catchup speed mod (Limit to a maximum of 50% of our original velocity +        float velocityMod = std::min<float>(distance / travelDist, 1.5f); + +        // Now we will always stay synch with our leader +        velocity *= velocityMod; +        _hasPredictedDestination = true; +    } +    else +    { +        // Formation leader is not moving. Just apply the base formation shape on his position. +        target->MovePositionToFirstCollision(dest, _range, _angle + relativeAngle); +        _hasPredictedDestination = false; +    } + +    // Leader is not moving, so just pick up his default walk speed +    if (velocity == 0.f) +        velocity = target->GetSpeed(MOVE_WALK); + +    Movement::MoveSplineInit init(owner); +    init.MoveTo(PositionToVector3(dest)); +    init.SetVelocity(velocity); +    init.Launch(); + +    _lastLeaderPosition = target->GetPosition(); +    owner->AddUnitState(UNIT_STATE_ROAMING_MOVE); +} +  void FormationMovementGenerator::DoDeactivate(Creature* owner)  {      AddFlag(MOVEMENTGENERATOR_FLAG_DEACTIVATED); @@ -155,5 +227,5 @@ void FormationMovementGenerator::DoFinalize(Creature* owner, bool active, bool m  void FormationMovementGenerator::MovementInform(Creature* owner)  {      if (owner->AI()) -        owner->AI()->MovementInform(FORMATION_MOTION_TYPE, _movementId); +        owner->AI()->MovementInform(FORMATION_MOTION_TYPE, 0);  } diff --git a/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.h index d00e6e3a73a..0b6d89b9b08 100644 --- a/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.h @@ -18,15 +18,17 @@  #ifndef TRINITY_FORMATIONMOVEMENTGENERATOR_H  #define TRINITY_FORMATIONMOVEMENTGENERATOR_H +#include "AbstractFollower.h"  #include "MovementGenerator.h"  #include "Position.h" +#include "Timer.h"  class Creature; -class FormationMovementGenerator : public MovementGeneratorMedium<Creature, FormationMovementGenerator> +class FormationMovementGenerator : public MovementGeneratorMedium<Creature, FormationMovementGenerator>, public AbstractFollower  {      public: -        explicit FormationMovementGenerator(uint32 id, Position destination, uint32 moveType, bool run, bool orientation); +        explicit FormationMovementGenerator(Unit* leader, float range, float angle, uint32 point1, uint32 point2);          MovementGeneratorType GetMovementGeneratorType() const override; @@ -36,16 +38,21 @@ class FormationMovementGenerator : public MovementGeneratorMedium<Creature, Form          void DoDeactivate(Creature*);          void DoFinalize(Creature*, bool, bool); -        void UnitSpeedChanged() override { AddFlag(MOVEMENTGENERATOR_FLAG_SPEED_UPDATE_PENDING); } -      private:          void MovementInform(Creature*); -        uint32 _movementId; -        Position _destination; -        uint32 _moveType; -        bool _run; -        bool _orientation; +        void LaunchMovement(Creature* owner, Unit* target); + +        static constexpr uint32 FORMATION_MOVEMENT_INTERVAL = 1200; // sniffed (3 batch update cycles) +        float const _range; +        float _angle; +        uint32 const _point1; +        uint32 const _point2; +        uint32 _lastLeaderSplineID; +        bool _hasPredictedDestination; + +        Position _lastLeaderPosition; +        TimeTrackerSmall _nextMoveTimer;  };  #endif // TRINITY_FORMATIONMOVEMENTGENERATOR_H diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index 817f7d58933..494e1aaa8e5 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -81,7 +81,7 @@ void PointMovementGenerator<T>::DoInitialize(T* owner)      // Call for creature group update      if (Creature* creature = owner->ToCreature()) -        creature->SignalFormationMovement(_destination, _movementId); +        creature->SignalFormationMovement();  }  template<class T> @@ -129,7 +129,7 @@ bool PointMovementGenerator<T>::DoUpdate(T* owner, uint32 /*diff*/)          // Call for creature group update          if (Creature* creature = owner->ToCreature()) -            creature->SignalFormationMovement(_destination, _movementId); +            creature->SignalFormationMovement();      }      if (owner->movespline->Finalized()) diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp index 464902624a6..2872683d58e 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp @@ -182,7 +182,7 @@ void RandomMovementGenerator<Creature>::SetRandomLocation(Creature* owner)      }      // Call for creature group update -    owner->SignalFormationMovement(position); +    owner->SignalFormationMovement();  }  template<class T> diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index 7d1fc1f133f..4278acc1841 100644 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -334,7 +334,6 @@ void WaypointMovementGenerator<Creature>::StartMove(Creature* owner, bool relaun      ASSERT(_currentNode < _path->nodes.size(), "WaypointMovementGenerator::StartMove: tried to reference a node id (%u) which is not included in path (%u)", _currentNode, _path->id);      WaypointNode const &waypoint = _path->nodes[_currentNode]; -    Position formationDest(waypoint.x, waypoint.y, waypoint.z, (waypoint.orientation && waypoint.delay) ? waypoint.orientation : 0.0f);      RemoveFlag(MOVEMENTGENERATOR_FLAG_TRANSITORY | MOVEMENTGENERATOR_FLAG_INFORM_ENABLED | MOVEMENTGENERATOR_FLAG_TIMED_PAUSED); @@ -344,15 +343,7 @@ void WaypointMovementGenerator<Creature>::StartMove(Creature* owner, bool relaun      //! If creature is on transport, we assume waypoints set in DB are already transport offsets      if (transportPath) -    {          init.DisableTransportPathTransformations(); -        if (TransportBase* trans = owner->GetDirectTransport()) -        { -            float orientation = formationDest.GetOrientation(); -            trans->CalculatePassengerPosition(formationDest.m_positionX, formationDest.m_positionY, formationDest.m_positionZ, &orientation); -            formationDest.SetOrientation(orientation); -        } -    }      //! Do not use formationDest here, MoveTo requires transport offsets due to DisableTransportPathTransformations() call      //! but formationDest contains global coordinates @@ -383,7 +374,7 @@ void WaypointMovementGenerator<Creature>::StartMove(Creature* owner, bool relaun      init.Launch();      // inform formation -    owner->SignalFormationMovement(formationDest, waypoint.id, waypoint.moveType, (waypoint.orientation && waypoint.delay) ? true : false); +    owner->SignalFormationMovement();  }  bool WaypointMovementGenerator<Creature>::ComputeNextNode() diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index 3b7939eb038..30618e96752 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -193,6 +193,8 @@ void MoveSpline::Initialize(MoveSplineInitArgs const& args)      anim_tier = args.animTier;      splineIsFacingOnly = args.path.size() == 2 && args.facing.type != MONSTER_MOVE_NORMAL && ((args.path[1] - args.path[0]).length() < 0.1f); +    velocity = args.velocity; +      // Check if its a stop spline      if (args.flags.done)      { @@ -223,7 +225,7 @@ void MoveSpline::Initialize(MoveSplineInitArgs const& args)  }  MoveSpline::MoveSpline() : m_Id(0), time_passed(0), -    vertical_acceleration(0.f), initialOrientation(0.f), effect_start_time(0), point_Idx(0), point_Idx_offset(0), +    vertical_acceleration(0.f), initialOrientation(0.f), effect_start_time(0), point_Idx(0), point_Idx_offset(0), velocity(0.f),      onTransport(false), splineIsFacingOnly(false)  {      splineflags.done = true; diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h index e9083eb6417..3eab8984260 100644 --- a/src/server/game/Movement/Spline/MoveSpline.h +++ b/src/server/game/Movement/Spline/MoveSpline.h @@ -80,6 +80,7 @@ namespace Movement          int32           effect_start_time;          int32           point_Idx;          int32           point_Idx_offset; +        float           velocity;          Optional<SpellEffectExtraData> spell_effect_extra;          Optional<AnimTierTransition> anim_tier; @@ -101,6 +102,7 @@ namespace Movement          int32 Duration() const { return spline.length(); }          MySpline const& _Spline() const { return spline; }          int32 _currentSplineIdx() const { return point_Idx; } +        float Velocity() const { return velocity; }          void _Finalize();          void _Interrupt() { splineflags.done = true; }  | 
