mirror of
https://github.com/thegeneralist01/Scene-Manager-DevRepo
synced 2026-01-10 15:20:29 +01:00
218 lines
9 KiB
C#
218 lines
9 KiB
C#
using Rage;
|
|
using RAGENativeUI.Elements;
|
|
using SceneManager.Managers;
|
|
using SceneManager.Paths;
|
|
using SceneManager.Waypoints;
|
|
using System;
|
|
using System.Linq;
|
|
|
|
namespace SceneManager.Utils
|
|
{
|
|
internal enum PedType
|
|
{
|
|
/// <summary>Any ped
|
|
/// </summary>
|
|
Any = 0,
|
|
/// <summary>Cop peds
|
|
/// </summary>
|
|
Cop = 1,
|
|
//Firefigher = 2,
|
|
//EMS = 3
|
|
}
|
|
|
|
/// <summary>A collection of potentially useful code snippets for GTA/LSPDFR development.
|
|
/// </summary>
|
|
internal static class Extensions
|
|
{
|
|
/// <summary>Determines if a ped can be considered ambient. Checks any type of ped by default.
|
|
/// </summary>
|
|
internal static bool IsAmbient(this Ped ped, PedType pedType = 0)
|
|
{
|
|
// Universal tasks (virtually all peds seem have this)
|
|
var taskAmbientClips = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 38);
|
|
|
|
// Universal on-foot tasks (virtually all ambient walking peds seem to have this)
|
|
var taskComplexControlMovement = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 35);
|
|
|
|
// Universal in-vehicle tasks (virtually all ambient driver peds seem to have this)
|
|
var taskInVehicleBasic = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 150);
|
|
var taskCarDriveWander = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 151);
|
|
|
|
// On-foot ambient tasks
|
|
var taskPolice = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 58); // From ambient cop (non-freemode) walking around
|
|
var taskWanderingScenario = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 100); // From ambient cop walking around
|
|
var taskUseScenario = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 118); // From ambient cop standing still
|
|
var taskScriptedAnimation = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 134); // From UB ped waiting for interaction
|
|
|
|
// In-vehicle controlled tasks
|
|
var taskControlVehicle = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 169); // From backup unit driving to player
|
|
|
|
// If ped relationship group does not contain "cop" then this extension doesn't apply
|
|
if (pedType == PedType.Cop && !ped.RelationshipGroup.Name.ToLower().Contains("cop"))
|
|
{
|
|
//Game.LogTrivial($"Ped does not belong to a cop relationship group.");
|
|
return false;
|
|
}
|
|
|
|
// Ped is in a vehicle
|
|
if (ped.CurrentVehicle)
|
|
{
|
|
//Game.LogTrivial($"Ped is in a vehicle.");
|
|
// Ped has a controlled driving task
|
|
//if (taskControlVehicle)
|
|
//{
|
|
// //Game.LogTrivial($"Ped has a controlled driving task. (non-ambient)");
|
|
// return false;
|
|
//}
|
|
|
|
// Ped has a wander driving task
|
|
if (taskCarDriveWander)
|
|
{
|
|
//Game.LogTrivial($"Ped has a wander driving task. (ambient)");
|
|
return true;
|
|
}
|
|
|
|
// If the ped is in a vehicle but doesn't have a driving task, then it's a passenger. Check if the vehicle's driver has a driving wander task
|
|
if (ped.CurrentVehicle.Driver && ped.CurrentVehicle.Driver != ped)
|
|
{
|
|
var driverHasWanderTask = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped.CurrentVehicle.Driver, 151);
|
|
if (driverHasWanderTask)
|
|
{
|
|
//Game.LogTrivial($"Ped is a passenger. Vehicle's driver has a wander driving task. (ambient)");
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ped.IsOnFoot)
|
|
{
|
|
// Cop ped walking around or standing still
|
|
if ((taskComplexControlMovement && taskWanderingScenario) || (taskAmbientClips && taskUseScenario))
|
|
{
|
|
//Game.LogTrivial($"Ped is wandering around or standing still. (ambient)");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// If nothing else returns true before now, then the ped is probably being controlled and doing something else
|
|
//Game.LogTrivial($"Nothing else has returned true by this point. (non-ambient)");
|
|
return false;
|
|
}
|
|
|
|
/// <summary>Determines if a vehicle and driver are valid.
|
|
/// </summary>
|
|
internal static bool VehicleAndDriverValid(this Vehicle vehicle)
|
|
{
|
|
if (vehicle && vehicle.HasDriver && vehicle.Driver && vehicle.Driver.IsAlive)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>Determines if this vehicle is within the waypoint's collection range.
|
|
/// </summary>
|
|
internal static bool IsNearCollectorWaypoint(this Vehicle vehicle, Waypoint waypoint)
|
|
{
|
|
return vehicle.FrontPosition.DistanceTo2D(waypoint.Position) <= waypoint.CollectorRadius && Math.Abs(waypoint.Position.Z - vehicle.Position.Z) < 3;
|
|
}
|
|
|
|
internal static bool IsValidForPathCollection(this Vehicle vehicle, Path path)
|
|
{
|
|
if (!vehicle)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var vehicleCollectedOnAnotherPath = PathManager.Paths.Any(p => p != null && p.Number != path.Number && p.CollectedPeds.Any(cp => cp && cp.CurrentVehicle == vehicle));
|
|
if (vehicleCollectedOnAnotherPath)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(path.BlacklistedVehicles.Contains(vehicle))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(vehicle == Game.LocalPlayer.Character.LastVehicle)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (vehicle.Driver)
|
|
{
|
|
if (!vehicle.Driver.IsAlive)
|
|
{
|
|
Game.LogTrivial($"Vehicle's driver is dead.");
|
|
path.BlacklistedVehicles.Add(vehicle);
|
|
return false;
|
|
}
|
|
if (vehicle.IsPoliceVehicle && !vehicle.Driver.IsAmbient())
|
|
{
|
|
Game.LogTrivial($"Vehicle is a non-ambient police vehicle.");
|
|
path.BlacklistedVehicles.Add(vehicle);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if ((vehicle.IsCar || vehicle.IsBike || vehicle.IsBicycle || vehicle.IsQuadBike) && !vehicle.IsSirenOn && vehicle.IsEngineOn && vehicle.IsOnAllWheels && vehicle.Speed > 1 && !path.CollectedPeds.Any(cp => cp && cp.CurrentVehicle == vehicle))
|
|
{
|
|
if (!vehicle.HasDriver)
|
|
{
|
|
vehicle.CreateRandomDriver();
|
|
GameFiber.Yield();
|
|
//while (vehicle && !vehicle.HasDriver)
|
|
//{
|
|
// Game.LogTrivial($"Trying to create new driver");
|
|
// GameFiber.Yield();
|
|
//}
|
|
if(!vehicle)
|
|
{
|
|
return false;
|
|
}
|
|
if(!vehicle.Driver)
|
|
{
|
|
Game.LogTrivial($"Unable to create a new driver");
|
|
vehicle.Delete();
|
|
return false;
|
|
}
|
|
Game.LogTrivial($"Vehicle has a new driver");
|
|
//vehicle.Driver.IsPersistent = true;
|
|
vehicle.Driver.BlockPermanentEvents = true;
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
internal static float GetTextWidth(this UIMenuItem menuItem)
|
|
{
|
|
menuItem.TextStyle.Apply();
|
|
Rage.Native.NativeFunction.Natives.x54CE8AC98E120CAB("STRING"); // _BEGIN_TEXT_COMMAND_GET_WIDTH
|
|
Rage.Native.NativeFunction.Natives.ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(menuItem.Text);
|
|
return Rage.Native.NativeFunction.Natives.x85F061DA64ED2F67<float>(true); // _END_TEXT_COMMAND_GET_WIDTH
|
|
}
|
|
|
|
internal static float GetSelectedItemTextWidth(this UIMenuListScrollerItem<string> scrollerItem)
|
|
{
|
|
if (scrollerItem.OptionCount == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
scrollerItem.GetTextWidth();
|
|
scrollerItem.TextStyle.Apply();
|
|
|
|
Rage.Native.NativeFunction.Natives.x54CE8AC98E120CAB("STRING"); // _BEGIN_TEXT_COMMAND_GET_WIDTH
|
|
Rage.Native.NativeFunction.Natives.ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(scrollerItem.SelectedItem);
|
|
|
|
return Rage.Native.NativeFunction.Natives.x85F061DA64ED2F67<float>(true); // _END_TEXT_COMMAND_GET_WIDTH
|
|
}
|
|
}
|
|
}
|