Files
RAGECOOP-V/Client/Scripts/Util/VehicleExtensions.cs

227 lines
7.6 KiB
C#
Raw Normal View History

2022-10-23 19:02:39 +08:00
using System;
using System.Collections.Generic;
using GTA;
using GTA.Native;
using RageCoop.Core;
namespace RageCoop.Client
{
internal static class VehicleExtensions
{
#region VEHICLE
2022-08-18 20:44:39 +08:00
public static VehicleDataFlags GetVehicleFlags(this SyncedVehicle v)
{
2022-09-06 21:46:35 +08:00
var veh = v.MainVehicle;
VehicleDataFlags flags = 0;
2022-10-23 19:02:39 +08:00
if (veh.IsEngineRunning) flags |= VehicleDataFlags.IsEngineRunning;
2022-10-23 19:02:39 +08:00
if (veh.AreLightsOn) flags |= VehicleDataFlags.AreLightsOn;
2022-10-23 19:02:39 +08:00
if (veh.BrakePower >= 0.01f) flags |= VehicleDataFlags.AreBrakeLightsOn;
2022-10-23 19:02:39 +08:00
if (veh.AreHighBeamsOn) flags |= VehicleDataFlags.AreHighBeamsOn;
2022-10-23 19:02:39 +08:00
if (veh.IsSirenActive) flags |= VehicleDataFlags.IsSirenActive;
2022-10-23 19:02:39 +08:00
if (veh.IsDead) flags |= VehicleDataFlags.IsDead;
2022-10-23 19:02:39 +08:00
if (Function.Call<bool>(Hash.IS_HORN_ACTIVE, veh.Handle)) flags |= VehicleDataFlags.IsHornActive;
2022-08-18 20:44:39 +08:00
if (v.IsSubmarineCar && Function.Call<bool>(Hash._GET_IS_SUBMARINE_VEHICLE_TRANSFORMED, veh.Handle))
flags |= VehicleDataFlags.IsTransformed;
2022-09-05 13:02:09 +02:00
2022-10-23 19:02:39 +08:00
if (v.IsAircraft) flags |= VehicleDataFlags.IsAircraft;
2022-09-05 13:02:09 +02:00
2022-10-23 19:02:39 +08:00
if (v.IsDeluxo && veh.IsDeluxoHovering()) flags |= VehicleDataFlags.IsDeluxoHovering;
2022-09-05 13:02:09 +02:00
2022-10-23 19:02:39 +08:00
if (v.HasRoof) flags |= VehicleDataFlags.HasRoof;
2022-09-05 13:02:09 +02:00
2022-10-23 19:02:39 +08:00
if (v.HasRocketBoost && veh.IsRocketBoostActive()) flags |= VehicleDataFlags.IsRocketBoostActive;
2022-09-05 13:02:09 +02:00
2022-10-23 19:02:39 +08:00
if (v.HasParachute && veh.IsParachuteActive()) flags |= VehicleDataFlags.IsParachuteActive;
2022-09-05 13:02:09 +02:00
2022-10-23 19:02:39 +08:00
if (veh.IsOnFire) flags |= VehicleDataFlags.IsOnFire;
return flags;
}
2022-10-23 19:02:39 +08:00
2022-08-17 23:18:06 +08:00
public static bool IsRocketBoostActive(this Vehicle veh)
{
2022-09-06 21:46:35 +08:00
return Function.Call<bool>(Hash._IS_VEHICLE_ROCKET_BOOST_ACTIVE, veh);
2022-08-17 23:18:06 +08:00
}
2022-10-23 19:02:39 +08:00
2022-09-06 21:46:35 +08:00
public static bool IsParachuteActive(this Vehicle veh)
{
return Function.Call<bool>((Hash)0x3DE51E9C80B116CF, veh);
2022-08-18 08:26:41 +08:00
}
2022-10-23 19:02:39 +08:00
2022-09-06 21:46:35 +08:00
public static void SetRocketBoostActive(this Vehicle veh, bool toggle)
2022-08-17 23:18:06 +08:00
{
2022-09-06 21:46:35 +08:00
Function.Call(Hash._SET_VEHICLE_ROCKET_BOOST_ACTIVE, veh, toggle);
2022-08-17 23:18:06 +08:00
}
2022-10-23 19:02:39 +08:00
2022-09-06 21:46:35 +08:00
public static void SetParachuteActive(this Vehicle veh, bool toggle)
2022-08-18 08:26:41 +08:00
{
2022-09-06 21:46:35 +08:00
Function.Call((Hash)0x0BFFB028B3DD0A97, veh, toggle);
2022-08-18 08:26:41 +08:00
}
2022-10-23 19:02:39 +08:00
public static Dictionary<int, int> GetVehicleMods(this VehicleModCollection mods)
{
2022-10-23 19:02:39 +08:00
var result = new Dictionary<int, int>();
foreach (var mod in mods.ToArray()) result.Add((int)mod.Type, mod.Index);
return result;
}
public static VehicleDamageModel GetVehicleDamageModel(this Vehicle veh)
{
// Broken windows
byte brokenWindows = 0;
2022-10-23 19:02:39 +08:00
for (var i = 0; i < 8; i++)
if (!veh.Windows[(VehicleWindowIndex)i].IsIntact)
brokenWindows |= (byte)(1 << i);
// Broken doors
byte brokenDoors = 0;
byte openedDoors = 0;
2022-10-23 19:02:39 +08:00
foreach (var door in veh.Doors)
if (door.IsBroken)
brokenDoors |= (byte)(1 << (byte)door.Index);
2022-10-23 19:02:39 +08:00
else if (door.IsOpen) openedDoors |= (byte)(1 << (byte)door.Index);
// Bursted tires
short burstedTires = 0;
2022-10-23 19:02:39 +08:00
foreach (var wheel in veh.Wheels.GetAllWheels())
if (wheel.IsBursted)
burstedTires |= (short)(1 << (int)wheel.BoneId);
2022-10-23 19:02:39 +08:00
return new VehicleDamageModel
{
BrokenDoors = brokenDoors,
OpenedDoors = openedDoors,
BrokenWindows = brokenWindows,
BurstedTires = burstedTires,
LeftHeadLightBroken = (byte)(veh.IsLeftHeadLightBroken ? 1 : 0),
RightHeadLightBroken = (byte)(veh.IsRightHeadLightBroken ? 1 : 0)
};
}
2022-07-20 17:50:01 +08:00
2022-07-12 17:15:54 +08:00
public static void SetDamageModel(this Vehicle veh, VehicleDamageModel model, bool leavedoors = true)
{
2022-10-23 19:02:39 +08:00
for (var i = 0; i < 8; i++)
2022-07-12 17:15:54 +08:00
{
var door = veh.Doors[(VehicleDoorIndex)i];
if ((model.BrokenDoors & (byte)(1 << i)) != 0)
{
2022-10-23 19:02:39 +08:00
if (!door.IsBroken) door.Break(leavedoors);
2022-07-13 00:20:06 +08:00
continue;
2022-07-12 17:15:54 +08:00
}
2022-10-23 19:02:39 +08:00
if (door.IsBroken)
2022-07-12 17:15:54 +08:00
{
// The vehicle can only fix a door if the vehicle was completely fixed
veh.Repair();
return;
}
2022-10-23 19:02:39 +08:00
2022-07-12 17:15:54 +08:00
if ((model.OpenedDoors & (byte)(1 << i)) != 0)
{
2022-10-23 19:02:39 +08:00
if (!door.IsOpen && !door.IsBroken) door.Open();
2022-07-12 17:15:54 +08:00
}
else if (door.IsOpen)
{
2022-10-23 19:02:39 +08:00
if (!door.IsBroken) door.Close();
2022-07-12 17:15:54 +08:00
}
if ((model.BrokenWindows & (byte)(1 << i)) != 0)
veh.Windows[(VehicleWindowIndex)i].Smash();
2022-10-23 19:02:39 +08:00
else if (!veh.Windows[(VehicleWindowIndex)i].IsIntact) veh.Windows[(VehicleWindowIndex)i].Repair();
2022-07-12 17:15:54 +08:00
}
2022-10-23 19:02:39 +08:00
foreach (var wheel in veh.Wheels)
2022-07-12 17:15:54 +08:00
if ((model.BurstedTires & (short)(1 << (int)wheel.BoneId)) != 0)
{
if (!wheel.IsBursted)
{
wheel.Puncture();
wheel.Burst();
}
}
else if (wheel.IsBursted)
{
wheel.Fix();
}
veh.IsLeftHeadLightBroken = model.LeftHeadLightBroken > 0;
veh.IsRightHeadLightBroken = model.RightHeadLightBroken > 0;
}
public static Dictionary<int, int> GetPassengers(this Vehicle veh)
{
2022-10-23 19:02:39 +08:00
var ps = new Dictionary<int, int>();
var d = veh.Driver;
2022-10-23 19:02:39 +08:00
if (d != null && d.IsSittingInVehicle()) ps.Add(-1, d.GetSyncEntity().ID);
foreach (var p in veh.Passengers)
if (p.IsSittingInVehicle())
2022-09-06 21:46:35 +08:00
ps.Add((int)p.SeatIndex, p.GetSyncEntity().ID);
return ps;
}
public static void SetDeluxoHoverState(this Vehicle deluxo, bool hover)
{
Function.Call(Hash._SET_VEHICLE_HOVER_TRANSFORM_PERCENTAGE, deluxo, hover ? 1f : 0f);
}
2022-10-23 19:02:39 +08:00
public static bool IsDeluxoHovering(this Vehicle deluxo)
{
2022-09-06 21:46:35 +08:00
return Math.Abs(deluxo.Bones[27].ForwardVector.GetCosTheta(deluxo.ForwardVector) - 1) > 0.05;
}
2022-10-23 19:02:39 +08:00
public static void SetDeluxoWingRatio(this Vehicle v, float ratio)
{
Function.Call(Hash._SET_SPECIALFLIGHT_WING_RATIO, v, ratio);
}
2022-10-23 19:02:39 +08:00
public static float GetDeluxoWingRatio(this Vehicle v)
{
2022-09-06 21:46:35 +08:00
return v.Bones[99].Position.DistanceTo(v.Bones[92].Position) - 1.43f;
}
2022-10-23 19:02:39 +08:00
public static float GetNozzleAngel(this Vehicle plane)
{
return Function.Call<float>(Hash._GET_VEHICLE_FLIGHT_NOZZLE_POSITION, plane);
}
2022-10-23 19:02:39 +08:00
public static bool HasNozzle(this Vehicle v)
{
switch (v.Model.Hash)
{
// Hydra
case 970385471:
return true;
// Avenger
case -2118308144:
return true;
2022-05-31 09:24:28 +08:00
// Tula
case 1043222410:
return true;
// Avenger
case 408970549:
return true;
}
2022-10-23 19:02:39 +08:00
return false;
}
2022-10-23 19:02:39 +08:00
public static void SetNozzleAngel(this Vehicle plane, float ratio)
{
Function.Call(Hash.SET_VEHICLE_FLIGHT_NOZZLE_POSITION, plane, ratio);
}
2022-10-23 19:02:39 +08:00
#endregion
}
2022-10-23 19:02:39 +08:00
}