aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp4
-rw-r--r--src/server/game/Entities/Creature/Creature.h2
-rw-r--r--src/server/game/Entities/Creature/CreatureGroups.cpp39
-rw-r--r--src/server/game/Entities/Creature/CreatureGroups.h2
-rw-r--r--src/server/game/Movement/MotionMaster.cpp8
-rw-r--r--src/server/game/Movement/MotionMaster.h2
-rw-r--r--src/server/game/Movement/MovementGenerators/FormationMovementGenerator.cpp188
-rw-r--r--src/server/game/Movement/MovementGenerators/FormationMovementGenerator.h25
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp4
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp2
-rw-r--r--src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp11
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.cpp4
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.h2
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; }