Customizable key binding and passenger fix.
This commit is contained in:
parent
74d9e69fe4
commit
6bacaad1ce
@ -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,
|
||||
|
117
Client/Main.cs
117
Client/Main.cs
@ -17,7 +17,7 @@ namespace RageCoop.Client
|
||||
/// <summary>
|
||||
/// Don't use it!
|
||||
/// </summary>
|
||||
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<int>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace RageCoop.Client.Menus
|
||||
/// <summary>
|
||||
/// Don't use it!
|
||||
/// </summary>
|
||||
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
|
||||
/// <summary>
|
||||
/// Don't use it!
|
||||
/// </summary>
|
||||
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)
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
/// <summary>
|
||||
/// Don't use it!
|
||||
/// </summary>
|
||||
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());
|
||||
|
||||
/// <summary>
|
||||
/// Don't use it!
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
}
|
@ -26,8 +26,9 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
|
||||
<DocumentationFile>bin\Debug\CoopClient.xml</DocumentationFile>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@ -135,9 +136,9 @@
|
||||
<Compile Include="Sync\Entities\SyncedVehicle.cs" />
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="MapLoader.cs" />
|
||||
<Compile Include="Menus\MenusMain.cs" />
|
||||
<Compile Include="Menus\RageCoopMenu.cs" />
|
||||
<Compile Include="Menus\Sub\Servers.cs" />
|
||||
<Compile Include="Menus\Sub\Settings.cs" />
|
||||
<Compile Include="Menus\Sub\SettingsMenu.cs" />
|
||||
<Compile Include="Networking\Networking.cs" />
|
||||
<Compile Include="PlayerList.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
@ -1,4 +1,5 @@
|
||||
#undef DEBUG
|
||||
using System.Windows.Forms;
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
/// <summary>
|
||||
@ -29,6 +30,15 @@ namespace RageCoop.Client
|
||||
/// </summary>
|
||||
public int LogLevel = 2;
|
||||
|
||||
/// <summary>
|
||||
/// The key to open menu
|
||||
/// </summary>
|
||||
public Keys MenuKey { get; set; } = Keys.F9;
|
||||
|
||||
/// <summary>
|
||||
/// The key to enter a vehicle as passenger.
|
||||
/// </summary>
|
||||
public Keys PassengerKey { get; set; }=Keys.G;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,6 @@ namespace RageCoop.Client
|
||||
private bool _lastRagdoll=false;
|
||||
private ulong _lastRagdollTime=0;
|
||||
private bool _lastInCover = false;
|
||||
private bool _isEnteringVehicle = false;
|
||||
/// <summary>
|
||||
/// The latest character model hash (may not have been applied yet)
|
||||
/// </summary>
|
||||
@ -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
|
||||
|
||||
/// <summary>
|
||||
/// Tell this character to enter a vehicle and do callback when the task is finished.
|
||||
/// </summary>
|
||||
/// <param name="veh"></param>
|
||||
/// <param name="seat"></param>
|
||||
/// <param name="callback"> callback function to be invoked when done, accepting first argument that indicates whether the operation is successful.</param>
|
||||
public void EnterVehicle(SyncedVehicle veh,VehicleSeat seat, Action<bool> callback)
|
||||
{
|
||||
Main.QueueAction(new Func<bool>(() =>
|
||||
{
|
||||
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<bool>(() =>
|
||||
{
|
||||
i++;
|
||||
if ((_lastEnteringVehicle && !MainPed.IsGettingIntoVehicle)||i>maxwait)
|
||||
{
|
||||
callback(MainPed.IsInVehicle());
|
||||
_isEnteringVehicle=false;
|
||||
return true;
|
||||
}
|
||||
_lastEnteringVehicle = MainPed.IsGettingIntoVehicle;
|
||||
return false;
|
||||
}));
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
630
Client/Util.cs
630
Client/Util.cs
@ -12,9 +12,13 @@ using System.Diagnostics;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
public enum ETasks
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
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<T>(this T item, T start, T end)
|
||||
{
|
||||
return Comparer<T>.Default.Compare(item, start) >= 0 && Comparer<T>.Default.Compare(item, end) <= 0;
|
||||
}
|
||||
|
||||
public static bool Compare<T, Y>(this Dictionary<T, Y> item, Dictionary<T, Y> item2)
|
||||
{
|
||||
if (item == null || item2 == null || item.Count != item2.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<T, Y> 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<byte, short> GetPedClothes(this Ped ped)
|
||||
{
|
||||
Dictionary<byte, short> result = new Dictionary<byte, short>();
|
||||
for (byte i = 0; i < 11; i++)
|
||||
{
|
||||
short mod = Function.Call<short>(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<bool>(Hash.GET_IS_TASK_ACTIVE, ped.Handle, ETasks.CLIMB_LADDER)) // USING_LADDER
|
||||
{
|
||||
flags |= PedDataFlags.IsOnLadder;
|
||||
}
|
||||
|
||||
if (ped.IsVaulting && !Function.Call<bool>(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<string, int> dictionary = new Dictionary<string, int>();
|
||||
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<T>(this T item, T start, T end)
|
||||
{
|
||||
return Comparer<T>.Default.Compare(item, start) >= 0 && Comparer<T>.Default.Compare(item, end) <= 0;
|
||||
}
|
||||
|
||||
public static bool Compare<T, Y>(this Dictionary<T, Y> item, Dictionary<T, Y> item2)
|
||||
{
|
||||
if (item == null || item2 == null || item.Count != item2.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<T, Y> 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<Vector3>(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<int>(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<bool>(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<int>(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<bool>(Hash.GET_IS_TASK_ACTIVE, ped.Handle, ETasks.CLIMB_LADDER)) // USING_LADDER
|
||||
{
|
||||
flags |= PedDataFlags.IsOnLadder;
|
||||
}
|
||||
|
||||
if (ped.IsVaulting && !Function.Call<bool>(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<byte, short> GetPedClothes(this Ped ped)
|
||||
{
|
||||
Dictionary<byte, short> result = new Dictionary<byte, short>();
|
||||
for (byte i = 0; i < 11; i++)
|
||||
{
|
||||
short mod = Function.Call<short>(Hash.GET_PED_DRAWABLE_VARIATION, ped.Handle, i);
|
||||
result.Add(i, mod);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Dictionary<uint, bool> 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<string, int> dictionary = new Dictionary<string, int>();
|
||||
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<Vector3>(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<int>(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<bool>(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<int>(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<WeaponHash, int> MuzzleBoneIndexes = new Dictionary<WeaponHash, int>
|
||||
{
|
||||
{WeaponHash.HeavySniper,6},
|
||||
|
Loading…
x
Reference in New Issue
Block a user