From be74f514a1a2b91bd48c514bec296ad7569c9826 Mon Sep 17 00:00:00 2001 From: Hondacrx Date: Sun, 10 Nov 2024 18:24:49 -0500 Subject: [PATCH] Core/Movement: Store adv flying speeds instead of hardcoding them in SMSG_UPDATE_OBJECT and enable packets modifying them Port From (https://github.com/TrinityCore/TrinityCore/commit/43c7965d6b97a919ddd7e97a1f6e3f5750553f09) --- Source/Framework/Constants/UnitConst.cs | 22 ++++ Source/Game/Entities/Object/WorldObject.cs | 34 +++--- Source/Game/Entities/Unit/Unit.Fields.cs | 1 + Source/Game/Entities/Unit/Unit.Movement.cs | 107 +++++++++++++++++- Source/Game/Entities/Unit/Unit.cs | 2 + Source/Game/Handlers/MovementHandler.cs | 23 ++++ .../Networking/Packets/MovementPackets.cs | 60 +++++++++- 7 files changed, 226 insertions(+), 23 deletions(-) diff --git a/Source/Framework/Constants/UnitConst.cs b/Source/Framework/Constants/UnitConst.cs index 981b9e5dd..196b6f6c3 100644 --- a/Source/Framework/Constants/UnitConst.cs +++ b/Source/Framework/Constants/UnitConst.cs @@ -112,6 +112,28 @@ namespace Framework.Constants End } + public enum AdvFlyingRateTypeSingle + { + AirFriction = 0, + MaxVel = 1, + LiftCoefficient = 2, + DoubleJumpVelMod = 3, + GlideStartMinHeight = 4, + AddImpulseMaxSpeed = 5, + SurfaceFriction = 14, + OverMaxDeceleration = 15, + LaunchSpeedCoefficient = 16, + Max = 17 + } + + public enum AdvFlyingRateTypeRange + { + BankingRate = 6, + PitchingRateDown = 8, + PitchingRateUp = 10, + TurnVelocityThreshold = 12 + } + public enum DamageEffectType { Direct = 0, // used for normal weapon damage (not for class abilities or spells) diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index 7156ba5d5..74ccbbb34 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -355,23 +355,23 @@ namespace Game.Entities data.WriteFloat(1.0f); // MovementForcesModMagnitude } - data.WriteFloat(2.0f); // advFlyingAirFriction - data.WriteFloat(65.0f); // advFlyingMaxVel - data.WriteFloat(1.0f); // advFlyingLiftCoefficient - data.WriteFloat(3.0f); // advFlyingDoubleJumpVelMod - data.WriteFloat(10.0f); // advFlyingGlideStartMinHeight - data.WriteFloat(100.0f); // advFlyingAddImpulseMaxSpeed - data.WriteFloat(90.0f); // advFlyingMinBankingRate - data.WriteFloat(140.0f); // advFlyingMaxBankingRate - data.WriteFloat(180.0f); // advFlyingMinPitchingRateDown - data.WriteFloat(360.0f); // advFlyingMaxPitchingRateDown - data.WriteFloat(90.0f); // advFlyingMinPitchingRateUp - data.WriteFloat(270.0f); // advFlyingMaxPitchingRateUp - data.WriteFloat(30.0f); // advFlyingMinTurnVelocityThreshold - data.WriteFloat(80.0f); // advFlyingMaxTurnVelocityThreshold - data.WriteFloat(2.75f); // advFlyingSurfaceFriction - data.WriteFloat(7.0f); // advFlyingOverMaxDeceleration - data.WriteFloat(0.4f); // advFlyingLaunchSpeedCoefficient + data.WriteFloat(unit.GetAdvFlyingSpeed(AdvFlyingRateTypeSingle.AirFriction)); + data.WriteFloat(unit.GetAdvFlyingSpeed(AdvFlyingRateTypeSingle.MaxVel)); + data.WriteFloat(unit.GetAdvFlyingSpeed(AdvFlyingRateTypeSingle.LiftCoefficient)); + data.WriteFloat(unit.GetAdvFlyingSpeed(AdvFlyingRateTypeSingle.DoubleJumpVelMod)); + data.WriteFloat(unit.GetAdvFlyingSpeed(AdvFlyingRateTypeSingle.GlideStartMinHeight)); + data.WriteFloat(unit.GetAdvFlyingSpeed(AdvFlyingRateTypeSingle.AddImpulseMaxSpeed)); + data.WriteFloat(unit.GetAdvFlyingSpeedMin(AdvFlyingRateTypeRange.BankingRate)); + data.WriteFloat(unit.GetAdvFlyingSpeedMax(AdvFlyingRateTypeRange.BankingRate)); + data.WriteFloat(unit.GetAdvFlyingSpeedMin(AdvFlyingRateTypeRange.PitchingRateDown)); + data.WriteFloat(unit.GetAdvFlyingSpeedMax(AdvFlyingRateTypeRange.PitchingRateDown)); + data.WriteFloat(unit.GetAdvFlyingSpeedMin(AdvFlyingRateTypeRange.PitchingRateUp)); + data.WriteFloat(unit.GetAdvFlyingSpeedMax(AdvFlyingRateTypeRange.PitchingRateUp)); + data.WriteFloat(unit.GetAdvFlyingSpeedMin(AdvFlyingRateTypeRange.TurnVelocityThreshold)); + data.WriteFloat(unit.GetAdvFlyingSpeedMax(AdvFlyingRateTypeRange.TurnVelocityThreshold)); + data.WriteFloat(unit.GetAdvFlyingSpeed(AdvFlyingRateTypeSingle.SurfaceFriction)); + data.WriteFloat(unit.GetAdvFlyingSpeed(AdvFlyingRateTypeSingle.OverMaxDeceleration)); + data.WriteFloat(unit.GetAdvFlyingSpeed(AdvFlyingRateTypeSingle.LaunchSpeedCoefficient)); data.WriteBit(HasSpline); data.FlushBits(); diff --git a/Source/Game/Entities/Unit/Unit.Fields.cs b/Source/Game/Entities/Unit/Unit.Fields.cs index 919102a54..7d2a69101 100644 --- a/Source/Game/Entities/Unit/Unit.Fields.cs +++ b/Source/Game/Entities/Unit/Unit.Fields.cs @@ -23,6 +23,7 @@ namespace Game.Entities //Movement protected float[] m_speed_rate = new float[(int)UnitMoveType.Max]; + float[] m_advFlyingSpeed = new float[(int)AdvFlyingRateTypeSingle.Max]; List m_followingMe = new(); public MoveSpline MoveSpline { get; set; } MotionMaster i_motionMaster; diff --git a/Source/Game/Entities/Unit/Unit.Movement.cs b/Source/Game/Entities/Unit/Unit.Movement.cs index 8435d276d..5a76c85a0 100644 --- a/Source/Game/Entities/Unit/Unit.Movement.cs +++ b/Source/Game/Entities/Unit/Unit.Movement.cs @@ -154,6 +154,111 @@ namespace Game.Entities public float GetSpeedRate(UnitMoveType mtype) { return m_speed_rate[(int)mtype]; } + void SetFlightCapabilityID(int flightCapabilityId, bool clientUpdate) + { + if (flightCapabilityId != 0 && !CliDB.FlightCapabilityStorage.HasRecord((uint)flightCapabilityId)) + return; + + SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.FlightCapabilityID), flightCapabilityId); + + UpdateAdvFlyingSpeed(AdvFlyingRateTypeSingle.AirFriction, clientUpdate); + UpdateAdvFlyingSpeed(AdvFlyingRateTypeSingle.MaxVel, clientUpdate); + UpdateAdvFlyingSpeed(AdvFlyingRateTypeSingle.LiftCoefficient, clientUpdate); + UpdateAdvFlyingSpeed(AdvFlyingRateTypeSingle.DoubleJumpVelMod, clientUpdate); + UpdateAdvFlyingSpeed(AdvFlyingRateTypeSingle.GlideStartMinHeight, clientUpdate); + UpdateAdvFlyingSpeed(AdvFlyingRateTypeSingle.AddImpulseMaxSpeed, clientUpdate); + UpdateAdvFlyingSpeed(AdvFlyingRateTypeRange.BankingRate, clientUpdate); + UpdateAdvFlyingSpeed(AdvFlyingRateTypeRange.PitchingRateDown, clientUpdate); + UpdateAdvFlyingSpeed(AdvFlyingRateTypeRange.PitchingRateUp, clientUpdate); + UpdateAdvFlyingSpeed(AdvFlyingRateTypeRange.TurnVelocityThreshold, clientUpdate); + UpdateAdvFlyingSpeed(AdvFlyingRateTypeSingle.SurfaceFriction, clientUpdate); + UpdateAdvFlyingSpeed(AdvFlyingRateTypeSingle.OverMaxDeceleration, clientUpdate); + UpdateAdvFlyingSpeed(AdvFlyingRateTypeSingle.LaunchSpeedCoefficient, clientUpdate); + } + + void UpdateAdvFlyingSpeed(AdvFlyingRateTypeSingle speedType, bool clientUpdate) + { + FlightCapabilityRecord flightCapabilityEntry = CliDB.FlightCapabilityStorage.LookupByKey(GetFlightCapabilityID()); + if (flightCapabilityEntry == null) + flightCapabilityEntry = CliDB.FlightCapabilityStorage.LookupByKey(1); + + (ServerOpcodes opcode, float newValue) = speedType switch + { + AdvFlyingRateTypeSingle.AirFriction => (ServerOpcodes.MoveSetAdvFlyingAirFriction, flightCapabilityEntry.AirFriction), + AdvFlyingRateTypeSingle.MaxVel => (ServerOpcodes.MoveSetAdvFlyingMaxVel, flightCapabilityEntry.MaxVel), + AdvFlyingRateTypeSingle.LiftCoefficient => (ServerOpcodes.MoveSetAdvFlyingLiftCoefficient, flightCapabilityEntry.LiftCoefficient), + AdvFlyingRateTypeSingle.DoubleJumpVelMod => (ServerOpcodes.MoveSetAdvFlyingDoubleJumpVelMod, flightCapabilityEntry.DoubleJumpVelMod), + AdvFlyingRateTypeSingle.GlideStartMinHeight => (ServerOpcodes.MoveSetAdvFlyingGlideStartMinHeight, flightCapabilityEntry.GlideStartMinHeight), + AdvFlyingRateTypeSingle.AddImpulseMaxSpeed => (ServerOpcodes.MoveSetAdvFlyingAddImpulseMaxSpeed, flightCapabilityEntry.AddImpulseMaxSpeed), + AdvFlyingRateTypeSingle.SurfaceFriction => (ServerOpcodes.MoveSetAdvFlyingSurfaceFriction, flightCapabilityEntry.SurfaceFriction), + AdvFlyingRateTypeSingle.OverMaxDeceleration => (ServerOpcodes.MoveSetAdvFlyingOverMaxDeceleration, flightCapabilityEntry.OverMaxDeceleration), + AdvFlyingRateTypeSingle.LaunchSpeedCoefficient => (ServerOpcodes.MoveSetAdvFlyingLaunchSpeedCoefficient, flightCapabilityEntry.LaunchSpeedCoefficient), + _ => (ServerOpcodes.Max, 0) + }; + + if (m_advFlyingSpeed[(int)speedType] == newValue) + return; + + m_advFlyingSpeed[(int)speedType] = newValue; + + if (!clientUpdate) + return; + + Player playerMover = GetUnitBeingMoved()?.ToPlayer(); + if (playerMover != null) + { + SetAdvFlyingSpeed selfpacket = new(opcode); + selfpacket.MoverGUID = GetGUID(); + selfpacket.SequenceIndex = m_movementCounter++; + selfpacket.Speed = newValue; + playerMover.GetSession().SendPacket(selfpacket); + } + } + + void UpdateAdvFlyingSpeed(AdvFlyingRateTypeRange speedType, bool clientUpdate) + { + FlightCapabilityRecord flightCapabilityEntry = CliDB.FlightCapabilityStorage.LookupByKey(GetFlightCapabilityID()); + if (flightCapabilityEntry == null) + flightCapabilityEntry = CliDB.FlightCapabilityStorage.LookupByKey(1); + + (ServerOpcodes opcode, float min, float max) = speedType switch + { + AdvFlyingRateTypeRange.BankingRate => (ServerOpcodes.MoveSetAdvFlyingBankingRate, flightCapabilityEntry.BankingRateMin, flightCapabilityEntry.BankingRateMax), + AdvFlyingRateTypeRange.PitchingRateDown => (ServerOpcodes.MoveSetAdvFlyingPitchingRateDown, flightCapabilityEntry.PitchingRateDownMin, flightCapabilityEntry.PitchingRateDownMax), + AdvFlyingRateTypeRange.PitchingRateUp => (ServerOpcodes.MoveSetAdvFlyingPitchingRateUp, flightCapabilityEntry.PitchingRateUpMin, flightCapabilityEntry.PitchingRateUpMax), + AdvFlyingRateTypeRange.TurnVelocityThreshold => (ServerOpcodes.MoveSetAdvFlyingTurnVelocityThreshold, flightCapabilityEntry.TurnVelocityThresholdMin, flightCapabilityEntry.TurnVelocityThresholdMax), + _ => (ServerOpcodes.Max, 0, 0) + }; + + if (m_advFlyingSpeed[(int)speedType] == min && m_advFlyingSpeed[(int)speedType + 1] == max) + return; + + m_advFlyingSpeed[(int)speedType] = min; + m_advFlyingSpeed[(int)speedType + 1] = max; + + if (!clientUpdate) + return; + + Player playerMover = GetUnitBeingMoved()?.ToPlayer(); + if (playerMover != null) + { + SetAdvFlyingSpeedRange selfpacket = new(opcode); + selfpacket.MoverGUID = GetGUID(); + selfpacket.SequenceIndex = m_movementCounter++; + selfpacket.SpeedMin = min; + selfpacket.SpeedMax = max; + playerMover.GetSession().SendPacket(selfpacket); + } + } + + int GetFlightCapabilityID() { return m_unitData.FlightCapabilityID; } + + public float GetAdvFlyingSpeed(AdvFlyingRateTypeSingle speedType) { return m_advFlyingSpeed[(int)speedType]; } + + public float GetAdvFlyingSpeedMin(AdvFlyingRateTypeRange speedType) { return m_advFlyingSpeed[(int)speedType]; } + + public float GetAdvFlyingSpeedMax(AdvFlyingRateTypeRange speedType) { return m_advFlyingSpeed[(int)speedType + 1]; } + public virtual MovementGeneratorType GetDefaultMovementType() { return MovementGeneratorType.Idle; @@ -254,7 +359,7 @@ namespace Game.Entities init.DisableTransportPathTransformations(); // It makes no sense to target global orientation init.SetFacing(point.GetPositionX(), point.GetPositionY(), point.GetPositionZ()); - //GetMotionMaster()->LaunchMoveSpline(std::move(init), EVENT_FACE, MOTION_PRIORITY_HIGHEST); + //GetMotionMaster().LaunchMoveSpline(std::move(init), EVENT_FACE, MOTION_PRIORITY_HIGHEST); UpdateSplineMovement((uint)init.Launch()); Creature creature = ToCreature(); if (creature != null) diff --git a/Source/Game/Entities/Unit/Unit.cs b/Source/Game/Entities/Unit/Unit.cs index fdaccd54d..023decb44 100644 --- a/Source/Game/Entities/Unit/Unit.cs +++ b/Source/Game/Entities/Unit/Unit.cs @@ -68,6 +68,8 @@ namespace Game.Entities for (byte i = 0; i < (int)UnitMoveType.Max; ++i) m_speed_rate[i] = 1.0f; + SetFlightCapabilityID(0, false); + m_serverSideVisibility.SetValue(ServerSideVisibilityType.Ghost, GhostVisibilityType.Alive); m_unitData = new UnitData(); diff --git a/Source/Game/Handlers/MovementHandler.cs b/Source/Game/Handlers/MovementHandler.cs index 34c575542..f0f74982c 100644 --- a/Source/Game/Handlers/MovementHandler.cs +++ b/Source/Game/Handlers/MovementHandler.cs @@ -607,6 +607,29 @@ namespace Game } } + [WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingAddImpulseMaxSpeedAck)] + [WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingAirFrictionAck)] + [WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingDoubleJumpVelModAck)] + [WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingGlideStartMinHeightAck)] + [WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingLaunchSpeedCoefficientAck)] + [WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingLiftCoefficientAck)] + [WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingMaxVelAck)] + [WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingOverMaxDecelerationAck)] + [WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingSurfaceFrictionAck)] + void HandleSetAdvFlyingSpeedAck(MovementSpeedAck speedAck) + { + GetPlayer().ValidateMovementInfo(speedAck.Ack.Status); + } + + [WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingBankingRateAck)] + [WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingPitchingRateDownAck)] + [WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingPitchingRateUpAck)] + [WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingTurnVelocityThresholdAck)] + void HandleSetAdvFlyingSpeedRangeAck(MovementSpeedRangeAck speedRangeAck) + { + GetPlayer().ValidateMovementInfo(speedRangeAck.Ack.Status); + } + [WorldPacketHandler(ClientOpcodes.SetActiveMover)] void HandleSetActiveMover(SetActiveMover packet) { diff --git a/Source/Game/Networking/Packets/MovementPackets.cs b/Source/Game/Networking/Packets/MovementPackets.cs index 28601f5f9..b7baa1e07 100644 --- a/Source/Game/Networking/Packets/MovementPackets.cs +++ b/Source/Game/Networking/Packets/MovementPackets.cs @@ -532,6 +532,40 @@ namespace Game.Networking.Packets public float Speed = 1.0f; } + class SetAdvFlyingSpeed : ServerPacket + { + public ObjectGuid MoverGUID; + public uint SequenceIndex; + public float Speed = 1.0f; + + public SetAdvFlyingSpeed(ServerOpcodes opcode) : base(opcode) { } + + public override void Write() + { + _worldPacket.WritePackedGuid(MoverGUID); + _worldPacket.WriteUInt32(SequenceIndex); + _worldPacket.WriteFloat(Speed); + } + } + + class SetAdvFlyingSpeedRange : ServerPacket + { + public ObjectGuid MoverGUID; + public uint SequenceIndex; + public float SpeedMin = 1.0f; + public float SpeedMax = 1.0f; + + public SetAdvFlyingSpeedRange(ServerOpcodes opcode) : base(opcode) { } + + public override void Write() + { + _worldPacket.WritePackedGuid(MoverGUID); + _worldPacket.WriteUInt32(SequenceIndex); + _worldPacket.WriteFloat(SpeedMin); + _worldPacket.WriteFloat(SpeedMax); + } + } + public class MoveSplineSetFlag : ServerPacket { public MoveSplineSetFlag(ServerOpcodes opcode) : base(opcode, ConnectionType.Instance) { } @@ -840,8 +874,8 @@ namespace Game.Networking.Packets } public ObjectGuid MoverGUID; - int AckIndex; - int MoveTime; + public int AckIndex; + public int MoveTime; } public class MovementAckMessage : ClientPacket @@ -870,6 +904,22 @@ namespace Game.Networking.Packets public float Speed; } + class MovementSpeedRangeAck : ClientPacket + { + public MovementAck Ack; + public float SpeedMin = 1.0f; + public float SpeedMax = 1.0f; + + public MovementSpeedRangeAck(WorldPacket packet) : base(packet) { } + + public override void Read() + { + Ack.Read(_worldPacket); + SpeedMin = _worldPacket.ReadFloat(); + SpeedMax = _worldPacket.ReadFloat(); + } + } + public class SetActiveMover : ClientPacket { public ObjectGuid ActiveMover; @@ -1263,7 +1313,7 @@ namespace Game.Networking.Packets Ticks = _worldPacket.ReadUInt32(); } } - + //Structs public struct MovementAck { @@ -1355,14 +1405,14 @@ namespace Game.Networking.Packets public void Write(WorldPacket data) { data.WriteInt32(TierTransitionID); - data .WriteUInt32(StartTime); + data.WriteUInt32(StartTime); data.WriteUInt32(EndTime); data.WriteUInt8(AnimTier); } } public class MonsterSplineUnknown901 - { + { public Array Data = new(16); public void Write(WorldPacket data)