diff --git a/Source/Game/Movement/Generators/FlightPathMovementGenerator.cs b/Source/Game/Movement/Generators/FlightPathMovementGenerator.cs index 1b9c56fde..a73192996 100644 --- a/Source/Game/Movement/Generators/FlightPathMovementGenerator.cs +++ b/Source/Game/Movement/Generators/FlightPathMovementGenerator.cs @@ -63,7 +63,7 @@ namespace Game.Movement MoveSplineInit init = new(owner); // Providing a starting vertex since the taxi paths do not provide such init.Path().Add(new Vector3(owner.GetPositionX(), owner.GetPositionY(), owner.GetPositionZ())); - for (int i = (int)currentNodeId; i != (uint)end; ++i) + for (int i = (int)currentNodeId; i != end; ++i) { Vector3 vertice = new(_path[i].Loc.X, _path[i].Loc.Y, _path[i].Loc.Z); init.Path().Add(vertice); diff --git a/Source/Game/Movement/MoveSpline.cs b/Source/Game/Movement/MoveSpline.cs index 2b71671b8..fc0321e77 100644 --- a/Source/Game/Movement/MoveSpline.cs +++ b/Source/Game/Movement/MoveSpline.cs @@ -77,17 +77,17 @@ namespace Game.Movement void InitSpline(MoveSplineInitArgs args) { - EvaluationMode[] modes = new EvaluationMode[2] { EvaluationMode.Linear, EvaluationMode.Catmullrom }; + EvaluationMode mode = args.flags.IsSmooth() ? EvaluationMode.Catmullrom : EvaluationMode.Linear; if (args.flags.HasFlag(MoveSplineFlagEnum.Cyclic)) { int cyclic_point = 0; if (splineflags.HasFlag(MoveSplineFlagEnum.EnterCycle)) cyclic_point = 1; // shouldn't be modified, came from client - spline.InitCyclicSpline(args.path.ToArray(), args.path.Count, modes[Convert.ToInt32(args.flags.IsSmooth())], cyclic_point, args.initialOrientation); + spline.InitCyclicSpline(args.path.ToArray(), args.path.Count, mode, cyclic_point, args.initialOrientation); } else { - spline.InitSpline(args.path.ToArray(), args.path.Count, modes[Convert.ToInt32(args.flags.IsSmooth())], args.initialOrientation); + spline.InitSpline(args.path.ToArray(), args.path.Count, mode, args.initialOrientation); } // init spline timestamps @@ -290,34 +290,7 @@ namespace Game.Movement if (splineflags.HasFlag(MoveSplineFlagEnum.EnterCycle)) { splineflags.SetUnsetFlag(MoveSplineFlagEnum.EnterCycle, false); - - MoveSplineInitArgs args = new(spline.GetPointCount()); - args.path.AddRange(spline.GetPoints().AsSpan().Slice(spline.First() + 1, spline.Last()).ToArray()); - 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(null)) - { - // 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 = new(); - tempSpline.Initialize(args); - args.velocity = (float)tempSpline.Duration() / Duration(); - - if (args.Validate(null)) - InitSpline(args); - } + reinit_spline_for_next_cycle(); } } else @@ -331,6 +304,38 @@ namespace Game.Movement return result; } + + void reinit_spline_for_next_cycle() + { + MoveSplineInitArgs args = new(spline.GetPointCount()); + args.path.AddRange(spline.GetPoints().AsSpan().Slice(spline.First() + 1, spline.Last()).ToArray()); + 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(null)) + { + // 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 = new(); + tempSpline.Initialize(args); + args.velocity = (float)tempSpline.Duration() / Duration(); + + if (args.Validate(null)) + InitSpline(args); + } + } + int NextTimestamp() { return spline.Length(point_Idx + 1); } int SegmentTimeElapsed() { return NextTimestamp() - time_passed; } public bool IsCyclic() { return splineflags.HasFlag(MoveSplineFlagEnum.Cyclic); } diff --git a/Source/Game/Movement/MoveSplineInit.cs b/Source/Game/Movement/MoveSplineInit.cs index d80cbbf02..872a064f5 100644 --- a/Source/Game/Movement/MoveSplineInit.cs +++ b/Source/Game/Movement/MoveSplineInit.cs @@ -126,7 +126,7 @@ namespace Game.Movement return 50.0f; return Math.Max(28.0f, unit.GetSpeed(UnitMoveType.Run) * 4.0f); - }; + } args.velocity = Math.Min(args.velocity, speedLimit()); @@ -218,20 +218,8 @@ namespace Game.Movement public void SetFacing(float angle) { - if (args.TransformForTransport) - { - Unit vehicle = unit.GetVehicleBase(); - if (vehicle != null) - angle -= vehicle.GetOrientation(); - else - { - ITransport transport = unit.GetTransport(); - if (transport != null) - angle -= transport.GetTransportOrientation(); - } - } - - args.facing.angle = MathFunctions.wrap(angle, 0.0f, MathFunctions.TwoPi); + TransportPathTransform transform = new(unit, args.TransformForTransport); + args.facing.angle = Position.NormalizeOrientation(transform.Calc(angle)); args.facing.type = MonsterMoveType.FacingAngle; } @@ -288,12 +276,12 @@ namespace Game.Movement public void SetUnlimitedSpeed() { args.flags.SetUnsetFlag(MoveSplineFlagEnum.UnlimitedSpeed, true); } - public void MovebyPath(Vector3[] controls, int path_offset = 0) + public void MovebyPath(Vector3[] path, int pointId = 0) { - args.path_Idx_offset = path_offset; + args.path_Idx_offset = pointId; TransportPathTransform transform = new(unit, args.TransformForTransport); - for (var i = 0; i < controls.Length; i++) - args.path.Add(transform.Calc(controls[i])); + for (var i = 0; i < path.Length; i++) + args.path.Add(transform.Calc(path[i])); } @@ -302,17 +290,17 @@ namespace Game.Movement MoveTo(new Vector3(x, y, z), generatePath, forceDest); } - public void SetParabolic(float amplitude, float time_shift) + public void SetParabolic(float amplitude, float start_time) { - args.effect_start_time_percent = time_shift; + args.effect_start_time_percent = start_time; args.parabolic_amplitude = amplitude; args.vertical_acceleration = 0.0f; args.flags.EnableParabolic(); } - public void SetParabolicVerticalAcceleration(float vertical_acceleration, float time_shift) + public void SetParabolicVerticalAcceleration(float vertical_acceleration, float start_time) { - args.effect_start_time_percent = time_shift; + args.effect_start_time_percent = start_time; args.parabolic_amplitude = 0.0f; args.vertical_acceleration = vertical_acceleration; args.flags.EnableParabolic(); @@ -345,30 +333,28 @@ namespace Game.Movement // Transforms coordinates from global to transport offsets public class TransportPathTransform { + ITransport _transport; + public TransportPathTransform(Unit owner, bool transformForTransport) { - _owner = owner; - _transformForTransport = transformForTransport; + _transport = transformForTransport ? owner.GetDirectTransport() : null; } public Vector3 Calc(Vector3 input) { - float x = input.X; - float y = input.Y; - float z = input.Z; - if (_transformForTransport) - { - ITransport transport = _owner.GetDirectTransport(); - if (transport != null) - { - float unused = 0.0f; // need reference - transport.CalculatePassengerOffset(ref x, ref y, ref z, ref unused); - } - } - return new Vector3(x, y, z); + float o = 0; + if (_transport != null) + _transport.CalculatePassengerOffset(ref input.X, ref input.Y, ref input.Z, ref o); + + return input; } - Unit _owner; - bool _transformForTransport; + public float Calc(float input) + { + if (_transport != null) + input -= _transport.GetTransportOrientation(); + + return input; + } } }