diff options
author | NoName <322016+Faq@users.noreply.github.com> | 2020-02-28 20:03:52 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-12-22 14:33:58 +0100 |
commit | 61f3d51143b51b04169bd1c2ff0393d2b9be7c33 (patch) | |
tree | 2f785946aa0861ccb30181d839c4f2812ffd1996 /src/server | |
parent | 94f7d2fb49c9c9f1d2e7dc3a4fe2a368d830404f (diff) |
Core/Movement: Implement MoveSplineFlag::Enter_Cycle (#24049)
by xvwyh
(cherry picked from commit 40542f01e3fec0bff2c6e5eadbe20e58f19b0fd8)
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 21 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 | ||||
-rw-r--r-- | src/server/game/Movement/MotionMaster.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Movement/Spline/MoveSpline.cpp | 40 | ||||
-rw-r--r-- | src/server/game/Movement/Spline/MoveSpline.h | 2 | ||||
-rw-r--r-- | src/server/game/Movement/Spline/MoveSplineInit.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MovementPackets.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MovementPackets.h | 11 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 2 |
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); |