diff --git a/Callouts/DomesticViolence.cs b/Callouts/DomesticViolence.cs
index bb22245..6457e59 100644
--- a/Callouts/DomesticViolence.cs
+++ b/Callouts/DomesticViolence.cs
@@ -3,10 +3,12 @@ using System.Linq;
using Rage;
using LSPD_First_Response.Mod.API;
using LSPD_First_Response.Mod.Callouts;
+using CalloutInterfaceAPI;
namespace Code_Blue_Calls.Callouts
{
[CalloutInfo("Domestic Violence", CalloutProbability.High)]
+ [CalloutInterface("Domestic Violence", CalloutProbability.Medium, "Code 3", "LSPD")]
public class DomesticViolence : Callout
{
private Ped victim, suspect;
@@ -14,47 +16,52 @@ namespace Code_Blue_Calls.Callouts
private Blip blip_victim;
private Vector3 location_suspect;
private Vector3 location_victim;
- private bool Victimfleeing;
- private bool SuspectKillingPlayer;
- private bool ShotAtVictim;
-
+ private bool victimFleeing;
+ private bool suspectKillingPlayer;
+ private bool shotAtVictim;
public override bool OnBeforeCalloutDisplayed()
{
+ // Set the locations for the suspect and victim
location_suspect = new Vector3(-111.19f, -8.28f, 70.52f);
location_victim = new Vector3(-111.19f, -11f, 70.52f);
+ // Show the callout area blip before accepting the callout
ShowCalloutAreaBlipBeforeAccepting(location_suspect, 30f);
+
+ // Set the callout message and position
CalloutMessage = "Domestic Violence";
CalloutPosition = location_suspect;
- Functions.PlayScannerAudioUsingPosition("WE_HAVE CRIME_RESISTING_ARREST_02 IN_OR_ON_POSITION", location_suspect);
+
+ // Play scanner audio to announce the callout
+ LSPD_First_Response.Mod.API.Functions.PlayScannerAudioUsingPosition("WE_HAVE CRIME_RESISTING_ARREST_02 IN_OR_ON_POSITION", location_suspect);
+
return base.OnBeforeCalloutDisplayed();
}
public override bool OnCalloutAccepted()
{
+ // Create relationship groups for the suspect and victim
new RelationshipGroup("Attacker");
new RelationshipGroup("Victims");
+ // Create the suspect and set properties
suspect = new Ped(location_suspect);
suspect.IsPersistent = true;
suspect.BlockPermanentEvents = true;
suspect.RelationshipGroup = "Attacker";
suspect.Inventory.GiveNewWeapon("WEAPON_NAVYREVOLVER", 1, true);
-
-
+ // Create the victim and set properties
victim = new Ped(location_victim);
victim.IsPersistent = true;
victim.BlockPermanentEvents = true;
victim.RelationshipGroup = "Victims";
- //Game.LocalPlayer.Character.RelationshipGroup = "Victims";
-
- suspect.Tasks.StandStill(-1);
-
- Game.SetRelationshipBetweenRelationshipGroups("Attacker", "Victim", Relationship.Hate);
+ // Set the relationship between the suspect and victim to hate
+ Game.SetRelationshipBetweenRelationshipGroups("Attacker", "Victims", Relationship.Hate);
+ // Attach blips to the suspect and victim
blip_suspect = suspect.AttachBlip();
blip_suspect.Color = System.Drawing.Color.Red;
blip_suspect.IsRouteEnabled = true;
@@ -70,27 +77,29 @@ namespace Code_Blue_Calls.Callouts
{
base.Process();
- if (Game.LocalPlayer.Character.DistanceTo(suspect) < 40f && !ShotAtVictim && !SuspectKillingPlayer && !victim.IsDead)
+ // If the player is near the suspect and hasn't shot at the victim yet, make the suspect fight the victim
+ if (Game.LocalPlayer.Character.DistanceTo(suspect) < 40f && !shotAtVictim && !suspectKillingPlayer && !victim.IsDead)
{
suspect.Tasks.FightAgainst(victim);
- ShotAtVictim = true;
+ shotAtVictim = true;
}
- if (Game.LocalPlayer.Character.DistanceTo(suspect) < 15f && !SuspectKillingPlayer)
+ // If the player is near the suspect and hasn't been attacked by the suspect yet, make the suspect attack the player
+ if (Game.LocalPlayer.Character.DistanceTo(suspect) < 15f && !suspectKillingPlayer)
{
- //Give the suspect a weapon and make him attack the player
suspect.Tasks.Clear();
suspect.Inventory.EquippedWeapon.Ammo = 6;
- SuspectKillingPlayer = true;
+ suspectKillingPlayer = true;
suspect.Tasks.FightAgainst(Game.LocalPlayer.Character);
-
}
+ // End the callout if the suspect is dead or cuffed
if (suspect.IsDead || suspect.IsCuffed)
{
End();
}
+ // If the suspect is still alive and the victim is null, create a new victim and make them fight the suspect
if (suspect.Exists() && victim == null)
{
victim = new Ped(location_victim);
@@ -98,17 +107,94 @@ namespace Code_Blue_Calls.Callouts
Game.DisplaySubtitle("Investigate the domestic violence report and neutralize the threat.", 5000);
}
+ // If the victim is dead, display a message to neutralize the suspect and end the callout
if (victim != null && victim.IsDead)
{
Game.DisplaySubtitle("The victim is dead. Neutralize the suspect.", 5000);
+ End();
+ }
+
+ // Randomly determine the outcome of the callout
+ Random random = new Random();
+ int outcome = random.Next(1, 101);
+
+ if (outcome <= 20)
+ {
+ // AG kills VI
+ if (!victim.IsDead)
+ {
+ suspect.Tasks.FightAgainst(victim);
+ }
+ }
+ else if (outcome <= 30)
+ {
+ // AG kills VI and PL
+ if (!victim.IsDead)
+ {
+ suspect.Tasks.FightAgainst(victim);
+ }
+ if (!Game.LocalPlayer.Character.IsDead)
+ {
+ suspect.Tasks.FightAgainst(Game.LocalPlayer.Character);
+ }
+ }
+ else if (outcome <= 35)
+ {
+ // AG kills VI and commits suicide
+ if (!victim.IsDead)
+ {
+ suspect.Tasks.FightAgainst(victim);
+ }
+ if (!suspect.IsDead)
+ {
+ suspect.Kill();
+ }
+ }
+ else if (outcome <= 50)
+ {
+ // AG kills PL
+ if (!Game.LocalPlayer.Character.IsDead)
+ {
+ suspect.Tasks.FightAgainst(Game.LocalPlayer.Character);
+ }
+ }
+ else if (outcome <= 60)
+ {
+ // AG takes VI hostage
+ if (!victim.IsDead)
+ {
+ suspect.Tasks.AimWeaponAt(victim, 999999);
+ }
+ }
+ else if (outcome <= 80)
+ {
+ // AG flees
+ if (!suspect.IsDead)
+ {
+ suspect.Tasks.ReactAndFlee(Game.LocalPlayer.Character);
+ }
+ }
+ else
+ {
+ // AG is drunk and noncompliant, eventually flees on foot
+ if (!suspect.IsDead)
+ {
+ suspect.Tasks.Wander();
+ }
}
}
public override void End()
{
base.End();
- if (blip_suspect.Exists()) blip_suspect.Delete();
- if (blip_victim.Exists()) blip_victim.Delete();
+
+ // Delete the suspect and victim blips if they exist
+ if (blip_suspect.Exists())
+ blip_suspect.Delete();
+ if (blip_victim.Exists())
+ blip_victim.Delete();
+
+ // Dismiss the suspect if they exist
if (suspect.Exists())
{
suspect.Dismiss();
diff --git a/Code Blue Calls.csproj b/Code Blue Calls.csproj
index 28087a0..aa26f25 100644
--- a/Code Blue Calls.csproj
+++ b/Code Blue Calls.csproj
@@ -9,9 +9,10 @@
Properties
Code_Blue_Calls
Code Blue Calls
- v4.7.2
+ v4.8
512
true
+
true
@@ -30,12 +31,42 @@
prompt
4
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE
+ full
+ x64
+ 7.3
+ prompt
+
+
+ bin\x64\Release\
+ TRACE
+ true
+ pdbonly
+ x64
+ 7.3
+ prompt
+
+
+ ..\..\..\Documents\References\CalloutInterface.dll
+
+
+ ..\..\..\Documents\References\CalloutInterfaceAPI.dll
+
- ..\References\LSPD First Response.dll
+ ..\..\..\Documents\References\LSPD First Response.dll
+
+
+ ..\..\..\Documents\References\RAGENativeUI.dll
- ..\References\RagePluginHookSDK.dll
+ ..\..\..\Documents\References\RagePluginHookSDK.dll
+
+
+ ..\..\..\Documents\References\StopThePed.dll
@@ -46,6 +77,9 @@
+
+ ..\..\..\Documents\References\UltimateBackup.dll
+
diff --git a/Code Blue Calls.sln b/Code Blue Calls.sln
index 32ec6a4..d37094f 100644
--- a/Code Blue Calls.sln
+++ b/Code Blue Calls.sln
@@ -8,13 +8,19 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3CD9D818-ECAE-497B-A7AD-5B64C2345A84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3CD9D818-ECAE-497B-A7AD-5B64C2345A84}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3CD9D818-ECAE-497B-A7AD-5B64C2345A84}.Debug|x64.ActiveCfg = Debug|x64
+ {3CD9D818-ECAE-497B-A7AD-5B64C2345A84}.Debug|x64.Build.0 = Debug|x64
{3CD9D818-ECAE-497B-A7AD-5B64C2345A84}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3CD9D818-ECAE-497B-A7AD-5B64C2345A84}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3CD9D818-ECAE-497B-A7AD-5B64C2345A84}.Release|x64.ActiveCfg = Release|x64
+ {3CD9D818-ECAE-497B-A7AD-5B64C2345A84}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Main.cs b/Main.cs
index a4785c9..9abd8c6 100644
--- a/Main.cs
+++ b/Main.cs
@@ -14,8 +14,13 @@ namespace Code_Blue_Calls
{
public override void Initialize()
{
+ // Subscribe to the OnOnDutyStateChanged event
Functions.OnOnDutyStateChanged += OnOnDutyStateChangedHandler;
+
+ // Log a message to indicate that the callouts have been initialized
Game.LogTrivial("Code Blue callouts initialized.");
+
+ // Register an event handler for resolving LSPDFR-related assemblies
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(LSPDFRResolveEventHandler);
}
@@ -24,46 +29,61 @@ namespace Code_Blue_Calls
throw new NotImplementedException();
}
+ // Event handler for the OnOnDutyStateChanged event
public static void OnOnDutyStateChangedHandler(bool OnDuty)
{
if (OnDuty)
{
- RegisterCallouts();
+ // If the player goes on duty, register the callouts
+ RegisterCallouts();
+
+ // Display a notification to indicate that the callouts have been loaded
Game.DisplayNotification("Code Blue Callouts loaded.");
}
}
+ // Register the callouts
private static void RegisterCallouts()
{
Functions.RegisterCallout(typeof(Callouts.DomesticViolence));
}
+ // Event handler for resolving LSPDFR-related assemblies
+ // I stole this code from a tutorial i have no idea how it works but i just know that it checks for lspdfr version. Btw comments are made by chat gpt
public static Assembly LSPDFRResolveEventHandler(object sender, ResolveEventArgs args)
{
+ // Iterate through all user plugins to find the requested assembly
foreach (Assembly assembly in Functions.GetAllUserPlugins())
{
+ // Check if the assembly name matches the requested name
if (args.Name.ToLower().Contains(assembly.GetName().Name.ToLower()))
{
- return assembly;
+ return assembly; // Return the assembly if found
}
}
- return null;
+ return null; // Return null if the assembly is not found
}
+ // Check if an LSPDFR plugin is running
+ // I stole this code from a tutorial i have no idea how it works but i just know that it checks for lspdfr version. Btw comments are made by chat gpt
public static bool IsLSPDFRPluginRunning(string Plugin, Version minversion = null)
{
+
foreach (Assembly assembly in Functions.GetAllUserPlugins())
{
AssemblyName an = assembly.GetName();
+
+ // Check if the plugin name matches the requested name
if (an.Name.ToLower() == Plugin.ToLower())
{
+ // Check the version if a minimum version is provided
if (minversion == null || an.Version.CompareTo(minversion) >= 0)
{
- return true;
+ return true; // Return true if the plugin is running and meets the minimum version requirement
}
}
}
- return false;
+ return false; // Return false if the plugin is not found or does not meet the minimum version requirement
}
}
}