From 6bacaad1cec1307266db965b9718dc7f0ceb4d00 Mon Sep 17 00:00:00 2001 From: sausage Date: Mon, 23 May 2022 11:10:11 +0800 Subject: [PATCH] Customizable key binding and passenger fix. --- Client/Debug.cs | 9 +- Client/Main.cs | 117 ++-- .../Menus/{MenusMain.cs => RageCoopMenu.cs} | 11 +- Client/Menus/Sub/DebugMenu.cs | 22 +- .../Sub/{Settings.cs => SettingsMenu.cs} | 75 ++- Client/RageCoop.Client.csproj | 9 +- Client/Settings.cs | 10 + Client/Sync/Entities/SyncedPed.cs | 53 -- Client/Sync/Entities/SyncedVehicle.cs | 2 +- Client/Util.cs | 630 +++++++++--------- 10 files changed, 453 insertions(+), 485 deletions(-) rename Client/Menus/{MenusMain.cs => RageCoopMenu.cs} (93%) rename Client/Menus/Sub/{Settings.cs => SettingsMenu.cs} (63%) diff --git a/Client/Debug.cs b/Client/Debug.cs index 41fc936..06896c1 100644 --- a/Client/Debug.cs +++ b/Client/Debug.cs @@ -9,16 +9,15 @@ namespace RageCoop.Client internal enum TimeStamp { AddPeds, + PedTotal, + AddVehicles, + VehicleTotal, SendPed, SendPedState, - PedTotal, - UpdatePed, - AddVehicles, SendVehicle, SendVehicleState, + UpdatePed, UpdateVehicle, - CheckPersistent, - VehicleTotal, CheckProjectiles, GetAllEntities, Receive, diff --git a/Client/Main.cs b/Client/Main.cs index 4a2e054..f726a85 100644 --- a/Client/Main.cs +++ b/Client/Main.cs @@ -17,7 +17,7 @@ namespace RageCoop.Client /// /// Don't use it! /// - public class Main : Script + internal class Main : Script { private bool _gameLoaded = false; @@ -28,13 +28,13 @@ namespace RageCoop.Client public static int MyPlayerID=0; public static bool DisableTraffic = true; public static bool NPCsAllowed = false; - internal static RelationshipGroup SyncedPedsGroup; + internal static RelationshipGroup SyncedPedsGroup; - public static Settings Settings = null; + public static new Settings Settings = null; public static Networking MainNetworking = null; #if !NON_INTERACTIVE - public static MenusMain MainMenu = null; + public static RageCoopMenu MainMenu = null; #endif public static Chat MainChat = null; public static PlayerList MainPlayerList = new PlayerList(); @@ -75,7 +75,7 @@ namespace RageCoop.Client MainNetworking = new Networking(); MainNetworking.Start(); #if !NON_INTERACTIVE - MainMenu = new MenusMain(); + MainMenu = new RageCoopMenu(); #endif MainChat = new Chat(); #if DEBUG @@ -106,7 +106,7 @@ namespace RageCoop.Client else if (!_gameLoaded && (_gameLoaded = true)) { #if !NON_INTERACTIVE - GTA.UI.Notification.Show(GTA.UI.NotificationIcon.AllPlayersConf, "RAGECOOP", "Welcome!", "Press ~g~F9~s~ to open the menu."); + GTA.UI.Notification.Show(GTA.UI.NotificationIcon.AllPlayersConf, "RAGECOOP","Welcome!", $"Press ~g~{Main.Settings.MenuKey}~s~ to open the menu."); #endif } @@ -176,7 +176,6 @@ namespace RageCoop.Client } #if !NON_INTERACTIVE - bool _lastEnteringVeh=false; private void OnKeyDown(object sender, KeyEventArgs e) { if (MainChat.Focused) @@ -189,80 +188,52 @@ namespace RageCoop.Client Function.Call(Hash.ACTIVATE_FRONTEND_MENU, Function.Call(Hash.GET_HASH_KEY, "FE_MENU_VERSION_SP_PAUSE"), false, 0); return; } - - switch (e.KeyCode) + if(e.KeyCode == Settings.MenuKey) { - case Keys.F9: - if (MainMenu.MenuPool.AreAnyVisible) - { - MainMenu.MainMenu.Visible = false; - MainMenu.SubSettings.MainMenu.Visible = false; - } - else - { - MainMenu.MainMenu.Visible = true; - } - break; - case Keys.J: - Game.Player.Character.CurrentVehicle.ApplyForce(new Vector3(0, 0, 100)); - Script.Yield(); - GTA.UI.Notification.Show(Game.Player.Character.CurrentVehicle.Speed.ToString()); - break; - default: - if (Game.IsControlJustPressed(GTA.Control.MultiplayerInfo)) - { - if (MainNetworking.IsOnServer()) - { - ulong currentTimestamp = Util.GetTickCount64(); - MainPlayerList.Pressed = (currentTimestamp - MainPlayerList.Pressed) < 5000 ? (currentTimestamp - 6000) : currentTimestamp; - } - } - else if (Game.IsControlJustPressed(GTA.Control.MpTextChatAll)) - { - if (MainNetworking.IsOnServer()) - { - MainChat.Focused = true; - } - } - break; - } - - - if (e.KeyCode==Keys.L) - { - GTA.UI.Notification.Show(DumpCharacters()); - } - if (e.KeyCode==Keys.I) - { - GTA.UI.Notification.Show(DumpPlayers()); - } - if (e.KeyCode==Keys.U) - { - Debug.ShowTimeStamps(); - } - if (e.KeyCode==Keys.G) - { - var P = Game.Player.Character; - if (P.IsInVehicle()) + if (MainMenu.MenuPool.AreAnyVisible) { - _lastEnteringVeh=false; - P.Task.LeaveVehicle(); + MainMenu.MainMenu.Visible = false; + MainMenu.SubSettings.MainMenu.Visible = false; } else { - var V = World.GetClosestVehicle(P.Position, 50); - - if (_lastEnteringVeh) + MainMenu.MainMenu.Visible = true; + } + } + else if (Game.IsControlJustPressed(GTA.Control.MultiplayerInfo)) + { + if (MainNetworking.IsOnServer()) + { + ulong currentTimestamp = Util.GetTickCount64(); + MainPlayerList.Pressed = (currentTimestamp - MainPlayerList.Pressed) < 5000 ? (currentTimestamp - 6000) : currentTimestamp; + } + } + else if (Game.IsControlJustPressed(GTA.Control.MpTextChatAll)) + { + if (MainNetworking.IsOnServer()) + { + MainChat.Focused = true; + } + } + else if (e.KeyCode==Settings.PassengerKey) + { + var P = Game.Player.Character; + + if (!P.IsInVehicle()) + { + if (P.IsTaskActive(ETasks.EnterVehicle)) { - P.Task.ClearAllImmediately(); - - _lastEnteringVeh = false; + P.Task.ClearAll(); } - else if (V!=null) + else { - var seat = Util.getNearestSeat(P, V); - P.Task.EnterVehicle(V, seat); - _lastEnteringVeh=true; + var V = World.GetClosestVehicle(P.Position, 50); + + if (V!=null) + { + var seat = Util.GetNearestSeat(P, V); + P.Task.EnterVehicle(V, seat); + } } } } diff --git a/Client/Menus/MenusMain.cs b/Client/Menus/RageCoopMenu.cs similarity index 93% rename from Client/Menus/MenusMain.cs rename to Client/Menus/RageCoopMenu.cs index e8df3bd..bd5fa88 100644 --- a/Client/Menus/MenusMain.cs +++ b/Client/Menus/RageCoopMenu.cs @@ -10,7 +10,7 @@ namespace RageCoop.Client.Menus /// /// Don't use it! /// - public class MenusMain + public class RageCoopMenu { public ObjectPool MenuPool = new ObjectPool(); @@ -20,7 +20,7 @@ namespace RageCoop.Client.Menus Alignment = Main.Settings.FlipMenu ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left }; #region SUB - public Sub.Settings SubSettings = new Sub.Settings(); + public Sub.SettingsMenu SubSettings = new Sub.SettingsMenu(); public Sub.Servers ServerList = new Sub.Servers(); #endregion @@ -39,7 +39,7 @@ namespace RageCoop.Client.Menus /// /// Don't use it! /// - public MenusMain() + public RageCoopMenu() { MainMenu.Banner.Color = Color.FromArgb(225, 0, 0, 0); MainMenu.Title.Color = Color.FromArgb(255, 165, 0); @@ -55,13 +55,14 @@ namespace RageCoop.Client.Menus MainMenu.Add(_serverConnectItem); MainMenu.AddSubMenu(SubSettings.MainMenu); - MainMenu.AddSubMenu(DebugMenu.Menu); + MainMenu.AddSubMenu(DebugMenu.MainMenu); MainMenu.Add(_aboutItem); MenuPool.Add(ServerList.MainMenu); MenuPool.Add(MainMenu); MenuPool.Add(SubSettings.MainMenu); - MenuPool.Add(DebugMenu.Menu); + MenuPool.Add(DebugMenu.MainMenu); + MenuPool.Add(DebugMenu.DiagnosticMenu); } public void UsernameActivated(object a, System.EventArgs b) diff --git a/Client/Menus/Sub/DebugMenu.cs b/Client/Menus/Sub/DebugMenu.cs index 6b45469..2739112 100644 --- a/Client/Menus/Sub/DebugMenu.cs +++ b/Client/Menus/Sub/DebugMenu.cs @@ -11,7 +11,12 @@ namespace RageCoop.Client { internal static class DebugMenu { - public static NativeMenu Menu = new NativeMenu("RAGECOOP", "Debug", "Debug settings") { + public static NativeMenu MainMenu = new NativeMenu("RAGECOOP", "Debug", "Debug settings") { + UseMouse = false, + Alignment = Main.Settings.FlipMenu ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left + }; + public static NativeMenu DiagnosticMenu = new NativeMenu("RAGECOOP", "Diagnostic", "Performence and Diagnostic") + { UseMouse = false, Alignment = Main.Settings.FlipMenu ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left }; @@ -24,15 +29,24 @@ namespace RageCoop.Client catch { } Update(); }; + - Menu.Add(d1); - Menu.Opening+=(sender, e) =>Update(); + MainMenu.Add(d1); + MainMenu.AddSubMenu(DiagnosticMenu); + MainMenu.Opening+=(sender, e) =>Update(); + DiagnosticMenu.Opening+=(sender, e) => + { + DiagnosticMenu.Clear(); + foreach (var pair in Debug.TimeStamps) + { + DiagnosticMenu.Add(new NativeItem(pair.Key.ToString(), pair.Value.ToString(), pair.Value.ToString())); + } + }; Update(); } private static void Update() { - d1.AltTitle = SyncParameters.PositioinPrediction.ToString(); } } diff --git a/Client/Menus/Sub/Settings.cs b/Client/Menus/Sub/SettingsMenu.cs similarity index 63% rename from Client/Menus/Sub/Settings.cs rename to Client/Menus/Sub/SettingsMenu.cs index d0a1447..06ec5dc 100644 --- a/Client/Menus/Sub/Settings.cs +++ b/Client/Menus/Sub/SettingsMenu.cs @@ -1,6 +1,7 @@ -#undef DEBUG -using System.Drawing; - +using System.Drawing; +using System; +using System.Windows.Forms; +using GTA; using LemonUI.Menus; namespace RageCoop.Client.Menus.Sub @@ -8,7 +9,7 @@ namespace RageCoop.Client.Menus.Sub /// /// Don't use it! /// - public class Settings + public class SettingsMenu { public NativeMenu MainMenu = new NativeMenu("RAGECOOP", "Settings", "Go to the settings") { @@ -18,32 +19,55 @@ namespace RageCoop.Client.Menus.Sub private readonly NativeCheckboxItem _disableTrafficItem = new NativeCheckboxItem("Disable Traffic (NPCs/Vehicles)", "Local traffic only", Main.DisableTraffic); private readonly NativeCheckboxItem _flipMenuItem = new NativeCheckboxItem("Flip menu", Main.Settings.FlipMenu); -#if DEBUG - private readonly NativeCheckboxItem _useDebugItem = new NativeCheckboxItem("Debug", Main.UseDebug); private readonly NativeCheckboxItem _showNetworkInfoItem = new NativeCheckboxItem("Show Network Info", Main.MainNetworking.ShowNetworkInfo); -#endif + private static NativeItem _menuKey = new NativeItem("Menu Key","The key to open menu", Main.Settings.MenuKey.ToString()); + private static NativeItem _passengerKey = new NativeItem("Passenger Key", "The key to enter a vehicle as passenger", Main.Settings.PassengerKey.ToString()); /// /// Don't use it! /// - public Settings() + public SettingsMenu() { MainMenu.Banner.Color = Color.FromArgb(225, 0, 0, 0); MainMenu.Title.Color = Color.FromArgb(255, 165, 0); _disableTrafficItem.CheckboxChanged += DisableTrafficCheckboxChanged; _flipMenuItem.CheckboxChanged += FlipMenuCheckboxChanged; -#if DEBUG - _useDebugItem.CheckboxChanged += UseDebugCheckboxChanged; _showNetworkInfoItem.CheckboxChanged += ShowNetworkInfoCheckboxChanged; -#endif + _menuKey.Activated+=ChaneMenuKey; + _passengerKey.Activated+=ChangePassengerKey; MainMenu.Add(_disableTrafficItem); MainMenu.Add(_flipMenuItem); -#if DEBUG - MainMenu.Add(_useDebugItem); MainMenu.Add(_showNetworkInfoItem); -#endif + MainMenu.Add(_menuKey); + MainMenu.Add(_passengerKey); + } + + private void ChaneMenuKey(object sender, EventArgs e) + { + try + { + Main.Settings.MenuKey =(Keys)Enum.Parse( + typeof(Keys), + Game.GetUserInput(WindowTitle.EnterMessage20, + Main.Settings.MenuKey.ToString(), 20)); + _menuKey.AltTitle=Main.Settings.MenuKey.ToString(); + } + catch { } + } + + private void ChangePassengerKey(object sender, EventArgs e) + { + try + { + Main.Settings.PassengerKey =(Keys)Enum.Parse( + typeof(Keys), + Game.GetUserInput(WindowTitle.EnterMessage20, + Main.Settings.PassengerKey.ToString(), 20)); + _passengerKey.AltTitle=Main.Settings.PassengerKey.ToString(); + } + catch { } } public void DisableTrafficCheckboxChanged(object a, System.EventArgs b) @@ -53,9 +77,8 @@ namespace RageCoop.Client.Menus.Sub public void FlipMenuCheckboxChanged(object a, System.EventArgs b) { -#if !NON_INTERACTIVE Main.MainMenu.MainMenu.Alignment = _flipMenuItem.Checked ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left; -#endif + MainMenu.Alignment = _flipMenuItem.Checked ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left; Main.MainMenu.ServerList.MainMenu.Alignment = _flipMenuItem.Checked ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left; @@ -63,25 +86,6 @@ namespace RageCoop.Client.Menus.Sub Util.SaveSettings(); } -#if DEBUG - public void UseDebugCheckboxChanged(object a, System.EventArgs b) - { - Main.UseDebug = _useDebugItem.Checked; - - if (!_useDebugItem.Checked && Main.DebugSyncPed != null) - { - if (Main.DebugSyncPed.Character.Exists()) - { - Main.DebugSyncPed.Character.Kill(); - Main.DebugSyncPed.Character.Delete(); - } - - Main.DebugSyncPed = null; - Main.LastFullDebugSync = 0; - Main.Players.Remove(0); - } - } - public void ShowNetworkInfoCheckboxChanged(object a, System.EventArgs b) { Main.MainNetworking.ShowNetworkInfo = _showNetworkInfoItem.Checked; @@ -92,6 +96,5 @@ namespace RageCoop.Client.Menus.Sub Main.MainNetworking.BytesSend = 0; } } -#endif } } diff --git a/Client/RageCoop.Client.csproj b/Client/RageCoop.Client.csproj index 08f9161..5e835b6 100644 --- a/Client/RageCoop.Client.csproj +++ b/Client/RageCoop.Client.csproj @@ -26,8 +26,9 @@ 4 x64 true - Auto - bin\Debug\CoopClient.xml + Off + + pdbonly @@ -135,9 +136,9 @@ - + - + diff --git a/Client/Settings.cs b/Client/Settings.cs index 74d3b88..7160c2a 100644 --- a/Client/Settings.cs +++ b/Client/Settings.cs @@ -1,4 +1,5 @@ #undef DEBUG +using System.Windows.Forms; namespace RageCoop.Client { /// @@ -29,6 +30,15 @@ namespace RageCoop.Client /// public int LogLevel = 2; + /// + /// The key to open menu + /// + public Keys MenuKey { get; set; } = Keys.F9; + + /// + /// The key to enter a vehicle as passenger. + /// + public Keys PassengerKey { get; set; }=Keys.G; } } diff --git a/Client/Sync/Entities/SyncedPed.cs b/Client/Sync/Entities/SyncedPed.cs index 9f26d4f..0f62fc4 100644 --- a/Client/Sync/Entities/SyncedPed.cs +++ b/Client/Sync/Entities/SyncedPed.cs @@ -71,7 +71,6 @@ namespace RageCoop.Client private bool _lastRagdoll=false; private ulong _lastRagdollTime=0; private bool _lastInCover = false; - private bool _isEnteringVehicle = false; /// /// The latest character model hash (may not have been applied yet) /// @@ -334,7 +333,6 @@ namespace RageCoop.Client private bool _isPlayingAnimation = false; private string[] _currentAnimation = new string[2] { "", "" }; - private float _animationStopTime = 0; private void DisplayOnFoot() { @@ -693,8 +691,6 @@ namespace RageCoop.Client SmoothTransition(); } - private bool StuckDetection = false; - private ulong LastStuckTime; private void UpdateOnFootPosition(bool updatePosition = true, bool updateRotation = true, bool updateVelocity = true) { /* @@ -767,19 +763,6 @@ namespace RageCoop.Client } MainPed.ApplyForce(f); } - private Vector3 GetCalibrationRotation() - { - var r = Rotation-MainPed.Rotation; - if (r.X>180) { r.X=(180-r.X); } - else if (r.X<-180) { r.X=360+r.X; } - - if (r.Y>180||r.Y<-180) { r.Y=(180-r.Y); } - else if (r.Y<-180) { r.Y=360+r.Y; } - - if (r.Z>180||r.Z<-180) { r.Z=(180-r.Z); } - else if (r.Z<-180) { r.Z=360+r.Z; } - return r; - } private string LoadAnim(string anim) { ulong startTime = Util.GetTickCount64(); @@ -797,41 +780,5 @@ namespace RageCoop.Client return anim; } #endregion - - #region QUEUED ACTIONS - #region ENTER-VEHICLE - - /// - /// Tell this character to enter a vehicle and do callback when the task is finished. - /// - /// - /// - /// callback function to be invoked when done, accepting first argument that indicates whether the operation is successful. - public void EnterVehicle(SyncedVehicle veh,VehicleSeat seat, Action callback) - { - Main.QueueAction(new Func(() => - { - MainPed.Task.EnterVehicle(veh.MainVehicle, seat,-1,2,EnterVehicleFlags.AllowJacking|EnterVehicleFlags.WarpToDoor); - return true; - })); - int i = 0; - float maxwait = Game.FPS*5; - Main.QueueAction(new Func(() => - { - i++; - if ((_lastEnteringVehicle && !MainPed.IsGettingIntoVehicle)||i>maxwait) - { - callback(MainPed.IsInVehicle()); - _isEnteringVehicle=false; - return true; - } - _lastEnteringVehicle = MainPed.IsGettingIntoVehicle; - return false; - })); - - } - #endregion - - #endregion } } diff --git a/Client/Sync/Entities/SyncedVehicle.cs b/Client/Sync/Entities/SyncedVehicle.cs index 3f15186..813af82 100644 --- a/Client/Sync/Entities/SyncedVehicle.cs +++ b/Client/Sync/Entities/SyncedVehicle.cs @@ -338,7 +338,7 @@ namespace RageCoop.Client } Function.Call(Hash.SET_VEHICLE_BRAKE_LIGHTS, MainVehicle.Handle, BrakeLightsOn); - MainVehicle.SetVehicleDamageModel(DamageModel); + MainVehicle.SetDamageModel(DamageModel); } MainVehicle.LockStatus=LockStatus; diff --git a/Client/Util.cs b/Client/Util.cs index b8bcd51..af56d5b 100644 --- a/Client/Util.cs +++ b/Client/Util.cs @@ -12,9 +12,13 @@ using System.Diagnostics; namespace RageCoop.Client { - public enum ETasks + /// + /// + /// + internal enum ETasks { - CLIMB_LADDER = 47 + CLIMB_LADDER = 47, + EnterVehicle = 160, } internal static partial class Util @@ -105,6 +109,180 @@ namespace RageCoop.Client } + + + public static bool IsBetween(this T item, T start, T end) + { + return Comparer.Default.Compare(item, start) >= 0 && Comparer.Default.Compare(item, end) <= 0; + } + + public static bool Compare(this Dictionary item, Dictionary item2) + { + if (item == null || item2 == null || item.Count != item2.Count) + { + return false; + } + + foreach (KeyValuePair pair in item) + { + if (item2.TryGetValue(pair.Key, out Y value) && Equals(value, pair.Value)) + { + continue; + } + + // TryGetValue() or Equals failed + return false; + } + + // No difference between item and item2 + return true; + } + + #region MATH + public static Vector3 LinearVectorLerp(Vector3 start, Vector3 end, ulong currentTime, int duration) + { + return new Vector3() + { + X = LinearFloatLerp(start.X, end.X, currentTime, duration), + Y = LinearFloatLerp(start.Y, end.Y, currentTime, duration), + Z = LinearFloatLerp(start.Z, end.Z, currentTime, duration), + }; + } + + public static float LinearFloatLerp(float start, float end, ulong currentTime, int duration) + { + return (end - start) * currentTime / duration + start; + } + + public static float Lerp(float from, float to, float fAlpha) + { + return (from * (1.0f - fAlpha)) + (to * fAlpha); //from + (to - from) * fAlpha + } + + public static Vector3 RotationToDirection(Vector3 rotation) + { + double z = DegToRad(rotation.Z); + double x = DegToRad(rotation.X); + double num = Math.Abs(Math.Cos(x)); + + return new Vector3 + { + X = (float)(-Math.Sin(z) * num), + Y = (float)(Math.Cos(z) * num), + Z = (float)Math.Sin(x) + }; + } + + + #endregion + + public static Model ModelRequest(this int hash) + { + Model model = new Model(hash); + + if (!model.IsValid) + { + //GTA.UI.Notification.Show("~y~Not valid!"); + return null; + } + + if (!model.IsLoaded) + { + return model.Request(1000) ? model : null; + } + + return model; + } + + #region PED + + public static byte GetPedSpeed(this Ped ped) + { + if (ped.IsSprinting) + { + return 3; + } + if (ped.IsRunning) + { + return 2; + } + if (ped.IsWalking) + { + return 1; + } + + return 0; + } + + public static Dictionary GetPedClothes(this Ped ped) + { + Dictionary result = new Dictionary(); + for (byte i = 0; i < 11; i++) + { + short mod = Function.Call(Hash.GET_PED_DRAWABLE_VARIATION, ped.Handle, i); + result.Add(i, mod); + } + return result; + } + + public static PedDataFlags GetPedFlags(this Ped ped) + { + PedDataFlags flags = PedDataFlags.None; + + if (ped.IsAiming || ped.IsOnTurretSeat()) + { + flags |= PedDataFlags.IsAiming; + } + + + if (ped.IsReloading) + { + flags |= PedDataFlags.IsReloading; + } + + if (ped.IsJumping) + { + flags |= PedDataFlags.IsJumping; + } + + if (ped.IsRagdoll) + { + flags |= PedDataFlags.IsRagdoll; + } + + if (ped.IsOnFire) + { + flags |= PedDataFlags.IsOnFire; + } + + if (ped.IsInParachuteFreeFall) + { + flags |= PedDataFlags.IsInParachuteFreeFall; + } + + if (ped.ParachuteState == ParachuteState.Gliding) + { + flags |= PedDataFlags.IsParachuteOpen; + } + + if (Function.Call(Hash.GET_IS_TASK_ACTIVE, ped.Handle, ETasks.CLIMB_LADDER)) // USING_LADDER + { + flags |= PedDataFlags.IsOnLadder; + } + + if (ped.IsVaulting && !Function.Call(Hash.GET_IS_TASK_ACTIVE, ped.Handle, ETasks.CLIMB_LADDER)) + { + flags |= PedDataFlags.IsVaulting; + } + + if (ped.IsInCover || ped.IsGoingIntoCover) + { + flags |=PedDataFlags.IsInCover; + } + + return flags; + } + public static string[] GetReloadingAnimation(this Ped ped) { switch (ped.Weapons.Current.Hash) @@ -188,94 +366,134 @@ namespace RageCoop.Client case WeaponHash.MG: return new string[2] { "weapons@machinegun@mg_str", "reload_aim" }; default: - GTA.UI.Notification.Show($"~r~Reloading failed! Weapon ~g~[{ped.Weapons.Current.Hash}]~r~ could not be found!"); + Main.Logger.Warning($"~r~Reloading failed! Weapon ~g~[{ped.Weapons.Current.Hash}]~r~ could not be found!"); return null; } } - public static Model ModelRequest(this int hash) + public static VehicleSeat GetNearestSeat(Ped ped, Vehicle veh, float distanceToignoreDoors = 50f) { - Model model = new Model(hash); - - if (!model.IsValid) + float num = 99f; + int result = -2; + Dictionary dictionary = new Dictionary(); + dictionary.Add("door_dside_f", -1); + dictionary.Add("door_pside_f", 0); + dictionary.Add("door_dside_r", 1); + dictionary.Add("door_pside_r", 2); + foreach (string text in dictionary.Keys) { - //GTA.UI.Notification.Show("~y~Not valid!"); - return null; - } - - if (!model.IsLoaded) - { - return model.Request(1000) ? model : null; - } - - return model; - } - - public static bool IsBetween(this T item, T start, T end) - { - return Comparer.Default.Compare(item, start) >= 0 && Comparer.Default.Compare(item, end) <= 0; - } - - public static bool Compare(this Dictionary item, Dictionary item2) - { - if (item == null || item2 == null || item.Count != item2.Count) - { - return false; - } - - foreach (KeyValuePair pair in item) - { - if (item2.TryGetValue(pair.Key, out Y value) && Equals(value, pair.Value)) + bool flag = veh.Bones[text].Position != Vector3.Zero; + if (flag) { - continue; + float num2 = ped.Position.DistanceTo(Function.Call(Hash.GET_WORLD_POSITION_OF_ENTITY_BONE, new InputArgument[] + { + veh, + veh.Bones[text].Index + })); + bool flag2 = (num2 < distanceToignoreDoors) && (num2 < num)&& IsSeatUsableByPed(ped, veh, dictionary[text]); + if (flag2) + { + num = num2; + result = dictionary[text]; + } + } + } + return (VehicleSeat)result; + } + public static bool IsSeatUsableByPed(Ped ped, Vehicle veh, int _seat) + { + VehicleSeat seat = (VehicleSeat)_seat; + bool result = false; + bool flag = veh.IsSeatFree(seat); + if (flag) + { + result = true; + } + else + { + + bool isDead = veh.GetPedOnSeat(seat).IsDead; + if (isDead) + { + result = true; + } + else + { + int num = Function.Call(Hash.GET_RELATIONSHIP_BETWEEN_PEDS, new InputArgument[] + { + ped, + veh.GetPedOnSeat(seat) + }); + bool flag2 = num > 2; + if (flag2) + { + result = true; + } } - // TryGetValue() or Equals failed - return false; } - - // No difference between item and item2 - return true; + return result; } - - public static Vector3 LinearVectorLerp(Vector3 start, Vector3 end, ulong currentTime, int duration) + public static bool IsTaskActive(this Ped p,ETasks task) { - return new Vector3() + return Function.Call(Hash.GET_IS_TASK_ACTIVE, p.Handle, task); + } + public static Vector3 GetAimCoord(this Ped p) + { + var weapon = p.Weapons.CurrentWeaponObject; + if (p.IsOnTurretSeat()) { return p.GetLookingCoord(); } + if (weapon!=null) { - X = LinearFloatLerp(start.X, end.X, currentTime, duration), - Y = LinearFloatLerp(start.Y, end.Y, currentTime, duration), - Z = LinearFloatLerp(start.Z, end.Z, currentTime, duration), - }; - } + // Not very accurate, but doesn't matter + Vector3 dir = weapon.RightVector; + return weapon.Position+dir*20; - public static float LinearFloatLerp(float start, float end, ulong currentTime, int duration) - { - return (end - start) * currentTime / duration + start; - } + /* + RaycastResult result = World.Raycast(weapon.Position+dir, weapon.Position+dir*10000, IntersectFlags.Everything, p.IsInVehicle() ? (Entity)p : p.CurrentVehicle); - public static float Lerp(float from, float to, float fAlpha) - { - return (from * (1.0f - fAlpha)) + (to * fAlpha); //from + (to - from) * fAlpha - } - - public static byte GetPedSpeed(this Ped ped) - { - if (ped.IsSprinting) - { - return 3; + if (result.DidHit) + { + return result.HitPosition; + } + else + { + return weapon.Position+dir*20; + } + */ } - if (ped.IsRunning) - { - return 2; - } - if (ped.IsWalking) - { - return 1; - } - - return 0; + return GetLookingCoord(p); + } + public static Vector3 GetLookingCoord(this Ped p) + { + EntityBone b = p.Bones[Bone.FacialForehead]; + Vector3 v = b.UpVector.Normalized; + return b.Position+200*v; } + public static void StayInCover(this Ped p) + { + Function.Call(Hash.TASK_STAY_IN_COVER, p); + } + public static VehicleSeat GetSeatTryingToEnter(this Ped p) + { + return (VehicleSeat)Function.Call(Hash.GET_SEAT_PED_IS_TRYING_TO_ENTER, p); + } + + public static Vector3 GetMuzzlePosition(this Ped p) + { + var w = p.Weapons.CurrentWeaponObject; + if (w!=null) + { + var hash = p.Weapons.Current.Hash; + if (MuzzleBoneIndexes.ContainsKey(hash)) { return w.Bones[MuzzleBoneIndexes[hash]].Position; } + return w.Position; + } + return p.Bones[Bone.SkelRightHand].Position; + } + + #endregion + + #region VEHICLE public static VehicleDataFlags GetVehicleFlags(this Vehicle veh) { @@ -336,63 +554,6 @@ namespace RageCoop.Client return flags; } - public static PedDataFlags GetPedFlags(this Ped ped) - { - PedDataFlags flags = PedDataFlags.None; - - if (ped.IsAiming || ped.IsOnTurretSeat()) - { - flags |= PedDataFlags.IsAiming; - } - - - if (ped.IsReloading) - { - flags |= PedDataFlags.IsReloading; - } - - if (ped.IsJumping) - { - flags |= PedDataFlags.IsJumping; - } - - if (ped.IsRagdoll) - { - flags |= PedDataFlags.IsRagdoll; - } - - if (ped.IsOnFire) - { - flags |= PedDataFlags.IsOnFire; - } - - if (ped.IsInParachuteFreeFall) - { - flags |= PedDataFlags.IsInParachuteFreeFall; - } - - if (ped.ParachuteState == ParachuteState.Gliding) - { - flags |= PedDataFlags.IsParachuteOpen; - } - - if (Function.Call(Hash.GET_IS_TASK_ACTIVE, ped.Handle, ETasks.CLIMB_LADDER)) // USING_LADDER - { - flags |= PedDataFlags.IsOnLadder; - } - - if (ped.IsVaulting && !Function.Call(Hash.GET_IS_TASK_ACTIVE, ped.Handle, ETasks.CLIMB_LADDER)) - { - flags |= PedDataFlags.IsVaulting; - } - - if (ped.IsInCover || ped.IsGoingIntoCover) - { - flags |=PedDataFlags.IsInCover; - } - - return flags; - } public static bool HasFlag(this PedDataFlags flagToCheck,PedDataFlags flag) { @@ -404,16 +565,6 @@ namespace RageCoop.Client return (flagToCheck & flag)!=0; } - public static Dictionary GetPedClothes(this Ped ped) - { - Dictionary result = new Dictionary(); - for (byte i = 0; i < 11; i++) - { - short mod = Function.Call(Hash.GET_PED_DRAWABLE_VARIATION, ped.Handle, i); - result.Add(i, mod); - } - return result; - } public static Dictionary GetWeaponComponents(this Weapon weapon) { @@ -508,32 +659,8 @@ namespace RageCoop.Client } return ps; } - public static void SetOnFire(this Entity e,bool toggle) - { - if (toggle) - { - Function.Call(Hash.START_ENTITY_FIRE, e.Handle); - } - else - { - Function.Call(Hash.STOP_ENTITY_FIRE, e.Handle); - } - } - public static SyncedPed GetSyncEntity(this Ped p) - { - if(p == null) { return null; } - var c = EntityPool.GetPedByHandle(p.Handle); - if(c==null) { EntityPool.Add(c=new SyncedPed(p)); } - return c; - } - public static SyncedVehicle GetSyncEntity(this Vehicle veh) - { - if(veh == null) { return null; } - var v=EntityPool.GetVehicleByHandle(veh.Handle); - if (v==null) { EntityPool.Add(v=new SyncedVehicle(veh)); } - return v; - } - public static void SetVehicleDamageModel(this Vehicle veh, VehicleDamageModel model, bool leavedoors = true) + + public static void SetDamageModel(this Vehicle veh, VehicleDamageModel model, bool leavedoors = true) { for (int i = 0; i < 8; i++) { @@ -590,132 +717,46 @@ namespace RageCoop.Client veh.IsRightHeadLightBroken = model.RightHeadLightBroken > 0; } + + #endregion + + public static void SetOnFire(this Entity e,bool toggle) + { + if (toggle) + { + Function.Call(Hash.START_ENTITY_FIRE, e.Handle); + } + else + { + Function.Call(Hash.STOP_ENTITY_FIRE, e.Handle); + } + } + + public static SyncedPed GetSyncEntity(this Ped p) + { + if(p == null) { return null; } + var c = EntityPool.GetPedByHandle(p.Handle); + if(c==null) { EntityPool.Add(c=new SyncedPed(p)); } + return c; + } + + public static SyncedVehicle GetSyncEntity(this Vehicle veh) + { + if(veh == null) { return null; } + var v=EntityPool.GetVehicleByHandle(veh.Handle); + if (v==null) { EntityPool.Add(v=new SyncedVehicle(veh)); } + return v; + } + + public static double DegToRad(double deg) { return deg * Math.PI / 180.0; } - public static Vector3 RotationToDirection(Vector3 rotation) - { - double z = DegToRad(rotation.Z); - double x = DegToRad(rotation.X); - double num = Math.Abs(Math.Cos(x)); + - return new Vector3 - { - X = (float)(-Math.Sin(z) * num), - Y = (float)(Math.Cos(z) * num), - Z = (float)Math.Sin(x) - }; - } - - - public static VehicleSeat getNearestSeat(Ped ped, Vehicle veh, float distanceToignoreDoors=50f) - { - float num = 99f; - int result = -2; - Dictionary dictionary = new Dictionary(); - dictionary.Add("door_dside_f", -1); - dictionary.Add("door_pside_f", 0); - dictionary.Add("door_dside_r", 1); - dictionary.Add("door_pside_r", 2); - foreach (string text in dictionary.Keys) - { - bool flag = veh.Bones[text].Position != Vector3.Zero; - if (flag) - { - float num2 = ped.Position.DistanceTo(Function.Call(Hash.GET_WORLD_POSITION_OF_ENTITY_BONE, new InputArgument[] - { - veh, - veh.Bones[text].Index - })); - bool flag2 = (num2 < distanceToignoreDoors) && (num2 < num )&& IsSeatUsableByPed(ped, veh, dictionary[text]); - if (flag2) - { - num = num2; - result = dictionary[text]; - } - } - } - return (VehicleSeat)result; - } - public static bool IsSeatUsableByPed(Ped ped, Vehicle veh, int _seat, bool allowJacking=false) - { - /* - - */ - if (!allowJacking) - { - return veh.IsSeatFree((VehicleSeat)_seat); - } - else - { - VehicleSeat seat = (VehicleSeat)_seat; - bool result = false; - bool flag = veh.IsSeatFree(seat); - if (flag) - { - result = true; - } - else - { - - bool isDead = veh.GetPedOnSeat(seat).IsDead; - if (isDead) - { - result = true; - } - else - { - int num = Function.Call(Hash.GET_RELATIONSHIP_BETWEEN_PEDS, new InputArgument[] - { - ped, - veh.GetPedOnSeat(seat) - }); - bool flag2 = num > 2; - if (flag2) - { - result = true; - } - } - - } - return result; - } - } - public static Vector3 GetAimCoord(this Ped p) - { - var weapon = p.Weapons.CurrentWeaponObject; - if (p.IsOnTurretSeat()) { return p.GetLookingCoord(); } - if (weapon!=null) - { - Vector3 dir = weapon.RightVector; - return weapon.Position+dir*20; - - - RaycastResult result = World.Raycast(weapon.Position+dir, weapon.Position+dir*10000, IntersectFlags.Everything, p.IsInVehicle() ? (Entity)p : p.CurrentVehicle); - - if (result.DidHit) - { - return result.HitPosition; - } - else - { - return weapon.Position+dir*20; - } - } - return GetLookingCoord(p); - } - public static Vector3 GetLookingCoord(this Ped p) - { - EntityBone b = p.Bones[Bone.FacialForehead]; - Vector3 v = b.UpVector.Normalized; - return b.Position+200*v; - } - public static bool IsWeapon(this Entity e) - { - return WeaponModels.Contains(e.Model); - } + public static bool IsTurretSeat(this Vehicle veh, int seat) { if (!Function.Call(Hash.DOES_VEHICLE_HAVE_WEAPONS, veh.Handle)) @@ -761,14 +802,6 @@ namespace RageCoop.Client if (P.CurrentVehicle == null) { return false; } return IsTurretSeat(P.CurrentVehicle, (int)P.SeatIndex); } - public static void StayInCover(this Ped p) - { - Function.Call(Hash.TASK_STAY_IN_COVER, p); - } - public static VehicleSeat GetSeatTryingToEnter(this Ped p) - { - return (VehicleSeat)Function.Call(Hash.GET_SEAT_PED_IS_TRYING_TO_ENTER, p); - } public static readonly Model[] WeaponModels = Weapon.GetAllModels(); @@ -793,17 +826,6 @@ namespace RageCoop.Client } return damage; } - public static Vector3 GetMuzzlePosition(this Ped p) - { - var w = p.Weapons.CurrentWeaponObject; - if (w!=null) - { - var hash = p.Weapons.Current.Hash; - if (MuzzleBoneIndexes.ContainsKey(hash)) { return w.Bones[MuzzleBoneIndexes[hash]].Position; } - return w.Position; - } - return p.Bones[Bone.SkelRightHand].Position; - } public static readonly Dictionary MuzzleBoneIndexes = new Dictionary { {WeaponHash.HeavySniper,6},