From 393a401860dc167b5e43940e73232c397e58baeb Mon Sep 17 00:00:00 2001 From: oldnapalm <38410858+oldnapalm@users.noreply.github.com> Date: Tue, 7 Nov 2023 20:27:14 -0300 Subject: [PATCH 1/3] Always sync vehicles with synced peds --- RageCoop.Client/Networking/Receive.cs | 5 +++-- RageCoop.Client/Sync/EntityPool.cs | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/RageCoop.Client/Networking/Receive.cs b/RageCoop.Client/Networking/Receive.cs index fcea653..a2b1357 100644 --- a/RageCoop.Client/Networking/Receive.cs +++ b/RageCoop.Client/Networking/Receive.cs @@ -3,6 +3,7 @@ using Lidgren.Network; using RageCoop.Client.Menus; using RageCoop.Core; using System; +using System.Linq; using System.Threading; namespace RageCoop.Client @@ -306,7 +307,7 @@ namespace RageCoop.Client if (c == null) { // Main.Logger.Debug($"Creating character for incoming sync:{packet.ID}"); - if (EntityPool.allPeds.Length < Main.Settings.GlobalPedSoftLimit || PlayerList.Players.ContainsKey(packet.ID)) + if (EntityPool.allPeds.Length < Main.Settings.GlobalPedSoftLimit + PlayerList.Players.Count || PlayerList.Players.ContainsKey(packet.ID)) EntityPool.ThreadSafe.Add(c = new SyncedPed(packet.ID)); else return; } @@ -356,7 +357,7 @@ namespace RageCoop.Client SyncedVehicle v = EntityPool.GetVehicleByID(packet.ID); if (v == null) { - if (EntityPool.allVehicles.Length < Main.Settings.GlobalVehicleSoftLimit) + if (EntityPool.allVehicles.Length < Main.Settings.GlobalVehicleSoftLimit || EntityPool.PedsByID.Any(x => x.Value.Position.DistanceTo(packet.Position) < 2f)) EntityPool.ThreadSafe.Add(v = new SyncedVehicle(packet.ID)); else return; } diff --git a/RageCoop.Client/Sync/EntityPool.cs b/RageCoop.Client/Sync/EntityPool.cs index 891e386..9b37b60 100644 --- a/RageCoop.Client/Sync/EntityPool.cs +++ b/RageCoop.Client/Sync/EntityPool.cs @@ -51,7 +51,7 @@ namespace RageCoop.Client PedsByID.Clear(); PedsByHandle.Clear(); - foreach (int id in new List(VehiclesByID.Keys)) + foreach (int id in VehiclesByID.Keys.ToArray()) { if (keepMine && (VehiclesByID[id].OwnerID == Main.LocalPlayerID)) { continue; } RemoveVehicle(id); @@ -359,11 +359,11 @@ namespace RageCoop.Client lock (PedsLock) { AddPlayer(); + var mainCharacters = new List { PedHash.Michael, PedHash.Franklin, PedHash.Franklin02, PedHash.Trevor }; foreach (Ped p in allPeds) { SyncedPed c = GetPedByHandle(p.Handle); - List mainCharacters = new List { PedHash.Michael, PedHash.Franklin, PedHash.Franklin02, PedHash.Trevor }; if (c == null && p != Game.Player.Character && !mainCharacters.Contains((PedHash)p.Model.Hash)) { if (allPeds.Length > Main.Settings.WorldPedSoftLimit && p.PopulationType == EntityPopulationType.RandomAmbient && !p.IsInVehicle()) From 3c7f16f7a4d1c1abb6475fd529692e02613eb922 Mon Sep 17 00:00:00 2001 From: oldnapalm <38410858+oldnapalm@users.noreply.github.com> Date: Sun, 12 Nov 2023 10:50:37 -0300 Subject: [PATCH 2/3] Add ped limit menu setting Fix vehicle limit menu setting Fix player blip disappearing after switching character --- RageCoop.Client/Menus/Sub/SettingsMenu.cs | 17 ++++++++++++++++- RageCoop.Client/Sync/Entities/Ped/SyncedPed.cs | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/RageCoop.Client/Menus/Sub/SettingsMenu.cs b/RageCoop.Client/Menus/Sub/SettingsMenu.cs index f3bbc90..17b1bf6 100644 --- a/RageCoop.Client/Menus/Sub/SettingsMenu.cs +++ b/RageCoop.Client/Menus/Sub/SettingsMenu.cs @@ -24,6 +24,7 @@ namespace RageCoop.Client.Menus private static readonly NativeItem _menuKey = new NativeItem("Menu Key", "The key to open menu", Main.Settings.MenuKey.ToString()); private static readonly NativeItem _passengerKey = new NativeItem("Passenger Key", "The key to enter a vehicle as passenger", Main.Settings.PassengerKey.ToString()); private static readonly NativeItem _vehicleSoftLimit = new NativeItem("Vehicle limit (soft)", "The game won't spawn more NPC traffic if the limit is exceeded. \n-1 for unlimited (not recommended).", Main.Settings.WorldVehicleSoftLimit.ToString()); + private static readonly NativeItem _pedSoftLimit = new NativeItem("Ped limit (soft)", "The game won't spawn more NPCs if the limit is exceeded. \n-1 for unlimited (not recommended).", Main.Settings.WorldPedSoftLimit.ToString()); static SettingsMenu() { @@ -37,6 +38,7 @@ namespace RageCoop.Client.Menus _menuKey.Activated += ChaneMenuKey; _passengerKey.Activated += ChangePassengerKey; _vehicleSoftLimit.Activated += VehicleSoftLimitActivated; + _pedSoftLimit.Activated += PedSoftLimitActivated; _showBlip.Activated += (s, e) => { Main.Settings.ShowPlayerBlip = _showBlip.Checked; @@ -55,6 +57,7 @@ namespace RageCoop.Client.Menus Menu.Add(_menuKey); Menu.Add(_passengerKey); Menu.Add(_vehicleSoftLimit); + Menu.Add(_pedSoftLimit); Menu.Add(_showBlip); Menu.Add(_showNametag); } @@ -89,7 +92,19 @@ namespace RageCoop.Client.Menus Main.Settings.WorldVehicleSoftLimit = int.Parse( Game.GetUserInput(WindowTitle.EnterMessage20, Main.Settings.WorldVehicleSoftLimit.ToString(), 20)); - _menuKey.AltTitle = Main.Settings.WorldVehicleSoftLimit.ToString(); + _vehicleSoftLimit.AltTitle = Main.Settings.WorldVehicleSoftLimit.ToString(); + Util.SaveSettings(); + } + catch { } + } + private static void PedSoftLimitActivated(object sender, EventArgs e) + { + try + { + Main.Settings.WorldPedSoftLimit = int.Parse( + Game.GetUserInput(WindowTitle.EnterMessage20, + Main.Settings.WorldPedSoftLimit.ToString(), 20)); + _pedSoftLimit.AltTitle = Main.Settings.WorldPedSoftLimit.ToString(); Util.SaveSettings(); } catch { } diff --git a/RageCoop.Client/Sync/Entities/Ped/SyncedPed.cs b/RageCoop.Client/Sync/Entities/Ped/SyncedPed.cs index 0452cf3..62554c7 100644 --- a/RageCoop.Client/Sync/Entities/Ped/SyncedPed.cs +++ b/RageCoop.Client/Sync/Entities/Ped/SyncedPed.cs @@ -205,7 +205,7 @@ namespace RageCoop.Client MainPed = null; } - if (PedBlip != null && PedBlip.Exists()) + if (PedBlip != null) { PedBlip.Delete(); PedBlip = null; From 8bd6ea15a3153839649f35a8b8d50d48a2c59c9b Mon Sep 17 00:00:00 2001 From: oldnapalm <38410858+oldnapalm@users.noreply.github.com> Date: Mon, 20 Nov 2023 11:32:18 -0300 Subject: [PATCH 3/3] Remove global limits world limits will be applied to all players instead Fix explosions when remote and local vehicles exist at same position Fix "floating corpses" issue when remote NPCs are killed --- RageCoop.Client/Networking/Receive.cs | 19 ++++---- RageCoop.Client/Properties/AssemblyInfo.cs | 4 +- RageCoop.Client/Settings.cs | 15 ------ .../Sync/Entities/Ped/SyncedPed.cs | 8 +++- .../Sync/Entities/Vehicle/SyncedVehicle.cs | 47 +++++-------------- RageCoop.Client/Sync/EntityPool.cs | 21 +++++---- RageCoop.Client/WorldThread.cs | 2 +- 7 files changed, 43 insertions(+), 73 deletions(-) diff --git a/RageCoop.Client/Networking/Receive.cs b/RageCoop.Client/Networking/Receive.cs index a2b1357..e343c62 100644 --- a/RageCoop.Client/Networking/Receive.cs +++ b/RageCoop.Client/Networking/Receive.cs @@ -306,12 +306,14 @@ namespace RageCoop.Client SyncedPed c = EntityPool.GetPedByID(packet.ID); if (c == null) { - // Main.Logger.Debug($"Creating character for incoming sync:{packet.ID}"); - if (EntityPool.allPeds.Length < Main.Settings.GlobalPedSoftLimit + PlayerList.Players.Count || PlayerList.Players.ContainsKey(packet.ID)) + if (EntityPool.PedsByID.Count(x => x.Value.OwnerID == packet.OwnerID) < Main.Settings.WorldPedSoftLimit / PlayerList.Players.Count || + EntityPool.VehiclesByID.Any(x => x.Value.Position.DistanceTo(packet.Position) < 2) || packet.ID == packet.OwnerID) + { + // Main.Logger.Debug($"Creating character for incoming sync:{packet.ID}"); EntityPool.ThreadSafe.Add(c = new SyncedPed(packet.ID)); + } else return; } - PedDataFlags flags = packet.Flags; c.ID = packet.ID; c.OwnerID = packet.OwnerID; c.Health = packet.Health; @@ -357,8 +359,12 @@ namespace RageCoop.Client SyncedVehicle v = EntityPool.GetVehicleByID(packet.ID); if (v == null) { - if (EntityPool.allVehicles.Length < Main.Settings.GlobalVehicleSoftLimit || EntityPool.PedsByID.Any(x => x.Value.Position.DistanceTo(packet.Position) < 2f)) + if (EntityPool.VehiclesByID.Count(x => x.Value.OwnerID == packet.OwnerID) < Main.Settings.WorldVehicleSoftLimit / PlayerList.Players.Count || + EntityPool.PedsByID.Any(x => x.Value.VehicleID == packet.ID || x.Value.Position.DistanceTo(packet.Position) < 2)) + { + // Main.Logger.Debug($"Creating vehicle for incoming sync:{packet.ID}"); EntityPool.ThreadSafe.Add(v = new SyncedVehicle(packet.ID)); + } else return; } if (v.IsLocal) { return; } @@ -393,15 +399,12 @@ namespace RageCoop.Client } private static void ProjectileSync(Packets.ProjectileSync packet) { - var p = EntityPool.GetProjectileByID(packet.ID); if (p == null) { if (packet.Flags.HasProjDataFlag(ProjectileDataFlags.Exploded)) { return; } // Main.Logger.Debug($"Creating new projectile: {(WeaponHash)packet.WeaponHash}"); - if (EntityPool.allProjectiles.Length < Main.Settings.GlobalProjectileSoftLimit) - EntityPool.ThreadSafe.Add(p = new SyncedProjectile(packet.ID)); - else return; + EntityPool.ThreadSafe.Add(p = new SyncedProjectile(packet.ID)); } p.Flags = packet.Flags; p.Position = packet.Position; diff --git a/RageCoop.Client/Properties/AssemblyInfo.cs b/RageCoop.Client/Properties/AssemblyInfo.cs index e6b2d99..66704d2 100644 --- a/RageCoop.Client/Properties/AssemblyInfo.cs +++ b/RageCoop.Client/Properties/AssemblyInfo.cs @@ -16,7 +16,7 @@ using System.Resources; // Version information -[assembly: AssemblyVersion("1.5.4.6")] -[assembly: AssemblyFileVersion("1.5.4.6")] +[assembly: AssemblyVersion("1.5.4.7")] +[assembly: AssemblyFileVersion("1.5.4.7")] [assembly: NeutralResourcesLanguageAttribute( "en-US" )] diff --git a/RageCoop.Client/Settings.cs b/RageCoop.Client/Settings.cs index b60e91e..cd1b5cc 100644 --- a/RageCoop.Client/Settings.cs +++ b/RageCoop.Client/Settings.cs @@ -68,21 +68,6 @@ namespace RageCoop.Client /// public int WorldPedSoftLimit { get; set; } = 30; - /// - /// The mod won't sync more vehicles if the limit is exceeded. - /// - public int GlobalVehicleSoftLimit { get; set; } = 100; - - /// - /// The mod won't sync more peds if the limit is exceeded. - /// - public int GlobalPedSoftLimit { get; set; } = 100; - - /// - /// The mod won't sync more projectiles if the limit is exceeded. - /// - public int GlobalProjectileSoftLimit { get; set; } = 100; - /// /// The directory where log and resources downloaded from server will be placed. /// diff --git a/RageCoop.Client/Sync/Entities/Ped/SyncedPed.cs b/RageCoop.Client/Sync/Entities/Ped/SyncedPed.cs index 62554c7..b77a287 100644 --- a/RageCoop.Client/Sync/Entities/Ped/SyncedPed.cs +++ b/RageCoop.Client/Sync/Entities/Ped/SyncedPed.cs @@ -141,6 +141,12 @@ namespace RageCoop.Client } } + if (!IsPlayer && Health <= 0 && !MainPed.IsDead) + { + MainPed.Kill(); + return; + } + if (Speed >= 4) { DisplayInVehicle(); @@ -420,7 +426,7 @@ namespace RageCoop.Client } _lastIsJumping = false; - if (IsRagdoll || Health == 0) + if (IsRagdoll || (IsPlayer && Health == 0)) { if (!MainPed.IsRagdoll) { diff --git a/RageCoop.Client/Sync/Entities/Vehicle/SyncedVehicle.cs b/RageCoop.Client/Sync/Entities/Vehicle/SyncedVehicle.cs index d99e89b..5cab0e0 100644 --- a/RageCoop.Client/Sync/Entities/Vehicle/SyncedVehicle.cs +++ b/RageCoop.Client/Sync/Entities/Vehicle/SyncedVehicle.cs @@ -4,6 +4,7 @@ using GTA.Native; using RageCoop.Core; using System; using System.Collections.Generic; +using System.Linq; namespace RageCoop.Client { @@ -307,6 +308,16 @@ namespace RageCoop.Client } private bool CreateVehicle() { + var existing = World.GetNearbyVehicles(Position, 2).ToList().FirstOrDefault(); + if (existing != null && existing != MainVehicle) + { + if (EntityPool.VehiclesByHandle.ContainsKey(existing.Handle)) + { + EntityPool.RemoveVehicle(ID); + return false; + } + existing.Delete(); + } MainVehicle?.Delete(); MainVehicle = Util.CreateVehicle(Model, Position); if (!Model.IsInCdImage) @@ -337,41 +348,5 @@ namespace RageCoop.Client Model.MarkAsNoLongerNeeded(); return true; } - #region -- PEDALING -- - /* - * Thanks to @oldnapalm. - */ - - private string PedalingAnimDict() - { - switch ((VehicleHash)Model) - { - case VehicleHash.Bmx: - return "veh@bicycle@bmx@front@base"; - case VehicleHash.Cruiser: - return "veh@bicycle@cruiserfront@base"; - case VehicleHash.Scorcher: - return "veh@bicycle@mountainfront@base"; - default: - return "veh@bicycle@roadfront@base"; - } - } - - private string PedalingAnimName(bool fast) - { - return fast ? "fast_pedal_char" : "cruise_pedal_char"; - } - - private void StartPedalingAnim(bool fast) - { - MainVehicle.Driver?.Task.PlayAnimation(PedalingAnimDict(), PedalingAnimName(fast), 8.0f, -8.0f, -1, AnimationFlags.Loop | AnimationFlags.Secondary, 1.0f); - - } - - private void StopPedalingAnim(bool fast) - { - MainVehicle.Driver.Task.ClearAnimation(PedalingAnimDict(), PedalingAnimName(fast)); - } - #endregion } } diff --git a/RageCoop.Client/Sync/EntityPool.cs b/RageCoop.Client/Sync/EntityPool.cs index 9b37b60..1053a85 100644 --- a/RageCoop.Client/Sync/EntityPool.cs +++ b/RageCoop.Client/Sync/EntityPool.cs @@ -363,18 +363,20 @@ namespace RageCoop.Client foreach (Ped p in allPeds) { - SyncedPed c = GetPedByHandle(p.Handle); - if (c == null && p != Game.Player.Character && !mainCharacters.Contains((PedHash)p.Model.Hash)) + if (!PedsByHandle.ContainsKey(p.Handle) && p != Game.Player.Character && !mainCharacters.Contains((PedHash)p.Model.Hash)) { - if (allPeds.Length > Main.Settings.WorldPedSoftLimit && p.PopulationType == EntityPopulationType.RandomAmbient && !p.IsInVehicle()) + if (PedsByID.Count(x => x.Value.IsLocal) > Main.Settings.WorldPedSoftLimit) { - p.Delete(); - continue; + if (p.PopulationType == EntityPopulationType.RandomAmbient && !p.IsInVehicle()) + { + p.Delete(); + continue; + } + if (p.PopulationType == EntityPopulationType.RandomScenario) continue; } // Main.Logger.Trace($"Creating SyncEntity for ped, handle:{p.Handle}"); - c = new SyncedPed(p); - Add(c); + Add(new SyncedPed(p)); } } #if BENCHMARK @@ -438,10 +440,9 @@ namespace RageCoop.Client { if (!VehiclesByHandle.ContainsKey(veh.Handle)) { - if (allVehicles.Length > Main.Settings.WorldVehicleSoftLimit) + if (VehiclesByID.Count(x => x.Value.IsLocal) > Main.Settings.WorldVehicleSoftLimit) { - var type = veh.PopulationType; - if (type == EntityPopulationType.RandomAmbient || type == EntityPopulationType.RandomParked) + if (veh.PopulationType == EntityPopulationType.RandomAmbient || veh.PopulationType == EntityPopulationType.RandomParked) { foreach (var p in veh.Occupants) { diff --git a/RageCoop.Client/WorldThread.cs b/RageCoop.Client/WorldThread.cs index 4192477..a0f0977 100644 --- a/RageCoop.Client/WorldThread.cs +++ b/RageCoop.Client/WorldThread.cs @@ -120,7 +120,7 @@ namespace RageCoop.Client if ((c == null) || (c.IsLocal && (ped.Handle != Game.Player.Character.Handle) && ped.PopulationType != EntityPopulationType.Mission)) { - Main.Logger.Trace($"Removing ped {ped.Handle}. Reason:RemoveTraffic"); + // Main.Logger.Trace($"Removing ped {ped.Handle}. Reason:RemoveTraffic"); ped.CurrentVehicle?.Delete(); ped.Kill(); ped.Delete();