Eddlm

Safer Chases v1.5

Jan 26th, 2016
2,565
1
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 18.03 KB | None | 1 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Globalization;
  5. using System.IO;
  6. using System.Linq;
  7. using LSPD_First_Response.Mod.API;
  8. using Rage;
  9. using Rage.Native;
  10.  
  11.  
  12. namespace RAGEComputer
  13. {
  14.     public class PortedAI : Plugin
  15.     {
  16.         public static float CopMaxRelativeSpeed = 1;
  17.         uint ReferenceTime = Game.GameTime;
  18.         public static bool PreventSuspectRammings = true;
  19.         public static bool AllowTakePrimary = true;
  20.         public static bool Debug = true;
  21.         public static string ScriptVer = "v1.5";
  22.         public static bool CopsYieldToPlayer = true;
  23.         public static bool HelpCopsManageTraffic = true;
  24.  
  25.         uint GameRefTime = Game.GameTime;
  26.         public List<PursuitHandler> Pursuits { get; set; }
  27.         public static List<Vehicle> CopVehiclesInThisPursuit  { get; set; }
  28.  
  29.         public override void Initialize()
  30.         {
  31.             Game.FrameRender += FrameRender;
  32.             Pursuits = new List<PursuitHandler>();
  33.             CopVehiclesInThisPursuit = new List<Vehicle>();
  34.  
  35.             Rage.Game.Console.Print("SAFER CHASES "+ ScriptVer + " LOADED");
  36.  
  37.         }
  38.  
  39.         private void FrameRender(object sender, GraphicsEventArgs graphicsEventArgs)
  40.         {
  41.             LookForFleeingVehicles();
  42.                
  43.             if(Game.GameTime > GameRefTime + 1000)
  44.             {
  45.                 GameRefTime = Game.GameTime;
  46.                 UpdateCopVehicleList();
  47.  
  48.             }
  49.                 lock (Pursuits)
  50.                     foreach (var pursuit in Pursuits)
  51.                     {
  52.                         pursuit.Update();
  53.                     }
  54.         }
  55.  
  56.         public static void UpdateCopVehicleList()
  57.         {
  58.             CopVehiclesInThisPursuit.Clear();
  59.             foreach (Vehicle veh in World.GetAllVehicles())
  60.             {
  61.                 if (veh.IsPoliceVehicle && CanWeUse(veh.GetPedOnSeat(-1))&& veh.GetPedOnSeat(-1).Handle != Game.LocalPlayer.Character.Handle)
  62.                 {
  63.                     CopVehiclesInThisPursuit.Add(veh);
  64.                 }
  65.             }
  66.         }
  67.         public static Vehicle GetLastVehicle(Ped RecieveOrder)
  68.         {
  69.             if (CanWeUse(RecieveOrder.CurrentVehicle)) return RecieveOrder.CurrentVehicle; else if (CanWeUse(RecieveOrder.LastVehicle)) return RecieveOrder.LastVehicle; else return null;
  70.         }
  71.         public static bool CanWeUse(Entity entity)
  72.         {
  73.             return entity != null && entity.Exists() && entity.IsValid();
  74.         }
  75.  
  76.         private void LoadSettings()
  77.         {
  78.             var s = IniSettings.Read("Plugins\\LSPDFR\\SaferChases.ini");
  79.             CopMaxRelativeSpeed = s.CopMaxRelativeSpeed;
  80.             PreventSuspectRammings = s.PreventSuspectRammings;
  81.             AllowTakePrimary = s.AllowTakePrimary;
  82.             Debug = s.Debug;
  83.             CopsYieldToPlayer = s.CopsYieldToPlayer;
  84.             HelpCopsManageTraffic = s.HelpCopsManageTraffic;
  85.         }
  86.  
  87.         public static bool IsPedInList(Ped candidate, List<Ped> list)
  88.         {
  89.             return list.Any(p => p.Handle == candidate.Handle);
  90.         }
  91.         private LHandle _currentPursuit;
  92.         private void LookForFleeingVehicles()
  93.         {
  94.             var pursuit = LSPD_First_Response.Mod.API.Functions.GetActivePursuit();
  95.  
  96.  
  97.             if (_currentPursuit == null && pursuit != null)
  98.             {
  99.                 LoadSettings();
  100.                 if (Debug) Game.DisplayNotification("Safer Chases ~g~loaded~w~ for this pursuit.~n~");
  101.  
  102.                 _currentPursuit = pursuit;
  103.  
  104.                 foreach (
  105.                     var veh in
  106.                         Functions.GetPursuitPeds(pursuit)
  107.                             .Where(ped => ped.IsInAnyVehicle(false) && CanWeUse(GetLastVehicle(ped)))
  108.                             .Select(GetLastVehicle)
  109.                             .Distinct())
  110.                 {
  111.                     Pursuits.Add(new PursuitHandler(pursuit, veh));
  112.                 }
  113.             }
  114.             else if (_currentPursuit != null && pursuit == null)
  115.             {
  116.                 lock (Pursuits) Pursuits.Clear();
  117.                 if (PortedAI.Debug) Game.DisplayNotification("Safer chases ~r~unloaded~w~.~n~");
  118.                 _currentPursuit = null;
  119.             }
  120.         }
  121.  
  122.         public static bool IsThisEntityAheadThatEntity(Entity ent1, Entity ent2)
  123.         {
  124.             Vector3 pos = ent1.Position;
  125.  
  126.             return NativeFunction.CallByName<Vector3>("GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS", ent2, pos.X, pos.Y, pos.Z).Y > 0f;
  127.         }
  128.  
  129.         public static bool isCopInRange(Vector3 Location, float Range)
  130.         {
  131.             return NativeFunction.CallByName<bool>("IS_COP_PED_IN_AREA_3D", Location.X - Range, Location.Y - Range, Location.Z - Range, Location.X + Range, Location.Y + Range, Location.Z + Range);
  132.         }
  133.  
  134.  
  135.         public override void Finally()
  136.         {
  137.  
  138.         }
  139.  
  140.  
  141.     }
  142.  
  143.     public class PursuitHandler
  144.     {
  145.         public PursuitHandler(LHandle pursuit, Vehicle puruitee)
  146.         {
  147.             PursuitParent = pursuit;
  148.             Pursuitee = puruitee;
  149.             _referenceTime = Game.GameTime;
  150.             CanCopsRamSuspect = false;
  151.         }
  152.  
  153.         public LHandle PursuitParent { get; set; }
  154.         public Vehicle Pursuitee { get; set; }
  155.         public bool IsPlayerPrimary { get; set; }
  156.         public bool CanCopsRamSuspect { get; set; }
  157.  
  158.         private uint _referenceTime;
  159.         private Dictionary<Entity, SizedQueue<string>> _debugMessages { get; set; }
  160.  
  161.         private void HandleCopCarefulBehavior()
  162.         {
  163.             int MaxVehicles =0;
  164.             Vehicle playerveh = PortedAI.GetLastVehicle(Game.LocalPlayer.Character);
  165.             foreach (Vehicle veh in PortedAI.CopVehiclesInThisPursuit)
  166.             {
  167.                 if (PortedAI.CanWeUse(veh) && veh.Speed > 1f && veh.IsOnAllWheels)
  168.                 {
  169.                     if (PortedAI.CanWeUse(playerveh) && playerveh.Handle != veh.Handle)
  170.                     {
  171.                         //// YIELD TO PLAYER ////
  172.                         if (PortedAI.CopsYieldToPlayer && PortedAI.CanWeUse(playerveh) && Game.LocalPlayer.Character.IsInAnyPoliceVehicle && Game.IsControlPressed(2, GameControl.VehicleHorn) && (Game.LocalPlayer.Character.Position - veh.Position).Length() < 30f &&
  173.                             NativeFunction.CallByName<Vector3>("GET_ENTITY_SPEED_VECTOR", veh, true).Y > 3f &&
  174.                             playerveh.Speed < NativeFunction.CallByName<Vector3>("GET_ENTITY_SPEED_VECTOR", veh, true).Y + 10f)
  175.                         {
  176.                             NativeFunction.CallByName<int>("APPLY_FORCE_TO_ENTITY", veh, 3, 0f, -0.6f, 0f, 0f, 0f, -0.3f, 0, true, true, true, true, true);
  177.                             if (PortedAI.Debug) Game.DisplayHelp(veh.Model.Name + " YIELDS TO PLAYER", 3000);
  178.                         }
  179.  
  180.                         //// ANTI CRASH INTO PLAYER ////
  181.                         if (veh.DistanceTo(Game.LocalPlayer.Character.Position + Game.LocalPlayer.Character.ForwardVector * -8f) < 6f && NativeFunction.CallByName<Vector3>("GET_ENTITY_SPEED_VECTOR", veh, true).Y + 2f > playerveh.Speed)
  182.                         {
  183.                             NativeFunction.CallByName<int>("APPLY_FORCE_TO_ENTITY", veh, 3, 0f, -0.4f, 0f, 0f, 0f, -0.2f, 0, true, true, true, true, true);
  184.                             if (PortedAI.Debug) Game.DisplayHelp("COP BEHIND TOO CLOSE", 3000);
  185.                         }
  186.  
  187.                         if (NativeFunction.CallByName<Vector3>("GET_ENTITY_SPEED_VECTOR", veh, true).Y > 1f && PortedAI.IsThisEntityAheadThatEntity(Game.LocalPlayer.Character, veh) && (Game.LocalPlayer.Character.Position - veh.Position).Length() < 30f)
  188.                         {
  189.                             if (Game.LocalPlayer.Character.IsInAnyVehicle(true))
  190.                             {
  191.                                 if (NativeFunction.CallByName<Vector3>("GET_ENTITY_SPEED_VECTOR", veh, true).Y > 10f && playerveh.Speed < NativeFunction.CallByName<Vector3>("GET_ENTITY_SPEED_VECTOR", veh, true).Y - PortedAI.CopMaxRelativeSpeed)
  192.                                 {
  193.  
  194.                                     NativeFunction.CallByName<int>("APPLY_FORCE_TO_ENTITY", veh, 3, 0f, -0.6f, 0f, 0f, 0f, -0.2f, 0, true, true, true, true, true);
  195.                                     if (PortedAI.Debug) Game.DisplayHelp(veh.Model.Name + " CAREFUL WITH DRIVING PLAYER", 3000);
  196.                                 }
  197.                             }
  198.                             else
  199.                             {
  200.                                 if (NativeFunction.CallByName<Vector3>("GET_ENTITY_SPEED_VECTOR", veh, true).Y > 10f)
  201.                                 {
  202.                                     NativeFunction.CallByName<int>("APPLY_FORCE_TO_ENTITY", veh, 3, 0f, -0.8f, 0f, 0f, 0f, -0.2f, 0, true, true, true, true, true);
  203.                                     if (PortedAI.Debug) Game.DisplayHelp(veh.Model.Name + " CAREFUL WITH STANDING PLAYER", 3000);
  204.                                 }
  205.                             }
  206.                         }
  207.                         //// ANTI CRASH INTO TRAFFIC ////
  208.                         if (MaxVehicles < 5 && PortedAI.HelpCopsManageTraffic && veh.DistanceTo(Game.LocalPlayer.Character.Position) < 50f)
  209.                         {
  210.                             MaxVehicles++;
  211.                             foreach (Entity saferentity in World.GetAllEntities())
  212.                             {//!Functions.GetPursuitPeds(Functions.GetActivePursuit()).Contains(saferentity) && saferentity.Handle != Game.LocalPlayer.Character.Handle && saferentity.Handle != playerveh.Handle && saferentity.Speed > 1f && saferentity.Position.DistanceTo(veh.Position + veh.ForwardVector * 10f) < 10f &&
  213.                                 if (PortedAI.CanWeUse(saferentity) && saferentity.Speed > 1f && PortedAI.IsThisEntityAheadThatEntity(saferentity, veh) && saferentity.Position.DistanceTo(veh.Position + veh.ForwardVector * 10f) < 10f)
  214.                                 {
  215.                                     if (saferentity.Speed > 5f && saferentity.Speed < NativeFunction.CallByName<Vector3>("GET_ENTITY_SPEED_VECTOR", veh, true).Y - 10f)
  216.                                     {
  217.                                         NativeFunction.CallByName<int>("APPLY_FORCE_TO_ENTITY", veh, 3, 0f, -0.6f, 0f, 0f, 0f, -0.3f, 0, true, true, true, true, true);
  218.  
  219.                                         if (PortedAI.Debug) Game.DisplayHelp(veh.Model.Name + " CAREFUL WITH FAST ENTITY", 3000);
  220.                                         break;
  221.                                     }
  222.                                     if (saferentity.Speed < 5f && NativeFunction.CallByName<Vector3>("GET_ENTITY_SPEED_VECTOR", veh, true).Y > 10f)
  223.                                     {
  224.                                         NativeFunction.CallByName<int>("APPLY_FORCE_TO_ENTITY", veh, 3, 0f, -0.6f, 0f, 0f, 0f, -0.3f, 0, true, true, true, true, true);
  225.  
  226.                                         if (PortedAI.Debug) Game.DisplayHelp(veh.Model.Name + " CAREFUL WITH SLOW ENTITY", 3000);
  227.                                         break;
  228.                                     }
  229.                                 }
  230.                             }
  231.                         }
  232.  
  233.                         if (PortedAI.CanWeUse(Pursuitee) && Pursuitee.Handle != veh.Handle)
  234.                         {
  235.                             //// ANTI CRASH INTO SUSPECT ////
  236.                             if (!CanCopsRamSuspect && PortedAI.PreventSuspectRammings && (veh.Position - Pursuitee.Position).Length() < 20f && Pursuitee.Speed > 1f &&
  237.                                 PortedAI.IsThisEntityAheadThatEntity(Pursuitee, veh) && Pursuitee.Speed < NativeFunction.CallByName<Vector3>("GET_ENTITY_SPEED_VECTOR", veh, true).Y)
  238.                             {
  239.                                 NativeFunction.CallByName<int>("APPLY_FORCE_TO_ENTITY", veh, 3, 0f, -0.6f, 0f, 0f, 0f, -0.3f, 0, true, true, true, true, true);
  240.                                 if (PortedAI.Debug) Game.DisplayHelp(veh.Model.Name + " CAREFUL WITH " + Pursuitee.Model.Name, 3000);
  241.                             }
  242.  
  243.                             //// ALLOW PLAYER TAKE PRIMARY  ////
  244.                             if (PortedAI.AllowTakePrimary && PortedAI.CanWeUse(playerveh) && playerveh.Speed > 20f && Pursuitee.Speed > 15f &&
  245.                                 (Game.LocalPlayer.Character.Position - Pursuitee.Position).Length() < 30f && (Pursuitee.Position - veh.Position).Length() < 30f &&
  246.                                 PortedAI.IsThisEntityAheadThatEntity(playerveh, veh) && PortedAI.IsThisEntityAheadThatEntity(Pursuitee, playerveh) && playerveh.Speed < NativeFunction.CallByName<Vector3>("GET_ENTITY_SPEED_VECTOR", veh, true).Y + 2f)
  247.                             {
  248.                                 NativeFunction.CallByName<int>("APPLY_FORCE_TO_ENTITY", veh, 3, 0f, -0.6f, 0f, 0f, 0f, -0.3f, 0, true, true, true, true, true);
  249.                                 if (PortedAI.Debug) Game.DisplayHelp(veh.Model.Name + " ALLOWS PRIMARY", 3000);
  250.                             }
  251.                         }
  252.                         else if (PortedAI.Debug) Game.DisplayHelp("NO PURSUITEE VEH FOUND", 3000);
  253.  
  254.  
  255.                     } else if (PortedAI.Debug) Game.DisplayHelp("NO PLAYER VEH FOUND", 3000);
  256.  
  257.                 }
  258.             }
  259.         }
  260.  
  261.  
  262.         public void Update()
  263.         {
  264.             HandleCopCarefulBehavior();
  265.  
  266.             if(CanCopsRamSuspect && Game.IsControlJustPressed(2,GameControl.VehicleHorn) && Pursuitee.DistanceTo(Game.LocalPlayer.Character.Position) < 50f)
  267.             {
  268.                 CanCopsRamSuspect = false;
  269.                 Game.DisplayNotification("web_lossantospolicedept", "web_lossantospolicedept", "LSPD First Response", "~b~Safer Chases " + PortedAI.ScriptVer, "Other units are ~o~prohibited~w~ form PITting the fleeing vehicle.");
  270.             }
  271.  
  272.             if (Game.GameTime > _referenceTime + 2000)
  273.             {
  274.                 _referenceTime = Game.GameTime;
  275.                 if (!CanCopsRamSuspect && PortedAI.CanWeUse(PortedAI.GetLastVehicle(Game.LocalPlayer.Character)) && PortedAI.CanWeUse(Pursuitee) && Pursuitee.Speed > 10f && NativeFunction.CallByName<bool>("HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY", Pursuitee, PortedAI.GetLastVehicle(Game.LocalPlayer.Character)))
  276.                 {
  277.                     CanCopsRamSuspect = true;
  278.                     Game.DisplayNotification("web_lossantospolicedept", "web_lossantospolicedept", "LSPD First Response", "~b~Safer Chases "+PortedAI.ScriptVer, "Other units are now allowed to ~y~PIT~w~ the fleeing vehicle.");
  279.                     NativeFunction.CallByName<int>("CLEAR_ENTITY_LAST_DAMAGE_ENTITY", Pursuitee);
  280.                 }
  281.  
  282.                 if (PortedAI.AllowTakePrimary && PortedAI.CanWeUse(Pursuitee) && Pursuitee.Speed > 1f)
  283.                 {
  284.                     if (IsPlayerPrimary && (Game.LocalPlayer.Character.Position - Pursuitee.Position).Length() > 30f)
  285.                     {
  286.                         IsPlayerPrimary = false;
  287.                     }
  288.  
  289.                     if (!IsPlayerPrimary && (Game.LocalPlayer.Character.Position - Pursuitee.Position).Length() < 30f)
  290.                     {
  291.                         IsPlayerPrimary = true;
  292.                     }
  293.                 }
  294.             }
  295.         }
  296.     }
  297.  
  298.     public class IniSettings
  299.     {
  300.         public IniSettings()
  301.         {
  302.             CopMaxRelativeSpeed = 20f;
  303.             PreventSuspectRammings = true;
  304.             AllowTakePrimary = true;
  305.             Debug = false;
  306.             CopsYieldToPlayer = true;
  307.             HelpCopsManageTraffic = false;
  308.         }
  309.  
  310.         public float CopMaxRelativeSpeed { get; set; }
  311.         public bool AllowTakePrimary { get; set; }
  312.         public bool PreventSuspectRammings { get; set; }
  313.         public bool Debug { get; set; }
  314.         public bool CopsYieldToPlayer { get; set; }
  315.         public bool HelpCopsManageTraffic { get; set; }
  316.  
  317.         public static IniSettings Read(string path)
  318.         {
  319.             var output = new IniSettings();
  320.             var tmpDict = new Dictionary<string, string>();
  321.             foreach (var line in File.ReadAllLines(path))
  322.             {
  323.                 if (line.StartsWith("[") || line.StartsWith(";") || string.IsNullOrWhiteSpace(line)) continue;
  324.                 var split = line.Split('=');
  325.                 if (!tmpDict.ContainsKey(split[0]))
  326.                     tmpDict.Add(split[0], split[1]);
  327.             }
  328.  
  329.             output.DecodeValueDict(tmpDict);
  330.  
  331.             return output;
  332.         }
  333.  
  334.         public void DecodeValueDict(Dictionary<string, string> dict)
  335.         {
  336.             foreach (var pair in dict)
  337.             {
  338.                 switch (pair.Key)
  339.                 {
  340.                     case "CopMaxRelativeSpeed":
  341.                         CopMaxRelativeSpeed = float.Parse(pair.Value, CultureInfo.InvariantCulture) / 3.6f;
  342.                         break;
  343.                     case "AllowTakePrimary":
  344.                         AllowTakePrimary = bool.Parse(pair.Value);
  345.                         break;
  346.                     case "PreventSuspectRammings":
  347.                         PreventSuspectRammings = bool.Parse(pair.Value);
  348.                         break;
  349.                     case "Debug":
  350.                         Debug = bool.Parse(pair.Value);
  351.                         break;
  352.                     case "CopsYieldToPlayer":
  353.                         CopsYieldToPlayer = bool.Parse(pair.Value);
  354.                         break;
  355.                     case "HelpCopsManageTraffic":
  356.                         HelpCopsManageTraffic = bool.Parse(pair.Value);
  357.                         break;
  358.  
  359.                 }
  360.  
  361.             }
  362.         }
  363.  
  364.     }
  365.  
  366.     public class SizedQueue<T> : List<T>
  367.     {
  368.         public int Size { get; set; }
  369.  
  370.         public SizedQueue(int size)
  371.         {
  372.             Size = size;
  373.         }
  374.  
  375.         public new void Add(T item)
  376.         {
  377.             if (Count > 0 && base[base.Count - 1].Equals(item)) return;
  378.  
  379.             base.Add(item);
  380.             if (base.Count > Size)
  381.                 base.RemoveAt(0);
  382.         }
  383.     }
  384. }
Advertisement
Comments
  • JakeKindaSus
    11 days
    # text 1.03 KB | 0 0
    1. Hey Eddlm, I wanted to ask for permission regarding your original Safer Chases v1.5 mod.
    2.  
    3. I've been working on a substantially rewritten and expanded version of Safer Chases, using your publicly available source code as the starting point. The project has been reorganized into multiple classes and includes a lot of rewritten functionality and new features. AI tools assisted with the development, but my main concern is the original source code and redistribution rights.
    4.  
    5. Would you be okay with me releasing this modified version publicly on LCPDFR? I'd provide proper credit to you and clearly acknowledge the original Safer Chases project as the foundation.
    6.  
    7. I noticed that the original Pastebin source doesn't specify a license, so I wanted to ask you directly rather than assume I'm allowed to redistribute a modified version.
    8.  
    9. If you're okay with it, are there any conditions you'd want me to follow regarding attribution, source-code availability, or distribution?
    10.  
    11. Thanks for your time, and thanks for making the original source available.
Add Comment
Please, Sign In to add comment