From 5d1a182e4754b6b47b80489f994c1733237ec006 Mon Sep 17 00:00:00 2001 From: Sardelka Date: Sun, 17 Jul 2022 18:44:16 +0800 Subject: [PATCH] Better ragdoll sync (maybe) --- RageCoop.Client/Main.cs | 21 +++++++++--- RageCoop.Client/Networking/Receive.cs | 8 ++++- RageCoop.Client/Networking/Send.cs | 11 +++++- RageCoop.Client/Sync/Entities/SyncedPed.cs | 39 ++++++++++++++++++++-- RageCoop.Client/Util/PedExtensions.cs | 1 - RageCoop.Client/Util/Util.cs | 4 +++ RageCoop.Core/Packets/PedSync.cs | 36 +++++++++++++++++--- 7 files changed, 105 insertions(+), 15 deletions(-) diff --git a/RageCoop.Client/Main.cs b/RageCoop.Client/Main.cs index 70340a8..573690f 100644 --- a/RageCoop.Client/Main.cs +++ b/RageCoop.Client/Main.cs @@ -99,12 +99,16 @@ namespace RageCoop.Client Util.NativeMemory(); Counter.Restart(); } - + #if DEBUG #endif + + int pinPart = 0; private void OnTick(object sender, EventArgs e) { - PlayerPosition=Game.Player.Character.Position; + var P = Game.Player.Character; + + PlayerPosition=P.Position; if (Game.IsLoading) { return; @@ -160,8 +164,6 @@ namespace RageCoop.Client Function.Call(Hash.IGNORE_NEXT_RESTART, true); Function.Call(Hash.FORCE_GAME_STATE_PLAYING); Function.Call(Hash.TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME, "respawn_controller"); - - var P = Game.Player.Character; if (P.IsDead) { Function.Call(Hash.SET_FADE_OUT_AFTER_DEATH, false); @@ -187,6 +189,16 @@ namespace RageCoop.Client private void OnKeyDown(object sender, KeyEventArgs e) { + if(e.KeyCode == Keys.Right) + { + pinPart++; + GTA.UI.Notification.Show(pinPart.ToString()); + } + if (e.KeyCode == Keys.Left) + { + pinPart--; + GTA.UI.Notification.Show(pinPart.ToString()); + } if (MainChat.Focused) { MainChat.OnKeyDown(e.KeyCode); @@ -337,7 +349,6 @@ namespace RageCoop.Client ServerItems.Clear(); } } - private static void DoQueuedActions() { lock (QueuedActions) diff --git a/RageCoop.Client/Networking/Receive.cs b/RageCoop.Client/Networking/Receive.cs index b95abe5..c50584a 100644 --- a/RageCoop.Client/Networking/Receive.cs +++ b/RageCoop.Client/Networking/Receive.cs @@ -287,7 +287,6 @@ namespace RageCoop.Client c.ID=packet.ID; c.OwnerID=packet.OwnerID; c.Health = packet.Health; - c.Position = packet.Position; c.Rotation = packet.Rotation; c.Velocity = packet.Velocity; c.Speed = packet.Speed; @@ -304,6 +303,13 @@ namespace RageCoop.Client c.IsInCover = flags.HasPedFlag(PedDataFlags.IsInCover); c.IsInStealthMode = flags.HasPedFlag(PedDataFlags.IsInStealthMode); c.Heading=packet.Heading; + c.Position = packet.Position; + if (c.IsRagdoll) + { + c.HeadPosition=packet.HeadPosition; + c.RightFootPosition=packet.RightFootPosition; + c.LeftFootPosition=packet.LeftFootPosition; + } c.LastSynced = Main.Ticked; if (c.IsAiming) { diff --git a/RageCoop.Client/Networking/Send.cs b/RageCoop.Client/Networking/Send.cs index 5a50d1a..69bf4e7 100644 --- a/RageCoop.Client/Networking/Send.cs +++ b/RageCoop.Client/Networking/Send.cs @@ -32,7 +32,6 @@ namespace RageCoop.Client ID =c.ID, OwnerID=c.OwnerID, Health = p.Health, - Position = p.Position, Rotation = p.Rotation, Velocity = p.Velocity, Speed = p.GetPedSpeed(), @@ -44,6 +43,16 @@ namespace RageCoop.Client { packet.AimCoords = p.GetAimCoord(); } + if (packet.Flags.HasPedFlag(PedDataFlags.IsRagdoll)) + { + packet.HeadPosition=p.Bones[Bone.SkelHead].Position; + packet.RightFootPosition=p.Bones[Bone.SkelRightFoot].Position; + packet.LeftFootPosition=p.Bones[Bone.SkelLeftFoot].Position; + } + else + { + packet.Position = p.Position; + } if (full) { packet.Flags |= PedDataFlags.IsFullSync; diff --git a/RageCoop.Client/Sync/Entities/SyncedPed.cs b/RageCoop.Client/Sync/Entities/SyncedPed.cs index 3dc05f9..a664d4e 100644 --- a/RageCoop.Client/Sync/Entities/SyncedPed.cs +++ b/RageCoop.Client/Sync/Entities/SyncedPed.cs @@ -63,6 +63,11 @@ namespace RageCoop.Client public Ped MainPed { get; internal set; } internal int Health { get; set; } internal bool IsInStealthMode { get; set; } + + internal Vector3 HeadPosition { get; set; } + internal Vector3 RightFootPosition { get; set; } + internal Vector3 LeftFootPosition { get; set; } + internal byte WeaponTint { get; set; } internal bool _lastEnteringVehicle=false; internal bool _lastSittingInVehicle=false; @@ -703,12 +708,42 @@ namespace RageCoop.Client { MainPed.Heading=Heading; MainPed.Velocity=Velocity+5*dist*(Position-MainPed.Position); - // if (MainPed.Speed<0.05) { f*=10; MainPed.Heading=Heading; } } - else if (Main.Ticked-_lastRagdollTime<20) + else if (Main.Ticked-_lastRagdollTime<30) { return; } + else if (IsRagdoll) + { + var helper = new GTA.NaturalMotion.ApplyImpulseHelper(MainPed); + var head = MainPed.Bones[Bone.SkelHead]; + var rightFoot = MainPed.Bones[Bone.SkelRightFoot]; + var leftFoot = MainPed.Bones[Bone.SkelLeftFoot]; + + // 20:head, 3:left foot, 6:right foot, 17:right hand, + + helper.EqualizeAmount = 1; + helper.PartIndex=20; + helper.Impulse=20*(HeadPosition-head.Position); + helper.Start(); + helper.Stop(); + + helper.EqualizeAmount = 1; + helper.PartIndex=6; + helper.Impulse=20*(RightFootPosition-rightFoot.Position); + helper.Start(); + helper.Stop(); + + helper.EqualizeAmount = 1; + helper.PartIndex=3; + helper.Impulse=20*(LeftFootPosition-leftFoot.Position); + helper.Start(); + helper.Stop(); + } + else + { + MainPed.Velocity=Velocity+5*dist*(Position-MainPed.Position); + } // MainPed.ApplyForce(f); } diff --git a/RageCoop.Client/Util/PedExtensions.cs b/RageCoop.Client/Util/PedExtensions.cs index 0b6855d..a7cc63f 100644 --- a/RageCoop.Client/Util/PedExtensions.cs +++ b/RageCoop.Client/Util/PedExtensions.cs @@ -333,7 +333,6 @@ namespace RageCoop.Client { return (VehicleSeat)Function.Call(Hash.GET_SEAT_PED_IS_TRYING_TO_ENTER, p); } - #endregion diff --git a/RageCoop.Client/Util/Util.cs b/RageCoop.Client/Util/Util.cs index 0d3d2f8..08a1e87 100644 --- a/RageCoop.Client/Util/Util.cs +++ b/RageCoop.Client/Util/Util.cs @@ -219,6 +219,10 @@ namespace RageCoop.Client return v; } + public static void ApplyForce(this Entity e,int boneIndex, Vector3 direction, Vector3 rotation = default(Vector3), ForceType forceType = ForceType.MaxForceRot2) + { + Function.Call(Hash.APPLY_FORCE_TO_ENTITY, e.Handle, forceType, direction.X, direction.Y, direction.Z, rotation.X, rotation.Y, rotation.Z, boneIndex, false, true, true, false, true); + } public static byte GetPlayerRadioIndex() { return (byte)Function.Call(Hash.GET_PLAYER_RADIO_STATION_INDEX); diff --git a/RageCoop.Core/Packets/PedSync.cs b/RageCoop.Core/Packets/PedSync.cs index ef629b6..2e0f6ee 100644 --- a/RageCoop.Core/Packets/PedSync.cs +++ b/RageCoop.Core/Packets/PedSync.cs @@ -26,7 +26,12 @@ namespace RageCoop.Core public Vector3 Velocity { get; set; } - // public Vector3 RotationVelocity { get; set; } + #region RAGDOLL + public Vector3 HeadPosition { get; set; } + public Vector3 RightFootPosition { get; set; } + public Vector3 LeftFootPosition { get; set; } + + #endregion public byte Speed { get; set; } @@ -71,8 +76,19 @@ namespace RageCoop.Core // Write ped health byteArray.AddRange(BitConverter.GetBytes(Health)); - // Write ped position - byteArray.AddVector3(Position); + // ragdoll sync + if (Flags.HasPedFlag(PedDataFlags.IsRagdoll)) + { + byteArray.AddVector3(HeadPosition); + byteArray.AddVector3(RightFootPosition); + byteArray.AddVector3(LeftFootPosition); + + } + else + { + // Write ped position + byteArray.AddVector3(Position); + } // Write ped rotation byteArray.AddVector3(Rotation); @@ -152,8 +168,18 @@ namespace RageCoop.Core // Read player health Health = reader.ReadInt(); - // Read player position - Position = reader.ReadVector3(); + if (Flags.HasPedFlag(PedDataFlags.IsRagdoll)) + { + HeadPosition=reader.ReadVector3(); + RightFootPosition=reader.ReadVector3(); + LeftFootPosition=reader.ReadVector3(); + Position=HeadPosition; + } + else + { + // Read player position + Position = reader.ReadVector3(); + } // Read player rotation Rotation = reader.ReadVector3();