aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp21
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
-rw-r--r--src/server/game/Movement/MotionMaster.cpp3
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.cpp40
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.h2
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.cpp3
-rw-r--r--src/server/game/Server/Packets/MovementPackets.cpp8
-rw-r--r--src/server/game/Server/Packets/MovementPackets.h11
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
9 files changed, 79 insertions, 13 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 333f2760a68..9a7bd88076d 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -517,19 +517,28 @@ void Unit::UpdateSplineMovement(uint32 t_diff)
movespline->updateState(t_diff);
bool arrived = movespline->Finalized();
+ if (movespline->isCyclic())
+ {
+ m_splineSyncTimer.Update(t_diff);
+ if (m_splineSyncTimer.Passed())
+ {
+ m_splineSyncTimer.Reset(5000); // Retail value, do not change
+
+ WorldPackets::Movement::FlightSplineSync flightSplineSync;
+ flightSplineSync.Guid = GetGUID();
+ flightSplineSync.SplineDist = movespline->timePassed() / movespline->Duration();
+ SendMessageToSet(flightSplineSync.Write(), true);
+ }
+ }
+
if (arrived)
DisableSpline();
- m_movesplineTimer.Update(t_diff);
- if (m_movesplineTimer.Passed() || arrived)
- UpdateSplinePosition();
+ UpdateSplinePosition();
}
void Unit::UpdateSplinePosition()
{
- static uint32 const positionUpdateDelay = 400;
-
- m_movesplineTimer.Reset(positionUpdateDelay);
Movement::Location loc = movespline->ComputePosition();
if (movespline->onTransport)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 9a8d2108e3f..10a1108f6b9 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1975,7 +1975,7 @@ class TC_GAME_API Unit : public WorldObject
private:
uint32 m_state; // Even derived shouldn't modify
- TimeTrackerSmall m_movesplineTimer;
+ TimeTrackerSmall m_splineSyncTimer;
Diminishing m_Diminishing;
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index a1ca939c1b4..28c991a3c8d 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -859,6 +859,9 @@ void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool
Movement::MoveSplineInit init(_owner);
+ // 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()));
+
for (uint8 i = 0; i < stepCount; angle += step, ++i)
{
G3D::Vector3 point;
diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp
index d2298b8536c..ccfc40eb67d 100644
--- a/src/server/game/Movement/Spline/MoveSpline.cpp
+++ b/src/server/game/Movement/Spline/MoveSpline.cpp
@@ -150,9 +150,8 @@ void MoveSpline::init_spline(MoveSplineInitArgs const& args)
if (args.flags.cyclic)
{
uint32 cyclic_point = 0;
- // MoveSplineFlag::Enter_Cycle support dropped
- //if (splineflags & SPLINEFLAG_ENTER_CYCLE)
- //cyclic_point = 1; // shouldn't be modified, came from client
+ if (splineflags.enter_cycle)
+ cyclic_point = 1; // shouldn't be modified, came from client
spline.init_cyclic_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()], cyclic_point, args.initialOrientation);
}
else
@@ -304,6 +303,41 @@ MoveSpline::UpdateResult MoveSpline::_updateState(int32& ms_time_diff)
point_Idx = spline.first();
time_passed = time_passed % Duration();
result = Result_NextCycle;
+
+ // Remove first point from the path after one full cycle.
+ // That point was the position of the unit prior to entering the cycle and it shouldn't be repeated with continuous cycles.
+ if (splineflags.enter_cycle)
+ {
+ splineflags.enter_cycle = false;
+
+ MoveSplineInitArgs args{ (size_t)spline.getPointCount() };
+ args.path.assign(spline.getPoints().begin() + spline.first() + 1, spline.getPoints().begin() + spline.last());
+ args.facing = facing;
+ args.flags = splineflags;
+ args.path_Idx_offset = point_Idx_offset;
+ // MoveSplineFlag::Parabolic | MoveSplineFlag::Animation not supported currently
+ //args.parabolic_amplitude = ?;
+ //args.time_perc = ?;
+ args.splineId = m_Id;
+ args.initialOrientation = initialOrientation;
+ args.velocity = 1.0f; // Calculated below
+ args.HasVelocity = true;
+ args.TransformForTransport = onTransport;
+ if (args.Validate(nullptr))
+ {
+ // New cycle should preserve previous cycle's duration for some weird reason, even though
+ // the path is really different now. Blizzard is weird. Or this was just a simple oversight.
+ // Since our splines precalculate length with velocity in mind, if we want to find the desired
+ // velocity, we have to make a fake spline, calculate its duration and then compare it to the
+ // desired duration, thus finding out how much the velocity has to be increased for them to match.
+ MoveSpline tempSpline;
+ tempSpline.Initialize(args);
+ args.velocity = (float)tempSpline.Duration() / Duration();
+
+ if (args.Validate(nullptr))
+ init_spline(args);
+ }
+ }
}
else
{
diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h
index 20265e23312..e9083eb6417 100644
--- a/src/server/game/Movement/Spline/MoveSpline.h
+++ b/src/server/game/Movement/Spline/MoveSpline.h
@@ -95,9 +95,9 @@ namespace Movement
int32 next_timestamp() const { return spline.length(point_Idx + 1); }
int32 segment_time_elapsed() const { return next_timestamp() - time_passed; }
int32 timeElapsed() const { return Duration() - time_passed; }
- int32 timePassed() const { return time_passed; }
public:
+ int32 timePassed() const { return time_passed; }
int32 Duration() const { return spline.length(); }
MySpline const& _Spline() const { return spline; }
int32 _currentSplineIdx() const { return point_Idx; }
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp
index 2757cc933a8..4f68c03bcd8 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.cpp
+++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp
@@ -86,7 +86,8 @@ namespace Movement
// correct first vertex
args.path[0] = real_position;
args.initialOrientation = real_position.orientation;
- move_spline.onTransport = !unit->GetTransGUID().IsEmpty();
+ args.flags.enter_cycle = args.flags.cyclic;
+ move_spline.onTransport = transport;
uint32 moveFlags = unit->m_movementInfo.GetMovementFlags();
if (!args.flags.backward)
diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp
index c18c3ea5e1a..8bc93a75a74 100644
--- a/src/server/game/Server/Packets/MovementPackets.cpp
+++ b/src/server/game/Server/Packets/MovementPackets.cpp
@@ -568,6 +568,14 @@ WorldPacket const* WorldPackets::Movement::MonsterMove::Write()
return &_worldPacket;
}
+WorldPacket const* WorldPackets::Movement::FlightSplineSync::Write()
+{
+ _worldPacket << Guid;
+ _worldPacket << float(SplineDist);
+
+ return &_worldPacket;
+}
+
WorldPacket const* WorldPackets::Movement::MoveSplineSetSpeed::Write()
{
_worldPacket << MoverGUID;
diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h
index 18936d9773a..73310a9e023 100644
--- a/src/server/game/Server/Packets/MovementPackets.h
+++ b/src/server/game/Server/Packets/MovementPackets.h
@@ -168,6 +168,17 @@ namespace WorldPackets
TaggedPosition<Position::XYZ> Pos;
};
+ class FlightSplineSync final : public ServerPacket
+ {
+ public:
+ FlightSplineSync() : ServerPacket(SMSG_FLIGHT_SPLINE_SYNC, 16 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Guid;
+ float SplineDist = 0.0f;
+ };
+
class MoveSplineSetSpeed : public ServerPacket
{
public:
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 57ab5a4cee1..ea17f2ffdd7 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -1252,7 +1252,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FEIGN_DEATH_RESISTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FISH_ESCAPED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FISH_NOT_HOOKED, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FLIGHT_SPLINE_SYNC, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FLIGHT_SPLINE_SYNC, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCED_DEATH_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_ANIMATIONS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);