aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Movement
diff options
context:
space:
mode:
authorNoName <322016+Faq@users.noreply.github.com>2020-02-28 20:03:52 +0200
committerShauren <shauren.trinity@gmail.com>2021-12-22 14:33:58 +0100
commit61f3d51143b51b04169bd1c2ff0393d2b9be7c33 (patch)
tree2f785946aa0861ccb30181d839c4f2812ffd1996 /src/server/game/Movement
parent94f7d2fb49c9c9f1d2e7dc3a4fe2a368d830404f (diff)
Core/Movement: Implement MoveSplineFlag::Enter_Cycle (#24049)
by xvwyh (cherry picked from commit 40542f01e3fec0bff2c6e5eadbe20e58f19b0fd8)
Diffstat (limited to 'src/server/game/Movement')
-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
4 files changed, 43 insertions, 5 deletions
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)