Advertisement
Eddlm

Safer Chases v1.5

Jan 26th, 2016
1,694
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 18.03 KB | None | 0 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
Add Comment
Please, Sign In to add comment
Advertisement