diff --git a/Source/Game/Movement/MotionMaster.cs b/Source/Game/Movement/MotionMaster.cs index 5b655e406..6d488dcea 100644 --- a/Source/Game/Movement/MotionMaster.cs +++ b/Source/Game/Movement/MotionMaster.cs @@ -736,6 +736,38 @@ namespace Game.Movement Add(movement); } + void MoveJumpWithGravity(Position pos, float speedXY, float gravity, uint id = EventId.Jump, bool hasOrientation = false, JumpArrivalCastArgs arrivalCast = null, SpellEffectExtraData spellEffectExtraData = null) + { + Log.outDebug(LogFilter.Movement, $"MotionMaster.MoveJumpWithGravity: '{_owner.GetGUID()}', jumps to point Id: {id} ({pos})"); + if (speedXY < 0.01f) + return; + + MoveSplineInit init = new(_owner); + init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), false); + init.SetParabolicVerticalAcceleration(gravity, 0); + init.SetUncompressed(); + init.SetVelocity(speedXY); + + if (hasOrientation) + init.SetFacing(pos.GetOrientation()); + + if (spellEffectExtraData != null) + init.SetSpellEffectExtraData(spellEffectExtraData); + + uint arrivalSpellId = 0; + ObjectGuid arrivalSpellTargetGuid = default; + if (arrivalCast != null) + { + arrivalSpellId = arrivalCast.SpellId; + arrivalSpellTargetGuid = arrivalCast.Target; + } + + GenericMovementGenerator movement = new GenericMovementGenerator(init, MovementGeneratorType.Effect, id, arrivalSpellId, arrivalSpellTargetGuid); + movement.Priority = MovementGeneratorPriority.Highest; + movement.BaseUnitState = UnitState.Jumping; + Add(movement); + } + public void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, byte stepCount) { float step = 2 * MathFunctions.PI / stepCount * (clockwise ? -1.0f : 1.0f); diff --git a/Source/Game/Movement/MoveSpline.cs b/Source/Game/Movement/MoveSpline.cs index 154386493..632ffd7ce 100644 --- a/Source/Game/Movement/MoveSpline.cs +++ b/Source/Game/Movement/MoveSpline.cs @@ -70,8 +70,15 @@ namespace Game.Movement effect_start_time = (int)(Duration() * args.time_perc); if (args.flags.HasFlag(SplineFlag.Parabolic) && effect_start_time < Duration()) { - float f_duration = (float)TimeSpan.FromMilliseconds(Duration() - effect_start_time).TotalSeconds; - vertical_acceleration = args.parabolic_amplitude * 8.0f / (f_duration * f_duration); + if (args.parabolic_amplitude != 0.0f) + { + float f_duration = MSToSec((uint)(Duration() - effect_start_time)); + vertical_acceleration = args.parabolic_amplitude * 8.0f / (f_duration * f_duration); + } + else if (args.vertical_acceleration != 0.0f) + { + vertical_acceleration = args.vertical_acceleration; + } } } } diff --git a/Source/Game/Movement/MoveSplineInit.cs b/Source/Game/Movement/MoveSplineInit.cs index 27e627554..da3bb115c 100644 --- a/Source/Game/Movement/MoveSplineInit.cs +++ b/Source/Game/Movement/MoveSplineInit.cs @@ -293,6 +293,15 @@ namespace Game.Movement { args.time_perc = time_shift; args.parabolic_amplitude = amplitude; + args.vertical_acceleration = 0.0f; + args.flags.EnableParabolic(); + } + + public void SetParabolicVerticalAcceleration(float vertical_acceleration, float time_shift) + { + args.time_perc = time_shift; + args.parabolic_amplitude = 0.0f; + args.vertical_acceleration = vertical_acceleration; args.flags.EnableParabolic(); } diff --git a/Source/Game/Movement/MoveSplineInitArgs.cs b/Source/Game/Movement/MoveSplineInitArgs.cs index de9db7c60..fadaa2a67 100644 --- a/Source/Game/Movement/MoveSplineInitArgs.cs +++ b/Source/Game/Movement/MoveSplineInitArgs.cs @@ -42,6 +42,7 @@ namespace Game.Movement public int path_Idx_offset; public float velocity; public float parabolic_amplitude; + public float vertical_acceleration; public float time_perc; public uint splineId; public float initialOrientation; diff --git a/Source/Game/Networking/Packets/MovementPackets.cs b/Source/Game/Networking/Packets/MovementPackets.cs index 8249fcf02..361996da6 100644 --- a/Source/Game/Networking/Packets/MovementPackets.cs +++ b/Source/Game/Networking/Packets/MovementPackets.cs @@ -208,7 +208,7 @@ namespace Game.Networking.Packets data.WriteBits(moveSpline.GetPath().Length, 16); data.WriteBit(false); // HasSplineFilter data.WriteBit(moveSpline.spell_effect_extra.HasValue); // HasSpellEffectExtraData - data.WriteBit(moveSpline.splineflags.HasFlag(SplineFlag.Parabolic)); // HasJumpExtraData + bool hasJumpExtraData = data.WriteBit(moveSpline.splineflags.HasFlag(SplineFlag.Parabolic) && (!moveSpline.spell_effect_extra.HasValue || moveSpline.effect_start_time != 0)); data.WriteBit(moveSpline.anim_tier.HasValue); // HasAnimationTierTransition data.WriteBit(false); // HasUnknown901 data.FlushBits(); @@ -253,7 +253,7 @@ namespace Game.Networking.Packets data.WriteUInt32(moveSpline.spell_effect_extra.Value.ParabolicCurveId); } - if (moveSpline.splineflags.HasFlag(SplineFlag.Parabolic)) + if (hasJumpExtraData) { data.WriteFloat(moveSpline.vertical_acceleration); data.WriteInt32(moveSpline.effect_start_time); @@ -385,7 +385,7 @@ namespace Game.Networking.Packets movementSpline.MoveTime = (uint)moveSpline.Duration(); - if (splineFlags.HasFlag(SplineFlag.Parabolic)) + if (splineFlags.HasFlag(SplineFlag.Parabolic) && (!moveSpline.spell_effect_extra.HasValue || moveSpline.effect_start_time != 0)) { movementSpline.JumpExtraData.HasValue = true; movementSpline.JumpExtraData.Value.JumpGravity = moveSpline.vertical_acceleration;