├── API Examples ├── Readme.txt ├── DemoProject │ ├── Dependencies │ │ ├── RagePluginHookSDK.dll │ │ └── LSPD First Response.dll │ └── DemoProject │ │ ├── DemoProject.sln │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── Main.cs │ │ ├── DemoProject.csproj │ │ └── Callouts │ │ └── ChaseCallout.cs ├── InheritanceExample │ ├── Models │ │ ├── Peds │ │ │ ├── IPedBase.cs │ │ │ ├── Suspect.cs │ │ │ └── PedBase.cs │ │ └── Callouts │ │ │ ├── ICalloutBase.cs │ │ │ ├── Callout Types │ │ │ └── MyNewCallout.cs │ │ │ └── CalloutBase.cs │ ├── Common.cs │ ├── Main.cs │ ├── Readme.txt │ └── Extensions │ │ └── Vector3Extensions.cs ├── Albo1125-LSPDFR-API-Guide-Final-Project │ ├── Main.cs │ └── Callouts │ │ └── StolenVehicle.cs └── MuggingExample │ ├── EntryPoint.cs │ └── Callouts │ └── Mugging.cs ├── Extensions ├── Readme.txt ├── TaskInvokerExtensions.cs ├── Vector3Extensions.cs └── VehicleExtension │ ├── VehicleColor.cs │ └── VehicleExtension.cs ├── Utilities ├── Readme.txt ├── GwenForm-Example │ ├── UI │ │ ├── Form_Template.cs │ │ ├── ExemplaryForm.cs │ │ ├── Form_Template.Designer.cs │ │ └── Form_Template.resx │ ├── EntryPoint.cs │ └── GwenForm-Example.csproj ├── IniFileDemo │ ├── IniFileDemo.ini │ └── EntryPoint.cs ├── IsKeyDownWithComputerCheck │ └── IsKeyDownWithComputerCheck.cs ├── LMS.AppDomainHelper │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── LMS.AppDomainHelper.csproj │ └── AppDomainHelper.cs └── RPH-Version-Check │ └── checkForRageVersionClass ├── API Documentation ├── Readme.txt └── Guide to using the LSPDFR API and Documentation - Albo1125.pdf ├── README.md └── .gitignore /API Examples/Readme.txt: -------------------------------------------------------------------------------- 1 | This should contain examples (callouts) based on the API. Please use subfolders. -------------------------------------------------------------------------------- /Extensions/Readme.txt: -------------------------------------------------------------------------------- 1 | This should contain extensions or wrappers for (existing) classes to enhance usability. -------------------------------------------------------------------------------- /Utilities/Readme.txt: -------------------------------------------------------------------------------- 1 | This should contain all kinds of (development) helpers and utilities, such as the AppDomain helper. Please use subfolders per project. -------------------------------------------------------------------------------- /API Documentation/Readme.txt: -------------------------------------------------------------------------------- 1 | This should contain generic information about the API, like guides for setting it up or extended documentation on certain features. -------------------------------------------------------------------------------- /API Examples/DemoProject/Dependencies/RagePluginHookSDK.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LMSDev/LSPDFR-API/HEAD/API Examples/DemoProject/Dependencies/RagePluginHookSDK.dll -------------------------------------------------------------------------------- /API Examples/DemoProject/Dependencies/LSPD First Response.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LMSDev/LSPDFR-API/HEAD/API Examples/DemoProject/Dependencies/LSPD First Response.dll -------------------------------------------------------------------------------- /API Documentation/Guide to using the LSPDFR API and Documentation - Albo1125.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LMSDev/LSPDFR-API/HEAD/API Documentation/Guide to using the LSPDFR API and Documentation - Albo1125.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LSPDFR-API 2 | The official LSPDFR API repository maintained by the LSPDFR team and our awesome community. Dedicated to provide examples for API integration as well as useful helper classes for plugin development. 3 | -------------------------------------------------------------------------------- /Utilities/GwenForm-Example/UI/Form_Template.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace GwenForm_Example.UI 12 | { 13 | public partial class Form_Template : Form 14 | { 15 | public Form_Template() 16 | { 17 | InitializeComponent(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /API Examples/InheritanceExample/Models/Peds/IPedBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using RagePluginHook; 8 | using Rage; 9 | 10 | namespace Stealth.Examples.Callouts.Models.Peds 11 | { 12 | interface IPedBase 13 | { 14 | Common.PedType Type { get; set; } 15 | String Name { get; set; } 16 | String DisplayName { get; set; } 17 | Blip Blip { get; set; } 18 | Vector3 OriginalSpawnPoint { get; set; } 19 | 20 | void CreateBlip(Color? pColor = null); 21 | void DeleteBlip(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /API Examples/InheritanceExample/Models/Callouts/ICalloutBase.cs: -------------------------------------------------------------------------------- 1 | using Rage; 2 | using Stealth.Examples.Callouts.Models.Peds; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Stealth.Examples.Callouts.Models.Callouts 10 | { 11 | interface ICalloutBase 12 | { 13 | Vector3 GetRandomSpawnPoint(float pMin, float pMax); 14 | void OnArrivalAtScene(); 15 | void CreateBlip(); 16 | void DeleteBlip(); 17 | PedBase GetPed(string pName); 18 | void OfficerDown(); 19 | void DeleteEntities(); 20 | 21 | List Peds { get; set; } 22 | } 23 | } -------------------------------------------------------------------------------- /API Examples/InheritanceExample/Common.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Stealth.Examples.Callouts 8 | { 9 | public class Common 10 | { 11 | public static Random gRandom = new Random(); 12 | 13 | public enum CallResponseType 14 | { 15 | Code_2 = 2, 16 | Code_3 = 3 17 | } 18 | 19 | public enum CalloutState 20 | { 21 | Cancelled, Created, Dispatched, UnitResponding, AtScene, Completed 22 | } 23 | 24 | public enum PedType 25 | { 26 | Unknown, Witness, Victim, Suspect 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Utilities/IniFileDemo/IniFileDemo.ini: -------------------------------------------------------------------------------- 1 | //Welcome to our example .ini file! 2 | //In this file, we have various categories, which are created by using square brackets containing a name: 3 | 4 | [Keybindings] 5 | 6 | //In this category, we can have various entries. In this example (check the code out) the value is this: 7 | 8 | myKeyBinding=D0 9 | 10 | //Remember you can only use valid System.Windows.Forms keys! For a complete list, check this out: https://msdn.microsoft.com/en-us/library/system.windows.forms.keys(v=vs.110).aspx 11 | //Feel free to change the value to whatever you like, as long as it's a valid key. 12 | 13 | [Misc] 14 | //New category! 15 | 16 | //We create a value with the playername. 17 | 18 | Playername=Albo1125 19 | 20 | //Feel free to change that to your liking as well. 21 | -------------------------------------------------------------------------------- /Extensions/TaskInvokerExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | using Rage; 5 | 6 | public static class TaskInvokerExtensions 7 | { 8 | /// 9 | /// Returns the internal of the task invoker. 10 | /// 11 | /// The task invoker. 12 | /// A instance. 13 | public static Ped GetInstancePed(this TaskInvoker taskInvoker) 14 | { 15 | PropertyInfo p = taskInvoker.GetType().GetProperty("Ped", BindingFlags.NonPublic | BindingFlags.Instance); 16 | if (p != null) 17 | { 18 | Ped instancePed = (Ped)p.GetMethod.Invoke(taskInvoker, null); 19 | return instancePed; 20 | } 21 | 22 | return null; 23 | } 24 | } -------------------------------------------------------------------------------- /API Examples/InheritanceExample/Main.cs: -------------------------------------------------------------------------------- 1 | using LSPD_First_Response.Mod.API; 2 | using Rage; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Stealth.Examples.Callouts 10 | { 11 | public class Main : Plugin 12 | { 13 | public override void Initialize() 14 | { 15 | Functions.OnOnDutyStateChanged += Functions_OnOnDutyStateChanged; 16 | } 17 | 18 | private static void Functions_OnOnDutyStateChanged(bool onDuty) 19 | { 20 | if (onDuty) 21 | { 22 | //Code here 23 | } 24 | } 25 | 26 | public override void Finally() 27 | { 28 | throw new NotImplementedException(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /API Examples/InheritanceExample/Readme.txt: -------------------------------------------------------------------------------- 1 | Creating a base class for your Callouts allows you to manage common elements all in one place. Your base class stores properties and functions that are common to ALL of your callouts. 2 | 3 | In the callout example class, you'll notice that you need to retrieve the suspect from the List each time you want to use it in a function. 4 | 5 | This seems like extra legwork, but it keeps your code more organized and efficient. Plus, it becomes less work as you develop more callouts, as your CalloutBase class is disposing objects for you automatically. 6 | 7 | This code was taken from the source code of Code 3 Callouts, but was converted from VB.NET into C#. 8 | 9 | If there are any errors, please create an bug on the Issues page, and assign it to me. 10 | 11 | Luke, I borrowed some of your chase callout example code. Hope you don't mind. ;) -------------------------------------------------------------------------------- /Extensions/Vector3Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Rage; 4 | 5 | public static class Vector3Extension 6 | { 7 | public static Vector3 Around(this Vector3 start, float radius) 8 | { 9 | // Random direction. 10 | Vector3 direction = Vector3Extension.RandomXY(); 11 | Vector3 around = start + (direction * radius); 12 | return around; 13 | } 14 | 15 | public static float DistanceTo(this Vector3 start, Vector3 end) 16 | { 17 | return (end - start).Length(); 18 | } 19 | 20 | public static Vector3 RandomXY() 21 | { 22 | Random random = new Random(Environment.TickCount); 23 | 24 | Vector3 vector3 = new Vector3(); 25 | vector3.X = (float)(random.NextDouble() - 0.5); 26 | vector3.Y = (float)(random.NextDouble() - 0.5); 27 | vector3.Z = 0.0f; 28 | vector3.Normalize(); 29 | return vector3; 30 | } 31 | } -------------------------------------------------------------------------------- /Utilities/IsKeyDownWithComputerCheck/IsKeyDownWithComputerCheck.cs: -------------------------------------------------------------------------------- 1 | public static class IsKeyDownWithComputerCheck 2 | { 3 | //Call this instead of Game.IsKeyDown 4 | public static bool IsKeyDownComputerCheck(Keys KeyPressed) 5 | { 6 | 7 | 8 | if (Rage.Native.NativeFunction.CallByName("UPDATE_ONSCREEN_KEYBOARD") != 0) 9 | { 10 | 11 | return Game.IsKeyDown(KeyPressed); 12 | } 13 | else 14 | { 15 | return false; 16 | } 17 | } 18 | 19 | //Call this instead of Game.IsKeyDownRightNow 20 | public static bool IsKeyDownRightNowComputerCheck(Keys KeyPressed) 21 | { 22 | 23 | 24 | if (Rage.Native.NativeFunction.CallByName("UPDATE_ONSCREEN_KEYBOARD") != 0) 25 | { 26 | return Game.IsKeyDownRightNow(KeyPressed); 27 | } 28 | else 29 | { 30 | return false; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /API Examples/DemoProject/DemoProject/DemoProject.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoProject", "DemoProject.csproj", "{09879FDF-84DF-4035-A77A-DB698A9CC530}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {09879FDF-84DF-4035-A77A-DB698A9CC530}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {09879FDF-84DF-4035-A77A-DB698A9CC530}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {09879FDF-84DF-4035-A77A-DB698A9CC530}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {09879FDF-84DF-4035-A77A-DB698A9CC530}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /API Examples/InheritanceExample/Extensions/Vector3Extensions.cs: -------------------------------------------------------------------------------- 1 | using Rage; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Stealth.Examples.Callouts.Extensions 9 | { 10 | public static class Vector3Extensions 11 | { 12 | public static Vector3 Around(this Vector3 start, float radius) 13 | { 14 | // Random direction. 15 | Vector3 direction = Vector3Extensions.RandomXY(); 16 | Vector3 around = start + (direction * radius); 17 | return around; 18 | } 19 | 20 | public static float DistanceTo(this Vector3 start, Vector3 end) 21 | { 22 | return (end - start).Length(); 23 | } 24 | 25 | public static Vector3 RandomXY() 26 | { 27 | Random random = new Random(Environment.TickCount); 28 | 29 | Vector3 vector3 = new Vector3(); 30 | vector3.X = (float)(random.NextDouble() - 0.5); 31 | vector3.Y = (float)(random.NextDouble() - 0.5); 32 | vector3.Z = 0.0f; 33 | vector3.Normalize(); 34 | return vector3; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /API Examples/InheritanceExample/Models/Peds/Suspect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Rage; 7 | 8 | namespace Stealth.Examples.Callouts.Models.Peds 9 | { 10 | public class Suspect : PedBase 11 | { 12 | public Suspect(string pName, Rage.Vector3 position, bool confirmedSuspect = true) : base(pName, Common.PedType.Suspect, position) 13 | { 14 | if (confirmedSuspect == false) 15 | { 16 | this.Type = Common.PedType.Unknown; 17 | } 18 | } 19 | 20 | public Suspect(string pName, Rage.Model model, Rage.Vector3 position, float heading, bool confirmedSuspect = true) : base(pName, Common.PedType.Suspect, model, position, heading) 21 | { 22 | if (confirmedSuspect == false) 23 | { 24 | this.Type = Common.PedType.Unknown; 25 | } 26 | } 27 | 28 | protected internal Suspect(string pName, Rage.PoolHandle handle, bool confirmedSuspect = true) : base(pName, Common.PedType.Suspect, handle) 29 | { 30 | if (confirmedSuspect == false) 31 | { 32 | this.Type = Common.PedType.Unknown; 33 | } 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /API Examples/Albo1125-LSPDFR-API-Guide-Final-Project/Main.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LSPD_First_Response.Mod.API; 7 | using Rage; 8 | using System.Windows.Forms; 9 | 10 | namespace LSPDFR_API_Guide 11 | { 12 | public class Main : Plugin 13 | { 14 | //For further information and explanation please check the PDF file. 15 | public override void Initialize() 16 | { 17 | Functions.OnOnDutyStateChanged += OnOnDutyStateChangedHandler; 18 | Game.LogTrivial("Plugin LSPDFR_API_Guide " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + " by Albo1125 has been initialised."); 19 | Game.LogTrivial("Go on duty to fully load LSPDFR_API_Guide."); 20 | } 21 | public override void Finally() 22 | { 23 | Game.LogTrivial("LSPDFR_API_Guide has been cleaned up."); 24 | } 25 | 26 | private static void OnOnDutyStateChangedHandler(bool OnDuty) 27 | { 28 | if (OnDuty) 29 | { 30 | RegisterCallouts(); 31 | } 32 | } 33 | 34 | private static void RegisterCallouts() 35 | { 36 | Functions.RegisterCallout(typeof(Callouts.StolenVehicle)); 37 | 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Utilities/GwenForm-Example/EntryPoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Runtime.InteropServices; 7 | using Rage; 8 | using Rage.Attributes; 9 | 10 | /* GwenForm-Example by LtFlash 11 | * Changes: 12 | * 2015-08-20 - Created 13 | * / 14 | 15 | /* Suggested sequence of developing a project with GwenForm: 16 | * 1. Create an EntryPoint of your plugin. 17 | * 2. Create a Windows Form, fill it with controls. 18 | * Don't forget to change the font unit to 'Pixel'! 19 | * 3. Add a derived class from GwenForm - in this example 'ExemplaryForm'. 20 | * 5. Remember to define variables for all of your controls. 21 | */ 22 | 23 | [assembly: Plugin("GwenForm-Example", Author="LtFlash")] 24 | namespace GwenForm_Example 25 | { 26 | public static class EntryPoint 27 | { 28 | //This variable will be storing a name entered in our text box 29 | internal static string sName; 30 | 31 | public static void Main() 32 | { 33 | sName = string.Empty; 34 | 35 | while(true) 36 | { 37 | if(Game.IsKeyDown(System.Windows.Forms.Keys.F9)) 38 | { 39 | Rage.Forms.GwenForm fExample = new UI.ExemplaryForm(); 40 | fExample.Show(); 41 | } 42 | 43 | GameFiber.Yield(); 44 | } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /API Examples/DemoProject/DemoProject/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DemoProject")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DemoProject")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("def6abf8-c631-4394-a3b8-dd6a31b41972")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Extensions/VehicleExtension/VehicleColor.cs: -------------------------------------------------------------------------------- 1 | namespace alexguirre.Common.Extensions 2 | { 3 | using Rage; 4 | using Rage.Native; 5 | using System.Drawing; 6 | using System; 7 | 8 | //Credit to Stealth22 for this struct 9 | /// 10 | /// Struct for vehicles primary and secondary colors 11 | /// 12 | public struct VehicleColor 13 | { 14 | /// 15 | /// The primary color paint index 16 | /// 17 | public EPaint PrimaryColor { get; set; } 18 | 19 | /// 20 | /// The secondary color paint index 21 | /// 22 | public EPaint SecondaryColor { get; set; } 23 | 24 | 25 | 26 | /// 27 | /// Gets the primary color name 28 | /// 29 | public string PrimaryColorName 30 | { 31 | get { return GetColorName(PrimaryColor); } 32 | } 33 | /// 34 | /// Gets the secondary color name 35 | /// 36 | public string SecondaryColorName 37 | { 38 | get { return GetColorName(SecondaryColor); } 39 | } 40 | 41 | 42 | 43 | /// 44 | /// Gets the color name 45 | /// 46 | /// Color to get the name from 47 | /// 48 | public string GetColorName(EPaint paint) 49 | { 50 | String name = Enum.GetName(typeof(EPaint), paint); 51 | return name.Replace("_", " "); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /API Examples/MuggingExample/EntryPoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using LSPD_First_Response; 3 | using LSPD_First_Response.Mod.API; 4 | using LSPD_First_Response.Mod.Callouts; 5 | using Rage; 6 | using StraysCallouts.Callouts; 7 | 8 | namespace StraysCallouts 9 | { 10 | /// 11 | /// Inherit Plugin, since this is a plugin. 12 | /// 13 | public class EntryPoint : Plugin 14 | { 15 | /// 16 | /// This method is run when the plugin is first initialized. 17 | /// 18 | public override void Initialize() 19 | { 20 | //Subscribe to the OnOnDutyStateChanged event, so we don't register our callouts unless the player is on duty. 21 | Functions.OnOnDutyStateChanged += this.OnDutyStateChangedEvent; 22 | 23 | //Logging is a great tool, so we log to make sure the plugins loaded. 24 | Game.LogTrivial("StraysCallouts initialized"); 25 | } 26 | 27 | /// 28 | /// Called when the OnOnDutyStateChanged event is raised. 29 | /// 30 | /// 31 | public void OnDutyStateChangedEvent(bool onDuty) 32 | { 33 | //If the player is going on duty, register the callout. 34 | if (onDuty) 35 | { 36 | Functions.RegisterCallout(typeof(Mugging)); 37 | } 38 | } 39 | 40 | /// 41 | /// Called before the plugin is unloaded. 42 | /// 43 | public override void Finally() 44 | { 45 | 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Utilities/LMS.AppDomainHelper/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Allgemeine Informationen über eine Assembly werden über die folgenden 6 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, 7 | // die mit einer Assembly verknüpft sind. 8 | [assembly: AssemblyTitle("LMS.AppDomainHelper")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LMS.AppDomainHelper")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar 18 | // für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von 19 | // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. 20 | [assembly: ComVisible(false)] 21 | 22 | // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird 23 | [assembly: Guid("f3645d74-82df-4273-8a45-cd430e474d72")] 24 | 25 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: 26 | // 27 | // Hauptversion 28 | // Nebenversion 29 | // Buildnummer 30 | // Revision 31 | // 32 | // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern 33 | // übernehmen, indem Sie "*" eingeben: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /API Examples/DemoProject/DemoProject/Main.cs: -------------------------------------------------------------------------------- 1 | using DemoProject.Callouts; 2 | using LSPD_First_Response.Mod.API; 3 | using Rage; 4 | 5 | namespace DemoProject 6 | { 7 | /// 8 | /// Do not rename! Attributes or inheritance based plugins will follow when the API is more in depth. 9 | /// 10 | public class Main : Plugin 11 | { 12 | /// 13 | /// Constructor for the main class, same as the class, do not rename. 14 | /// 15 | public Main() 16 | { 17 | 18 | } 19 | 20 | /// 21 | /// Called when the plugin ends or is terminated to cleanup 22 | /// 23 | public override void Finally() 24 | { 25 | 26 | } 27 | 28 | /// 29 | /// Called when the plugin is first loaded by LSPDFR 30 | /// 31 | public override void Initialize() 32 | { 33 | //Event handler for detecting if the player goes on duty 34 | Functions.OnOnDutyStateChanged += Functions_OnOnDutyStateChanged; 35 | Game.LogTrivial("Callouts Plugin loaded!"); 36 | } 37 | 38 | /// 39 | /// The event handler mentioned above, 40 | /// 41 | static void Functions_OnOnDutyStateChanged(bool onDuty) 42 | { 43 | if (onDuty) 44 | { 45 | //If the player goes on duty we need to register our custom callouts 46 | //Here we register our ExampleCallout class which is inside our Callouts folder (APIExample.Callouts namespace) 47 | Functions.RegisterCallout(typeof(ChaseCallout)); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Utilities/GwenForm-Example/UI/ExemplaryForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Rage.Forms; 7 | using Rage; 8 | using RagePluginHook; 9 | 10 | namespace GwenForm_Example.UI 11 | { 12 | //This class defines the actual form which will be displayed in-game. 13 | //It uses the Windows Form you created as a template to get sizes, positions of 14 | //controls etc. so you don't need to code it manually here. 15 | 16 | public class ExemplaryForm : GwenForm 17 | { 18 | //Before you fill up this class with code you need to create a new "Windows Form...", 19 | //it is crucial to set the Font->Unit of the actual form to 'Pixel' 20 | //instead of default 'Point'. You can place controls at the form as you want, 21 | //your design will be used to display the form in-game. 22 | 23 | //All names come from the Form_Template, you got to copy them here 24 | private Gwen.Control.Label lbName; 25 | private Gwen.Control.TextBox tbName; 26 | private Gwen.Control.Button btnAccept; 27 | 28 | public ExemplaryForm() : base(typeof(Form_Template)) 29 | { 30 | } 31 | 32 | public override void InitializeLayout() 33 | { 34 | //You can customize the initial position of your window 35 | this.Position = 36 | new System.Drawing.Point(1, 37 | Game.Resolution.Height / 2 - this.Size.Height / 2); 38 | 39 | //In this loop we check if the window was closed, it let you to save 40 | //the data inside text boxes etc. to prevent it being removed when 41 | //player click at the red X. You can remove this check. 42 | GameFiber.StartNew(delegate 43 | { 44 | while (true) 45 | { 46 | if (!this.Window.IsVisible) 47 | { 48 | GwenForm_Example.EntryPoint.sName = tbName.Text; 49 | 50 | break; 51 | } 52 | GameFiber.Yield(); 53 | } 54 | }); 55 | 56 | tbName.Text = GwenForm_Example.EntryPoint.sName; 57 | 58 | btnAccept.Clicked += btnAccept_Clicked; 59 | 60 | base.InitializeLayout(); 61 | } 62 | 63 | void btnAccept_Clicked(Gwen.Control.Base sender, Gwen.Control.ClickedEventArgs arguments) 64 | { 65 | //You can easily create a message boxes known from OS 66 | Gwen.Control.MessageBox mbName = 67 | new Gwen.Control.MessageBox(this, "Your name is " + tbName.Text, "Message Box"); 68 | 69 | btnAccept.Text = "Accepted!"; 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /API Examples/DemoProject/DemoProject/DemoProject.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {09879FDF-84DF-4035-A77A-DB698A9CC530} 8 | Library 9 | Properties 10 | DemoProject 11 | DemoProject 12 | v4.5.1 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | ..\Dependencies\LSPD First Response.dll 36 | 37 | 38 | ..\Dependencies\RagePluginHookSDK.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 61 | -------------------------------------------------------------------------------- /API Examples/InheritanceExample/Models/Callouts/Callout Types/MyNewCallout.cs: -------------------------------------------------------------------------------- 1 | using LSPD_First_Response.Mod.API; 2 | using LSPD_First_Response.Mod.Callouts; 3 | using Rage; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using Stealth.Examples.Callouts.Extensions; 10 | using Stealth.Examples.Callouts.Models.Peds; 11 | 12 | namespace Stealth.Examples.Callouts.Models.Callouts.Callout_Types 13 | { 14 | [CalloutInfo("ExampleCallout", CalloutProbability.Medium)] 15 | class MyNewCallout : CalloutBase 16 | { 17 | private LHandle pursuit; 18 | private bool pursuitInitiated = false; 19 | 20 | public override bool OnBeforeCalloutDisplayed() 21 | { 22 | //Create our ped in the world 23 | Suspect myPed = new Suspect("Suspect1", "a_m_y_mexthug_01", SpawnPoint.Around(10), 0); 24 | 25 | //Create the vehicle for our ped 26 | Vehicle myVehicle = new Vehicle("DUKES2", SpawnPoint); 27 | 28 | //Now we have spawned them, check they actually exist and if not return false (preventing the callout from being accepted and aborting it) 29 | if (!myPed.Exists()) return false; 30 | if (!myVehicle.Exists()) return false; 31 | 32 | //Add the Ped to the callout's list of Peds 33 | Peds.Add(myPed); 34 | 35 | //If we made it this far both exist so let's warp the ped into the driver seat 36 | myPed.WarpIntoVehicle(myVehicle, -1); 37 | 38 | // Show the user where the pursuit is about to happen and block very close peds. 39 | this.ShowCalloutAreaBlipBeforeAccepting(SpawnPoint, 15f); 40 | this.AddMinimumDistanceCheck(5f, myPed.Position); 41 | 42 | // Set up our callout message and location 43 | this.CalloutMessage = "Example Callout Message"; 44 | this.CalloutPosition = SpawnPoint; 45 | 46 | //Play the police scanner audio for this callout (available as of the 0.2a API) 47 | Functions.PlayScannerAudioUsingPosition("CITIZENS_REPORT CRIME_RESIST_ARREST IN_OR_ON_POSITION", SpawnPoint); 48 | 49 | return base.OnBeforeCalloutDisplayed(); 50 | } 51 | 52 | public override void OnArrivalAtScene() 53 | { 54 | base.OnArrivalAtScene(); 55 | 56 | Suspect mySuspect = (Suspect)GetPed("Suspect1"); 57 | 58 | if (mySuspect != null && mySuspect.Exists()) 59 | { 60 | pursuit = Functions.CreatePursuit(); 61 | Functions.AddPedToPursuit(pursuit, mySuspect); 62 | } 63 | } 64 | 65 | public override void Process() 66 | { 67 | base.Process(); 68 | 69 | if (pursuitInitiated && !Functions.IsPursuitStillRunning(pursuit)) 70 | { 71 | End(); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /API Examples/Albo1125-LSPDFR-API-Guide-Final-Project/Callouts/StolenVehicle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Rage; 7 | using LSPD_First_Response.Mod.API; 8 | using LSPD_First_Response.Mod.Callouts; 9 | using LSPD_First_Response.Engine.Scripting.Entities; 10 | 11 | 12 | namespace LSPDFR_API_Guide.Callouts 13 | { 14 | [CalloutInfo("StolenVehicle", CalloutProbability.High)] 15 | public class StolenVehicle : Callout 16 | { 17 | private Ped Suspect; 18 | private Vehicle SuspectVehicle; 19 | private Vector3 SpawnPoint; 20 | private Blip SuspectBlip; 21 | private LHandle Pursuit; 22 | private bool PursuitCreated = false; 23 | 24 | public override bool OnBeforeCalloutDisplayed() 25 | { 26 | SpawnPoint = World.GetNextPositionOnStreet(Game.LocalPlayer.Character.Position.Around(250f)); 27 | 28 | ShowCalloutAreaBlipBeforeAccepting(SpawnPoint, 30f); 29 | AddMinimumDistanceCheck(20f, SpawnPoint); 30 | 31 | CalloutMessage = "Stolen Vehicle"; 32 | CalloutPosition = SpawnPoint; 33 | 34 | Functions.PlayScannerAudioUsingPosition("WE_HAVE CRIME_GRAND_THEFT_AUTO IN_OR_ON_POSITION", SpawnPoint); 35 | 36 | return base.OnBeforeCalloutDisplayed(); 37 | } 38 | 39 | public override bool OnCalloutAccepted() 40 | { 41 | SuspectVehicle = new Vehicle("ZENTORNO", SpawnPoint); 42 | SuspectVehicle.IsPersistent = true; 43 | 44 | Suspect = SuspectVehicle.CreateRandomDriver(); 45 | Suspect.IsPersistent = true; 46 | Suspect.BlockPermanentEvents = true; 47 | 48 | SuspectBlip = Suspect.AttachBlip(); 49 | SuspectBlip.IsFriendly = false; 50 | 51 | Suspect.Tasks.CruiseWithVehicle(20f, VehicleDrivingFlags.Emergency); 52 | return base.OnCalloutAccepted(); 53 | } 54 | 55 | public override void Process() 56 | { 57 | 58 | base.Process(); 59 | if (!PursuitCreated && Game.LocalPlayer.Character.DistanceTo(Suspect.Position) < 30f) 60 | { 61 | Pursuit = Functions.CreatePursuit(); 62 | Functions.AddPedToPursuit(Pursuit, Suspect); 63 | Functions.SetPursuitIsActiveForPlayer(Pursuit, true); 64 | PursuitCreated = true; 65 | } 66 | 67 | if (PursuitCreated && !Functions.IsPursuitStillRunning(Pursuit)) 68 | { 69 | End(); 70 | } 71 | } 72 | 73 | public override void End() 74 | { 75 | base.End(); 76 | if (Suspect.Exists()) { Suspect.Dismiss(); } 77 | if (SuspectVehicle.Exists()) { SuspectVehicle.Dismiss(); } 78 | if (SuspectBlip.Exists()) { SuspectBlip.Delete(); } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Utilities/LMS.AppDomainHelper/LMS.AppDomainHelper.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {C6A346DD-BCCC-4794-8E17-CA5596F294E7} 8 | Library 9 | Properties 10 | LMS.AppDomainHelper 11 | LMS.AppDomainHelper 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | {5477469E-83B1-11D2-8B49-00A0C9B7C9C4} 48 | 2 49 | 4 50 | 0 51 | tlbimp 52 | False 53 | True 54 | 55 | 56 | 57 | 64 | -------------------------------------------------------------------------------- /Utilities/LMS.AppDomainHelper/AppDomainHelper.cs: -------------------------------------------------------------------------------- 1 | namespace LMS.AppDomainHelper 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Runtime.InteropServices; 7 | 8 | using mscoree; 9 | 10 | public class AppDomainHelper 11 | { 12 | public delegate void CrossAppDomainCallDelegate(params object[] payload); 13 | public delegate object CrossAppDomainCallRetValueDelegate(params object[] payload); 14 | 15 | public static AppDomain GetAppDomainByName(string name) 16 | { 17 | return GetAppDomains().FirstOrDefault(appDomain => appDomain.FriendlyName == name); 18 | } 19 | 20 | public static void InvokeOnAppDomain(AppDomain appDomain, CrossAppDomainCallDelegate targetFunc, params object[] payload) 21 | { 22 | appDomain.SetData(appDomain.FriendlyName + "_payload", payload); 23 | appDomain.SetData(appDomain.FriendlyName + "_func", targetFunc); 24 | appDomain.DoCallBack(InvokedOnAppDomain); 25 | } 26 | 27 | public static T InvokeOnAppDomain(AppDomain appDomain, CrossAppDomainCallRetValueDelegate targetFunc, params object[] payload) 28 | { 29 | appDomain.SetData(appDomain.FriendlyName + "_payload", payload); 30 | appDomain.SetData(appDomain.FriendlyName + "_func", targetFunc); 31 | appDomain.DoCallBack(InvokedOnAppDomainRet); 32 | 33 | return (T)Convert.ChangeType(appDomain.GetData("result"), typeof(T)); 34 | } 35 | 36 | private static void InvokedOnAppDomain() 37 | { 38 | AppDomain currentAppDomain = AppDomain.CurrentDomain; 39 | string name = currentAppDomain.FriendlyName; 40 | 41 | // Grab payload. 42 | object[] payload = (object[])currentAppDomain.GetData(name + "_payload"); 43 | CrossAppDomainCallDelegate func = (CrossAppDomainCallDelegate)currentAppDomain.GetData(name + "_func"); 44 | 45 | func.Invoke(payload); 46 | } 47 | 48 | private static void InvokedOnAppDomainRet() 49 | { 50 | AppDomain currentAppDomain = AppDomain.CurrentDomain; 51 | string name = currentAppDomain.FriendlyName; 52 | 53 | // Grab payload. 54 | object[] payload = (object[])currentAppDomain.GetData(name + "_payload"); 55 | CrossAppDomainCallRetValueDelegate func = (CrossAppDomainCallRetValueDelegate)currentAppDomain.GetData(name + "_func"); 56 | 57 | object result = func.Invoke(payload); 58 | currentAppDomain.SetData("result", result); 59 | } 60 | 61 | public static IList GetAppDomains() 62 | { 63 | IList domains = new List(); 64 | IntPtr enumHandle = IntPtr.Zero; 65 | ICorRuntimeHost host = new CorRuntimeHost(); 66 | 67 | try 68 | { 69 | host.EnumDomains(out enumHandle); 70 | while (true) 71 | { 72 | object domain; 73 | host.NextDomain(enumHandle, out domain); 74 | if (domain == null) break; 75 | AppDomain appDomain = (AppDomain)domain; 76 | domains.Add(appDomain); 77 | } 78 | 79 | return domains; 80 | } 81 | finally 82 | { 83 | host.CloseEnum(enumHandle); 84 | Marshal.ReleaseComObject(host); 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /Utilities/GwenForm-Example/UI/Form_Template.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace GwenForm_Example.UI 2 | { 3 | partial class Form_Template 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.lbName = new System.Windows.Forms.Label(); 32 | this.tbName = new System.Windows.Forms.TextBox(); 33 | this.btnAccept = new System.Windows.Forms.Button(); 34 | this.SuspendLayout(); 35 | // 36 | // lbName 37 | // 38 | this.lbName.AutoSize = true; 39 | this.lbName.Location = new System.Drawing.Point(12, 9); 40 | this.lbName.Name = "lbName"; 41 | this.lbName.Size = new System.Drawing.Size(49, 17); 42 | this.lbName.TabIndex = 0; 43 | this.lbName.Text = "Name:"; 44 | // 45 | // tbName 46 | // 47 | this.tbName.Location = new System.Drawing.Point(12, 30); 48 | this.tbName.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 49 | this.tbName.Name = "tbName"; 50 | this.tbName.Size = new System.Drawing.Size(156, 23); 51 | this.tbName.TabIndex = 1; 52 | // 53 | // btnAccept 54 | // 55 | this.btnAccept.Location = new System.Drawing.Point(40, 78); 56 | this.btnAccept.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 57 | this.btnAccept.Name = "btnAccept"; 58 | this.btnAccept.Size = new System.Drawing.Size(99, 30); 59 | this.btnAccept.TabIndex = 2; 60 | this.btnAccept.Text = "Accept"; 61 | this.btnAccept.UseVisualStyleBackColor = true; 62 | // 63 | // Form_Template 64 | // 65 | this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 17F); 66 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 67 | this.ClientSize = new System.Drawing.Size(180, 131); 68 | this.Controls.Add(this.btnAccept); 69 | this.Controls.Add(this.tbName); 70 | this.Controls.Add(this.lbName); 71 | this.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(238))); 72 | this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 73 | this.Name = "Form_Template"; 74 | this.Text = "Form template"; 75 | this.ResumeLayout(false); 76 | this.PerformLayout(); 77 | 78 | } 79 | 80 | #endregion 81 | 82 | private System.Windows.Forms.Label lbName; 83 | private System.Windows.Forms.TextBox tbName; 84 | private System.Windows.Forms.Button btnAccept; 85 | } 86 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | *.publishproj 131 | 132 | # NuGet Packages Directory 133 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 134 | #packages/ 135 | 136 | # Windows Azure Build Output 137 | csx 138 | *.build.csdef 139 | 140 | # Windows Store app package directory 141 | AppPackages/ 142 | 143 | # Others 144 | sql/ 145 | *.Cache 146 | ClientBin/ 147 | [Ss]tyle[Cc]op.* 148 | ~$* 149 | *~ 150 | *.dbmdl 151 | *.[Pp]ublish.xml 152 | *.pfx 153 | *.publishsettings 154 | 155 | # RIA/Silverlight projects 156 | Generated_Code/ 157 | 158 | # Backup & report files from converting an old project file to a newer 159 | # Visual Studio version. Backup files are not needed, because we have git ;-) 160 | _UpgradeReport_Files/ 161 | Backup*/ 162 | UpgradeLog*.XML 163 | UpgradeLog*.htm 164 | 165 | # SQL Server files 166 | App_Data/*.mdf 167 | App_Data/*.ldf 168 | 169 | ############# 170 | ## Windows detritus 171 | ############# 172 | 173 | # Windows image file caches 174 | Thumbs.db 175 | ehthumbs.db 176 | 177 | # Folder config file 178 | Desktop.ini 179 | 180 | # Recycle Bin used on file shares 181 | $RECYCLE.BIN/ 182 | 183 | # Mac crap 184 | .DS_Store 185 | 186 | 187 | ############# 188 | ## Python 189 | ############# 190 | 191 | *.py[cod] 192 | 193 | # Packages 194 | *.egg 195 | *.egg-info 196 | dist/ 197 | build/ 198 | eggs/ 199 | parts/ 200 | var/ 201 | sdist/ 202 | develop-eggs/ 203 | .installed.cfg 204 | 205 | # Installer logs 206 | pip-log.txt 207 | 208 | # Unit test / coverage reports 209 | .coverage 210 | .tox 211 | 212 | #Translations 213 | *.mo 214 | 215 | #Mr Developer 216 | .mr.developer.cfg 217 | -------------------------------------------------------------------------------- /API Examples/InheritanceExample/Models/Peds/PedBase.cs: -------------------------------------------------------------------------------- 1 | using Rage; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Drawing; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Stealth.Examples.Callouts.Models.Peds 10 | { 11 | public class PedBase : Ped, IPedBase 12 | { 13 | public Common.PedType Type { get; set; } 14 | public string Name { get; set; } 15 | public string DisplayName { get; set; } 16 | public Blip Blip { get; set; } 17 | public Vector3 OriginalSpawnPoint { get; set; } 18 | 19 | public PedBase(string pName, Common.PedType pType, Rage.Model model, Rage.Vector3 position, float heading) : base(model, position, heading) 20 | { 21 | Name = pName; 22 | Type = pType; 23 | Init(); 24 | } 25 | 26 | protected internal PedBase(string pName, Common.PedType pType, Rage.PoolHandle handle) : base(handle) 27 | { 28 | Name = pName; 29 | Type = pType; 30 | Init(); 31 | } 32 | 33 | public PedBase(string pName, Rage.Vector3 position) : this(pName, Common.PedType.Unknown, position) 34 | { 35 | } 36 | 37 | public PedBase(string pName, Rage.Model model, Rage.Vector3 position, float heading) : this(pName, Common.PedType.Unknown, model, position, heading) 38 | { 39 | } 40 | 41 | protected internal PedBase(string pName, Rage.PoolHandle handle) : this(pName, Common.PedType.Unknown, handle) 42 | { 43 | } 44 | 45 | public PedBase(string pName, Common.PedType pType, Rage.Vector3 position) : base(position) 46 | { 47 | Name = pName; 48 | Type = pType; 49 | Init(); 50 | } 51 | 52 | protected internal void Init() 53 | { 54 | OriginalSpawnPoint = this.Position; 55 | } 56 | 57 | public override void Dismiss() 58 | { 59 | DeleteBlip(); 60 | base.Dismiss(); 61 | } 62 | 63 | public override void Delete() 64 | { 65 | DeleteBlip(); 66 | base.Delete(); 67 | } 68 | 69 | public void CreateBlip(Color? pColor = null) 70 | { 71 | if (this.Exists()) 72 | { 73 | Color color = default(Color); 74 | 75 | if (pColor == null) 76 | { 77 | switch (Type) 78 | { 79 | case Common.PedType.Suspect: 80 | color = Color.Red; 81 | break; 82 | case Common.PedType.Unknown: 83 | color = Color.Yellow; 84 | break; 85 | default: 86 | color = Color.Lime; 87 | break; 88 | } 89 | } 90 | else 91 | { 92 | color = (Color)pColor; 93 | } 94 | 95 | this.Blip = new Blip(this); 96 | this.Blip.Color = color; 97 | } 98 | } 99 | 100 | public void DeleteBlip() 101 | { 102 | try 103 | { 104 | if (this.Blip != null) 105 | { 106 | if (this.Blip.Exists()) 107 | { 108 | this.Blip.Delete(); 109 | } 110 | } 111 | else 112 | { 113 | //Game.LogVerboseDebug("Tried to delete Ped blip, but it was null"); 114 | } 115 | } 116 | catch (Exception ex) 117 | { 118 | Game.LogVerboseDebug("Error deleting Ped blip -- " + ex.Message); 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Utilities/GwenForm-Example/GwenForm-Example.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {EF9A2A3E-B438-4FBC-946E-1CA301AF7CF9} 8 | Library 9 | Properties 10 | GwenForm_Example 11 | GwenForm-Example 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | true 35 | bin\x64\Debug\ 36 | DEBUG;TRACE 37 | full 38 | x64 39 | prompt 40 | MinimumRecommendedRules.ruleset 41 | 42 | 43 | bin\x64\Release\ 44 | TRACE 45 | true 46 | pdbonly 47 | x64 48 | prompt 49 | MinimumRecommendedRules.ruleset 50 | 51 | 52 | 53 | ..\..\..\..\..\Software\Rockstar Games\Grand Theft Auto V\Gwen.dll 54 | False 55 | 56 | 57 | ..\..\..\..\..\Software\Rockstar Games\Grand Theft Auto V\SDK\RagePluginHookSDK.dll 58 | False 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Form 76 | 77 | 78 | Form_Template.cs 79 | 80 | 81 | 82 | 83 | 84 | Form_Template.cs 85 | 86 | 87 | 88 | 95 | -------------------------------------------------------------------------------- /Utilities/RPH-Version-Check/checkForRageVersionClass: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | using Rage; 8 | using System.Diagnostics; 9 | using System.Globalization; 10 | 11 | namespace Albo1125.Common 12 | { 13 | /// 14 | /// Class for checking the user's RPH version. 15 | /// 16 | class checkForRageVersionClass 17 | { 18 | private static bool correctVersion; 19 | 20 | /// 21 | /// Checks whether the person has the specified minimum version or higher. 22 | /// 23 | /// Provide in the format of a float i.e.: 0.22 24 | /// 25 | public static bool checkForRageVersion(float minimumVersion) 26 | { 27 | 28 | var versionInfo = FileVersionInfo.GetVersionInfo("RAGEPluginHook.exe"); 29 | float Rageversion; 30 | try 31 | { 32 | //If you decide to use this in your plugin, I would appreciate some credit :) 33 | Rageversion = float.Parse(versionInfo.ProductVersion.Substring(0, 4), CultureInfo.InvariantCulture); 34 | Game.LogTrivial("Albo1125.Common detected RAGEPluginHook version: " + Rageversion.ToString()); 35 | 36 | //If user's RPH version is older than the minimum 37 | if (Rageversion < minimumVersion) 38 | { 39 | correctVersion = false; 40 | GameFiber.StartNew(delegate 41 | { 42 | while (Game.IsLoading) 43 | { 44 | GameFiber.Yield(); 45 | } 46 | //If you decide to use this in your plugin, I would appreciate some credit :) 47 | Game.DisplayNotification("RPH ~r~v" + Rageversion.ToString() + " ~s~detected. ~b~Albo1125.Common ~s~requires ~b~v" + minimumVersion.ToString() + " ~s~or higher."); 48 | GameFiber.Sleep(5000); 49 | Game.LogTrivial("RAGEPluginHook version " + Rageversion.ToString() + " detected. Albo1125.Common requires v" + minimumVersion.ToString() + " or higher."); 50 | Game.LogTrivial("Preparing redirect..."); 51 | Game.DisplayNotification("You are being redirected to the RagePluginHook website so you can download the latest version."); 52 | Game.DisplayNotification("Press Backspace to cancel the redirect."); 53 | 54 | int count = 0; 55 | while (true) 56 | { 57 | GameFiber.Sleep(10); 58 | count++; 59 | if (Game.IsKeyDownRightNow(System.Windows.Forms.Keys.Back)) 60 | { 61 | break; 62 | } 63 | if (count >= 300) 64 | { 65 | //URL to the RPH download page. 66 | //I use bit.ly to track the number of times this is called: at the moment, it has been called 327 times over the past 2 days! What a timesaver for me. 67 | System.Diagnostics.Process.Start("http://bit.ly/RPHDownload"); 68 | break; 69 | } 70 | } 71 | 72 | }); 73 | } 74 | //If user's RPH version is (above) the specified minimum 75 | else 76 | { 77 | correctVersion = true; 78 | } 79 | } 80 | catch (Exception e) 81 | { 82 | //If for whatever reason the version couldn't be found. 83 | Game.LogTrivial(e.ToString()); 84 | Game.LogTrivial("Unable to detect your Rage installation."); 85 | if (File.Exists("RAGEPluginHook.exe")) 86 | { 87 | Game.LogTrivial("RAGEPluginHook.exe exists"); 88 | } 89 | else { Game.LogTrivial("RAGEPluginHook doesn't exist."); } 90 | Game.LogTrivial("Rage Version: " + versionInfo.ProductVersion.ToString()); 91 | Game.DisplayNotification("Albo1125.Common unable to detect RPH installation. Please send me your logfile."); 92 | correctVersion = false; 93 | 94 | } 95 | 96 | return correctVersion; 97 | 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /API Examples/DemoProject/DemoProject/Callouts/ChaseCallout.cs: -------------------------------------------------------------------------------- 1 | using LSPD_First_Response.Engine.Scripting.Entities; 2 | using LSPD_First_Response.Mod.API; 3 | using LSPD_First_Response.Mod.Callouts; 4 | using Rage; 5 | 6 | //Our namespace (aka folder) where we keep our callout classes. 7 | namespace DemoProject.Callouts 8 | { 9 | //Give your callout a string name and a probability of spawning. We also inherit from the Callout class, as this is a callout 10 | [CalloutInfo("ExampleCallout", CalloutProbability.Medium)] 11 | public class ChaseCallout : Callout 12 | { 13 | //Here we declare our variables, things we need or our callout 14 | private Vehicle myVehicle; // a rage vehicle 15 | private Ped myPed; // a rage ped 16 | private Vector3 SpawnPoint; // a Vector3 17 | private Blip myBlip; // a rage blip 18 | private LHandle pursuit; // an API pursuit handle 19 | 20 | /// 21 | /// OnBeforeCalloutDisplayed is where we create a blip for the user to see where the pursuit is happening, we initiliaize any variables above and set 22 | /// the callout message and position for the API to display 23 | /// 24 | /// 25 | public override bool OnBeforeCalloutDisplayed() 26 | { 27 | //Set our spawn point to be on a street around 300f (distance) away from the player. 28 | SpawnPoint = World.GetNextPositionOnStreet(Game.LocalPlayer.Character.Position.Around(300f)); 29 | 30 | //Create our ped in the world 31 | myPed = new Ped("a_m_y_mexthug_01", SpawnPoint, 0f); 32 | 33 | //Create the vehicle for our ped 34 | myVehicle = new Vehicle("DUKES2", SpawnPoint); 35 | 36 | //Now we have spawned them, check they actually exist and if not return false (preventing the callout from being accepted and aborting it) 37 | if (!myPed.Exists()) return false; 38 | if (!myVehicle.Exists()) return false; 39 | 40 | //If we made it this far both exist so let's warp the ped into the driver seat 41 | myPed.WarpIntoVehicle(myVehicle, -1); 42 | 43 | // Show the user where the pursuit is about to happen and block very close peds. 44 | this.ShowCalloutAreaBlipBeforeAccepting(SpawnPoint, 15f); 45 | this.AddMinimumDistanceCheck(5f, myPed.Position); 46 | 47 | // Set up our callout message and location 48 | this.CalloutMessage = "Example Callout Message"; 49 | this.CalloutPosition = SpawnPoint; 50 | 51 | //Play the police scanner audio for this callout (available as of the 0.2a API) 52 | Functions.PlayScannerAudioUsingPosition("CITIZENS_REPORT CRIME_RESIST_ARREST IN_OR_ON_POSITION", SpawnPoint); 53 | 54 | return base.OnBeforeCalloutDisplayed(); 55 | } 56 | 57 | 58 | /// 59 | /// OnCalloutAccepted is where we begin our callout's logic. In this instance we create our pursuit and add our ped from eariler to the pursuit as well 60 | /// 61 | /// 62 | public override bool OnCalloutAccepted() 63 | { 64 | //We accepted the callout, so lets initilize our blip from before and attach it to our ped so we know where he is. 65 | myBlip = myPed.AttachBlip(); 66 | this.pursuit = Functions.CreatePursuit(); 67 | Functions.AddPedToPursuit(this.pursuit, this.myPed); 68 | 69 | return base.OnCalloutAccepted(); 70 | } 71 | 72 | /// 73 | /// If you don't accept the callout this will be called, we clear anything we spawned here to prevent it staying in the game 74 | /// 75 | public override void OnCalloutNotAccepted() 76 | { 77 | base.OnCalloutNotAccepted(); 78 | if (myPed.Exists()) myPed.Delete(); 79 | if (myVehicle.Exists()) myVehicle.Delete(); 80 | if (myBlip.Exists()) myBlip.Delete(); 81 | } 82 | 83 | //This is where it all happens, run all of your callouts logic here 84 | public override void Process() 85 | { 86 | base.Process(); 87 | 88 | //A simple check, if our pursuit has ended we end the callout 89 | if (!Functions.IsPursuitStillRunning(pursuit)) 90 | { 91 | this.End(); 92 | } 93 | } 94 | 95 | /// 96 | /// More cleanup, when we call end you clean away anything left over 97 | /// This is also important as this will be called if a callout gets aborted (for example if you force a new callout) 98 | /// 99 | public override void End() 100 | { 101 | base.End(); 102 | if (myBlip.Exists()) myBlip.Delete(); 103 | if (myPed.Exists()) myPed.Delete(); 104 | if (myVehicle.Exists()) myVehicle.Delete(); 105 | 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /Utilities/IniFileDemo/EntryPoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Rage; 7 | using System.Windows.Forms; 8 | [assembly: Rage.Attributes.Plugin("IniFileDemo", Description = "Shows how to set up and use a .ini file.", Author = "Albo1125")] 9 | 10 | //To try this out, compile this code and place the .dll and .ini file in your /plugins folder. 11 | namespace IniFileDemo 12 | { 13 | public class EntryPoint 14 | { 15 | /// 16 | /// In this method, we load up the .ini file so other methods can use it. 17 | /// 18 | /// 19 | public static InitializationFile initialiseFile() 20 | { 21 | //InitializationFile is a Rage class. 22 | InitializationFile ini = new InitializationFile("Plugins/IniFileDemo.ini"); 23 | ini.Create(); 24 | return ini; 25 | } 26 | 27 | /// 28 | /// In this method, we load up the ini file with the method above and we read one of the values: in this case, a keybinding. 29 | /// 30 | /// 31 | public static String getMyKeyBinding() 32 | { 33 | InitializationFile ini = initialiseFile(); 34 | 35 | //ReadString takes 3 parameters: the first is the category, the second is the name of the entry and the third is the default value should the user leave the field blank. 36 | //Take a look at the example .ini file to understand this better. 37 | string keyBinding = ini.ReadString("Keybindings", "myKeyBinding", "B"); 38 | return keyBinding; 39 | } 40 | 41 | /// 42 | /// In this method, we read the player's name from the .ini file. If it is too long, we let the player know in a somewhat subtle way. 43 | /// 44 | /// 45 | public static String getPlayerName() 46 | { 47 | //We use the first method we created 48 | InitializationFile ini = initialiseFile(); 49 | 50 | //ReadString takes 3 parameters: the first is the category, the second is the name of the entry and the third is the default value should the user leave the field blank. 51 | //Take a look at the example .ini file to understand this better. 52 | string playerName = ini.ReadString("Misc", "Playername", "NoNameSet"); 53 | 54 | //If the name has more than 12 characters 55 | if (playerName.Length > 12) 56 | { 57 | playerName = "NameTooLong"; 58 | } 59 | return playerName; 60 | } 61 | 62 | /// 63 | /// In the main method, we attempt to read all the information from the .ini file. To convert a string to a System.Windows.Forms.Keys, we use a KeyConverter. 64 | /// Do not forget to add a reference to System.Windows.Forms, which can be done via project> add reference> assemblies> framework. 65 | /// I also added using System.Windows.Keys; at the beginning of the project so we don't have to type that every time we use one of its methods. 66 | /// 67 | public static void Main() 68 | { 69 | //A keysconverter is used to convert a string to a key. 70 | KeysConverter kc = new KeysConverter(); 71 | 72 | //We create two variables: one is a System.Windows.Keys, the other is a string. 73 | Keys myKeyBinding; 74 | string playerName; 75 | 76 | 77 | //Use a try/catch, because reading values from files is risky: we can never be sure what we're going to get and we don't want our plugin to crash. 78 | try 79 | { 80 | //We assign myKeyBinding the value of the string read by the method getMyKeyBinding(). We then use the kc.ConvertFromString method to convert this to a key. 81 | //If the string does not represent a valid key (see .ini file for a link) an exception is thrown. That's why we need a try/catch. 82 | myKeyBinding = (Keys)kc.ConvertFromString(getMyKeyBinding()); 83 | 84 | //For the playerName, we don't need to convert the value to a Key, so we can simply assign playerName to the return value of getPlayerName(). 85 | //Remember we've already made sure the name can't be longer than 12 characters. 86 | playerName = getPlayerName(); 87 | } 88 | //If there was an error reading the values, we set them to their defaults. We also let the user know via a notification. 89 | catch 90 | { 91 | myKeyBinding = Keys.B; 92 | playerName = "DefaultName"; 93 | Game.DisplayNotification("There was an error reading the .ini file. Setting defaults..."); 94 | } 95 | 96 | //Now you can do whatever you like with them! To finish off the example, we create a notification with our name when we press our keybinding. 97 | 98 | //We create a new GameFiber to listen for our key input. 99 | GameFiber.StartNew(delegate 100 | { 101 | //This loop runs until it's broken 102 | while (true) 103 | { 104 | //If our key has been pressed 105 | if (Game.IsKeyDown(myKeyBinding)) 106 | { 107 | //Create a notification displaying our name. 108 | Game.DisplayNotification("Your name is: " + playerName + "."); 109 | //And break out of the loop. 110 | break; 111 | } 112 | 113 | //Let other GameFibers do their job by sleeping this one for a bit. 114 | GameFiber.Yield(); 115 | } 116 | }); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Utilities/GwenForm-Example/UI/Form_Template.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /API Examples/InheritanceExample/Models/Callouts/CalloutBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Linq; 6 | using LSPD_First_Response; 7 | using LSPD_First_Response.Engine.Scripting; 8 | using Rage; 9 | using Stealth.Examples.Callouts.Extensions; 10 | using Stealth.Examples.Callouts.Models.Peds; 11 | 12 | namespace Stealth.Examples.Callouts.Models.Callouts 13 | { 14 | 15 | public abstract class CalloutBase : LSPD_First_Response.Mod.Callouts.Callout, ICalloutBase 16 | { 17 | public CalloutBase() 18 | { 19 | State = Common.CalloutState.Created; 20 | CalloutMessage = ""; 21 | ResponseType = Common.CallResponseType.Code_2; 22 | Peds = new List(); 23 | } 24 | 25 | public CalloutBase(string pCalloutMessage, Common.CallResponseType pResponseType = Common.CallResponseType.Code_2) 26 | { 27 | State = Common.CalloutState.Created; 28 | CalloutMessage = pCalloutMessage; 29 | ResponseType = pResponseType; 30 | Peds = new List(); 31 | } 32 | 33 | protected Vector3 GetRandomSpawnPoint(int pMin, int pMax) 34 | { 35 | return World.GetNextPositionOnStreet(Game.LocalPlayer.Character.Position.Around(Common.gRandom.Next(pMin, pMax))); 36 | } 37 | 38 | public override bool OnBeforeCalloutDisplayed() 39 | { 40 | //Base spawn point 41 | SpawnPoint = GetRandomSpawnPoint(150, 401); 42 | 43 | CalloutPosition = SpawnPoint; 44 | 45 | return base.OnBeforeCalloutDisplayed(); 46 | } 47 | 48 | public override void OnCalloutDisplayed() 49 | { 50 | //Radio.DispatchCallout(this.ScriptInfo.Name, SpawnPoint, CrimeEnums, ResponseType); 51 | State = Common.CalloutState.Dispatched; 52 | base.OnCalloutDisplayed(); 53 | } 54 | 55 | public override bool OnCalloutAccepted() 56 | { 57 | //Radio.AcknowledgeCallout(this.ScriptInfo.Name, ResponseType); 58 | 59 | State = Common.CalloutState.UnitResponding; 60 | CreateBlip(); 61 | 62 | return base.OnCalloutAccepted(); 63 | } 64 | 65 | public override void OnCalloutNotAccepted() 66 | { 67 | State = Common.CalloutState.Cancelled; 68 | 69 | foreach (PedBase p in Peds) 70 | { 71 | if (p != null) 72 | { 73 | if (p.Exists()) 74 | { 75 | p.Delete(); 76 | } 77 | } 78 | } 79 | 80 | base.OnCalloutNotAccepted(); 81 | } 82 | 83 | public override void Process() 84 | { 85 | base.Process(); 86 | 87 | if (Game.LocalPlayer.Character.IsDead) 88 | { 89 | OfficerDown(); 90 | End(); 91 | } 92 | 93 | if (State == Common.CalloutState.UnitResponding) 94 | { 95 | if (Game.LocalPlayer.Character.Position.DistanceTo(SpawnPoint) < 30f) 96 | { 97 | //Radio.UnitIsOnScene(); 98 | State = Common.CalloutState.AtScene; 99 | OnArrivalAtScene(); 100 | } 101 | } 102 | else if (State == Common.CalloutState.AtScene) 103 | { 104 | //If Game.LocalPlayer.Character.Position.DistanceTo(SpawnPoint) > 1000.0F Then 105 | // 'If player is more than 1 KM from the scene 106 | // 'If LSPD_First_Response.Mod.API.Functions 107 | //End If 108 | 109 | if (Game.IsKeyDown(System.Windows.Forms.Keys.T)) 110 | { 111 | if (Game.IsKeyDownRightNow(System.Windows.Forms.Keys.ControlKey)) 112 | { 113 | //AskPedToFollowOfficer(); 114 | } 115 | } 116 | } 117 | } 118 | 119 | public virtual void OfficerDown() 120 | { 121 | //code here 122 | } 123 | 124 | public virtual void OnArrivalAtScene() 125 | { 126 | DeleteBlip(); 127 | } 128 | 129 | public override void End() 130 | { 131 | base.End(); 132 | 133 | DeleteBlip(); 134 | 135 | foreach (PedBase p in Peds) 136 | { 137 | if (p != null) 138 | { 139 | if (p.Exists() == true) 140 | { 141 | p.DeleteBlip(); 142 | p.Dismiss(); 143 | } 144 | } 145 | } 146 | 147 | Peds.Clear(); 148 | 149 | State = Common.CalloutState.Completed; 150 | } 151 | 152 | public void CreateBlip() 153 | { 154 | CallBlip = new Blip(CalloutPosition); 155 | CallBlip.Color = System.Drawing.Color.LimeGreen; 156 | CallBlip.EnableRoute(System.Drawing.Color.LimeGreen); 157 | } 158 | 159 | public void DeleteBlip() 160 | { 161 | if (CallBlip != null) 162 | { 163 | if (CallBlip.Exists()) 164 | { 165 | CallBlip.DisableRoute(); 166 | CallBlip.Delete(); 167 | } 168 | } 169 | } 170 | 171 | public PedBase GetPed(string pName) 172 | { 173 | return (from x in Peds where x.Name == pName select x).FirstOrDefault(); 174 | } 175 | 176 | public Vector3 GetRandomSpawnPoint(float pMin, float pMax) 177 | { 178 | return Vector3.Zero; 179 | } 180 | 181 | public void DeleteEntities() 182 | { 183 | throw new NotImplementedException(); 184 | } 185 | 186 | public Common.CallResponseType ResponseType { get; set; } 187 | public Vector3 SpawnPoint { get; set; } 188 | public new Common.CalloutState State { get; set; } 189 | public Blip CallBlip { get; set; } 190 | public List Peds { get; set; } 191 | } 192 | 193 | } -------------------------------------------------------------------------------- /Extensions/VehicleExtension/VehicleExtension.cs: -------------------------------------------------------------------------------- 1 | namespace alexguirre.Common.Extensions 2 | { 3 | using Rage; 4 | using Rage.Native; 5 | using System.Drawing; 6 | using System; 7 | 8 | /// 9 | /// Vehicle extensions 10 | /// 11 | public static class VehicleExtension 12 | { 13 | /// 14 | /// Toggles the neon light in a vehicle 15 | /// 16 | /// 17 | /// Neon index 18 | /// Toggle the neon 19 | public static void ToggleNeonLight(this Vehicle vehicle, ENeonLights neonLight, bool toggle) 20 | { 21 | ulong SetVehicleNeonLightEnabledHash = 0x2aa720e4287bf269; 22 | 23 | NativeFunction.CallByHash(SetVehicleNeonLightEnabledHash, vehicle, (int)neonLight, toggle); 24 | } 25 | 26 | 27 | /// 28 | /// Sets the neon light color 29 | /// 30 | /// 31 | /// Color to set 32 | public static void SetNeonLightsColor(this Vehicle vehicle, Color color) 33 | { 34 | ulong SetVehicleNeonLightsColoursHash = 0x8e0a582209a62695; 35 | 36 | NativeFunction.CallByHash(SetVehicleNeonLightsColoursHash, vehicle, (int)color.R, (int)color.G, (int)color.B); 37 | } 38 | 39 | 40 | /// 41 | /// Returns true if the neon light is enabled 42 | /// 43 | /// 44 | /// Neon index 45 | /// true if the neon light is enabled 46 | public static bool IsNeonLightEnable(this Vehicle vehicle, ENeonLights neonLight) 47 | { 48 | ulong IsVehicleNeonLightEnabledHash = 0x8c4b92553e4766a5; 49 | if (NativeFunction.CallByHash(IsVehicleNeonLightEnabledHash, vehicle, (int)neonLight)) return true; 50 | else if (!NativeFunction.CallByHash(IsVehicleNeonLightEnabledHash, vehicle, (int)neonLight)) return false; 51 | else return false; 52 | } 53 | 54 | 55 | /// 56 | /// Returns the neon light color 57 | /// 58 | /// 59 | /// the neon light color 60 | public static Color GetNeonLightsColor(this Vehicle vehicle) 61 | { 62 | return UnsafeGetNeonLightsColor(vehicle); 63 | } 64 | private static unsafe Color UnsafeGetNeonLightsColor(Vehicle vehicle) 65 | { 66 | Color color; 67 | int red; 68 | int green; 69 | int blue; 70 | ulong GetVehicleNeonLightsColourHash = 0x7619eee8c886757f; 71 | NativeFunction.CallByHash(GetVehicleNeonLightsColourHash, vehicle, &red, &green, &blue); 72 | 73 | return color = Color.FromArgb(red, green, blue); 74 | } 75 | 76 | // Credit to Stealth22 for this function 77 | /// 78 | /// Gets the primary and secondary colors of this instance of Rage.Vehicle 79 | /// 80 | /// 81 | /// 82 | public static VehicleColor GetColors(this Vehicle v) 83 | { 84 | return UnsafeGetVehicleColors(v); 85 | } 86 | 87 | private static unsafe VehicleColor UnsafeGetVehicleColors(Vehicle vehicle) 88 | { 89 | int colorPrimaryInt; 90 | int colorSecondaryInt; 91 | 92 | ulong GetVehicleColorsHash = 0xa19435f193e081ac; 93 | NativeFunction.CallByHash(GetVehicleColorsHash, vehicle, &colorPrimaryInt, &colorSecondaryInt); 94 | 95 | VehicleColor colors = new VehicleColor(); 96 | 97 | colors.PrimaryColor = (EPaint)colorPrimaryInt; 98 | colors.SecondaryColor = (EPaint)colorSecondaryInt; 99 | 100 | return colors; 101 | } 102 | 103 | 104 | /// 105 | /// Sets the color to this Rage.Vehicle instance 106 | /// 107 | /// 108 | /// The primary color 109 | /// The secondary color 110 | public static void SetColors(this Vehicle v, EPaint primaryColor, EPaint secondaryColor) 111 | { 112 | NativeFunction.CallByName("SET_VEHICLE_COLOURS", v, (int)primaryColor, (int)secondaryColor); 113 | } 114 | /// 115 | /// Sets the color to this Rage.Vehicle instance 116 | /// 117 | /// 118 | /// The color 119 | public static void SetColors(this Vehicle v, VehicleColor color) 120 | { 121 | NativeFunction.CallByName("SET_VEHICLE_COLOURS", v, (int)color.PrimaryColor, (int)color.SecondaryColor); 122 | } 123 | } 124 | 125 | public enum ENeonLights 126 | { 127 | Front = 2, 128 | Back = 3, 129 | Left = 0, 130 | Right = 1, 131 | } 132 | 133 | public enum EPaint 134 | { 135 | /* CLASSIC|METALLIC */ 136 | Black = 0, 137 | Carbon_Black = 147, 138 | Graphite = 1, 139 | Anhracite_Black = 11, 140 | Black_Steel = 2, 141 | Dark_Steel = 3, 142 | Silver = 4, 143 | Bluish_Silver = 5, 144 | Rolled_Steel = 6, 145 | Shadow_Silver = 7, 146 | Stone_Silver = 8, 147 | Midnight_Silver = 9, 148 | Cast_Iron_Silver = 10, 149 | Red = 27, 150 | Torino_Red = 28, 151 | Formula_Red = 29, 152 | Lava_Red = 150, 153 | Blaze_Red = 30, 154 | Grace_Red = 31, 155 | Garnet_Red = 32, 156 | Sunset_Red = 33, 157 | Cabernet_Red = 34, 158 | Wine_Red = 143, 159 | Candy_Red = 35, 160 | Hot_Pink = 135, 161 | Pfister_Pink = 137, 162 | Salmon_Pink = 136, 163 | Sunrise_Orange = 36, 164 | Orange = 38, 165 | Bright_Orange = 138, 166 | Gold = 37, 167 | Bronze = 90, 168 | Yellow = 88, 169 | Race_Yellow = 89, 170 | Dew_Yellow = 91, 171 | Green = 139, 172 | Dark_Green = 49, 173 | Racing_Green = 50, 174 | Sea_Green = 51, 175 | Olive_Green = 52, 176 | Bright_Green = 53, 177 | Gasoline_Green = 54, 178 | Lime_Green = 92, 179 | Hunter_Green = 144, 180 | Securiror_Green = 125, 181 | Midnight_Blue = 141, 182 | Galaxy_Blue = 61, 183 | Dark_Blue = 62, 184 | Saxon_Blue = 63, 185 | Blue = 64, 186 | Bright_Blue = 140, 187 | Mariner_Blue = 65, 188 | Harbor_Blue = 66, 189 | Diamond_Blue = 67, 190 | Surf_Blue = 68, 191 | Nautical_Blue = 69, 192 | Racing_Blue = 73, 193 | Ultra_Blue = 70, 194 | Light_Blue = 74, 195 | Police_Car_Blue = 127, 196 | Epsilon_Blue = 157, 197 | Chocolate_Brown = 96, 198 | Bison_Brown = 101, 199 | Creek_Brown = 95, 200 | Feltzer_Brown = 94, 201 | Maple_Brown = 97, 202 | Beechwood_Brown = 103, 203 | Sienna_Brown = 104, 204 | Saddle_Brown = 98, 205 | Moss_Brown = 100, 206 | Woodbeech_Brown = 102, 207 | Straw_Brown = 99, 208 | Sandy_Brown = 105, 209 | Bleached_Brown = 106, 210 | Schafter_Purple = 71, 211 | Spinnaker_Purple = 72, 212 | Midnight_Purple = 142, 213 | Metallic_Midnight_Purple = 146, 214 | Bright_Purple = 145, 215 | Cream = 107, 216 | Ice_White = 111, 217 | Frost_White = 112, 218 | Pure_White = 134, 219 | Default_Alloy = 156, 220 | Champagne = 93, 221 | 222 | 223 | /* MATTE */ 224 | Matte_Black = 12, 225 | Matte_Gray = 13, 226 | Matte_Light_Gray = 14, 227 | Matte_Ice_White = 131, 228 | Matte_Blue = 83, 229 | Matte_Dark_Blue = 82, 230 | Matte_Midnight_Blue = 84, 231 | Matte_Midnight_Purple = 149, 232 | Matte_Schafter_Purple = 148, 233 | Matte_Red = 39, 234 | Matte_Dark_Red = 40, 235 | Matte_Orange = 41, 236 | Matte_Yellow = 42, 237 | Matte_Lime_Green = 55, 238 | Matte_Green = 128, 239 | Matte_Forest_Green = 151, 240 | Matte_Foliage_Green = 155, 241 | Matte_Brown = 129, 242 | Matte_Olive_Darb = 152, 243 | Matte_Dark_Earth = 153, 244 | Matte_Desert_Tan = 154, 245 | 246 | 247 | /* METALS */ 248 | Brushed_Steel = 117, 249 | Brushed_Black_Steel = 118, 250 | Brushed_Aluminum = 119, 251 | Pure_Gold = 158, 252 | Brushed_Gold = 159, 253 | 254 | 255 | /* CHROME */ 256 | Chrome = 120, 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /API Examples/MuggingExample/Callouts/Mugging.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Rage; 3 | using Rage.Native; 4 | using LSPD_First_Response.Mod.Callouts; 5 | using LSPD_First_Response.Mod.API; 6 | using LSPD_First_Response.Engine.Scripting.Entities; 7 | 8 | namespace StraysCallouts.Callouts 9 | { 10 | //Name the callout, and set the probability. 11 | [CalloutInfo("Mugging", CalloutProbability.Medium)] 12 | //Inherit the Callout class, since we're making a callout. 13 | public class Mugging : LSPD_First_Response.Mod.Callouts.Callout 14 | { 15 | /// 16 | /// This callout waits until the player is on scene to start, which is the purpose of EMuggingState, so we know when to start running the callout's logic. 17 | /// 18 | public EMuggingState state; 19 | public LHandle pursuit; 20 | public Vector3 spawnPoint; 21 | public Blip ABlip; 22 | public Ped Aggressor; 23 | public Ped Victim; 24 | 25 | /// 26 | /// Called before the callout is displayed. Do all spawning here, so that if spawning isn't successful, the player won't notice, as the callout won't be shown. 27 | /// 28 | /// 29 | public override bool OnBeforeCalloutDisplayed() 30 | { 31 | //Get a valid spawnpoint for the callout, and spawn the Aggressor there 32 | spawnPoint = World.GetNextPositionOnStreet(Game.LocalPlayer.Character.Position.Around(300f)); 33 | Aggressor = new Ped(spawnPoint); 34 | 35 | //Spawn the victim in front of the aggressor 36 | Victim = new Ped(Aggressor.GetOffsetPosition(new Vector3(0, 1.8f, 0))); 37 | 38 | //If for some reason, the spawning of either two peds failed, don't display the callout 39 | if(!Aggressor.Exists()) return false; 40 | if(!Victim.Exists()) return false; 41 | 42 | //If the peds are valid, display the area that the callout is in. 43 | this.ShowCalloutAreaBlipBeforeAccepting(spawnPoint, 15f); 44 | this.AddMinimumDistanceCheck(5f, spawnPoint); 45 | 46 | //Give the aggressor his weapon 47 | Aggressor.GiveNewWeapon("WEAPON_PISTOL", 500, true); 48 | 49 | //Set the callout message(displayed in the notification), and the position(also shown in the notification) 50 | this.CalloutMessage = "Mugging"; 51 | this.CalloutPosition = spawnPoint; 52 | 53 | //Play the scanner audio. 54 | Functions.PlayScannerAudioUsingPosition("CITIZENS_REPORT_03 CRIME_POSSIBLE_MUGGING IN_OR_ON_POSITION", this.spawnPoint); 55 | 56 | return base.OnBeforeCalloutDisplayed(); 57 | } 58 | 59 | /// 60 | /// Called when the player accepts the callout 61 | /// 62 | /// 63 | public override bool OnCalloutAccepted() 64 | { 65 | //Set the player as en route to the scene 66 | state = EMuggingState.EnRoute; 67 | 68 | //Attach a blip to the Aggressor, so the player knows where to go, and can find the aggressor if he flees 69 | ABlip = Aggressor.AttachBlip(); 70 | 71 | //Have the aggressor aim at the victim, and have the victim put their hands up. -1 makes the task permanent, or until we clear the task, which we do later. 72 | NativeFunction.CallByName("TASK_AIM_GUN_AT_ENTITY", Aggressor, Victim, -1, true); 73 | Victim.Tasks.PutHandsUp(-1, Aggressor); 74 | 75 | //Block permanent events, so the victim doesn't flee if something disturbs them(A vehicle tapping them, etc..), as this would completely disrupt the callout's logic. 76 | Victim.BlockPermanentEvents = true; 77 | 78 | //Display a message to let the user know that the callout was accepted. 79 | Game.DisplaySubtitle("Get to the ~r~scene~w~.", 6500); 80 | return base.OnCalloutAccepted(); 81 | } 82 | 83 | /// 84 | /// Called if the player ignores the callout 85 | /// 86 | public override void OnCalloutNotAccepted() 87 | { 88 | base.OnCalloutNotAccepted(); 89 | //Clean up what we spawned earlier, since the player didn't accept the callout. 90 | if (Aggressor.Exists()) Aggressor.Delete(); 91 | if (Victim.Exists()) Victim.Delete(); 92 | if (ABlip.Exists()) ABlip.Delete(); 93 | } 94 | 95 | /// 96 | /// All callout logic should be done here. 97 | /// 98 | public override void Process() 99 | { 100 | base.Process(); 101 | 102 | //If the player is driving to the scene, and their distance to the scene is less than 15, start the callout's logic. 103 | if (state == EMuggingState.EnRoute && Game.LocalPlayer.Character.Position.DistanceTo(spawnPoint) <= 15) 104 | { 105 | //Set the player as on scene 106 | state = EMuggingState.OnScene; 107 | 108 | //Start the callout's logic. You can paste the logic from StartMuggingScenario straight into here, but I don't, since I like it to look clean, and place any long methods towards the bottom of the class. 109 | StartMuggingScenario(); 110 | } 111 | 112 | //If the state is DecisionMade(The aggressor already decided what random outcome to execute), and the pursuit isn't running anymore, end the callout. 113 | if (state == EMuggingState.DecisionMade && !Functions.IsPursuitStillRunning(pursuit)) 114 | { 115 | this.End(); 116 | } 117 | } 118 | 119 | /// 120 | /// Called when the callout ends 121 | /// 122 | public override void End() 123 | { 124 | //Dismiss the aggressor and victim, so they can be deleted by the game once the player leaves the scene. 125 | if (Aggressor.Exists()) Aggressor.Dismiss(); 126 | if (Victim.Exists()) Victim.Dismiss(); 127 | 128 | //Delete the blip attached to the aggressor 129 | if (ABlip.Exists()) ABlip.Delete(); 130 | base.End(); 131 | } 132 | 133 | /// 134 | /// The method that contains the callout's logic 135 | /// 136 | public void StartMuggingScenario() 137 | { 138 | //ALWAYS START A NEW GAME FIBER IF YOU'RE GOING TO USE GameFiber.Sleep, DON'T SLEEP THE MAIN FIBER. 139 | GameFiber.StartNew(delegate 140 | { 141 | //Create the pursuit 142 | this.pursuit = Functions.CreatePursuit(); 143 | 144 | //Pick a random number, to choose a random outcome 145 | int r = new Random().Next(1, 4); 146 | 147 | //Set the state to decision made, since the outcome is chosen. 148 | state = EMuggingState.DecisionMade; 149 | 150 | //Execute one of the random outcomes 151 | if (r == 1) 152 | { 153 | //The aggressor kills the victim before fleeing from the scene, and the victim flees the scene, trying to escape the aggressor. 154 | NativeFunction.CallByName("TASK_COMBAT_PED", Aggressor, Victim, 0, 1); 155 | NativeFunction.CallByName("TASK_REACT_AND_FLEE_PED", Victim, Aggressor); 156 | 157 | //The aggressor shoots at the victim for 5 seconds, which either kills them, or severely injures them. 158 | GameFiber.Sleep(5000); 159 | 160 | NativeFunction.CallByName("TASK_REACT_AND_FLEE_PED", Victim, Aggressor); 161 | //Now for another random outcome 162 | if (new Random().Next(1, 3) == 2) 163 | { 164 | //The aggressor attacks the player. 165 | NativeFunction.CallByName("TASK_COMBAT_PED", Aggressor, Game.LocalPlayer.Character, 0, 1); 166 | 167 | //We wait 4.5 seconds before adding the ped to a pursuit, since as soon as we add the aggressor to a pursuit, LSPDFR takes over the AI, and they won't attack the player anymore. They'll flee instead. 168 | GameFiber.Sleep(4500); 169 | } 170 | } 171 | else 172 | { 173 | //The aggressor doesn't attack the victim, instead, both peds flee. We don't need to tell the aggressor to flee, as LSPDFR's pursuit system does that for us. 174 | NativeFunction.CallByName("TASK_REACT_AND_FLEE_PED", Victim, Aggressor); 175 | } 176 | //Dismiss the aggressor from our plugin 177 | Aggressor.Dismiss(); 178 | 179 | //Add the aggressor to a pursuit 180 | Functions.AddPedToPursuit(this.pursuit, Aggressor); 181 | 182 | //Dispatch a backup unit. 183 | Functions.RequestBackup(Game.LocalPlayer.Character.Position, LSPD_First_Response.EBackupResponseType.Pursuit, LSPD_First_Response.EBackupUnitType.LocalUnit); 184 | }); 185 | } 186 | } 187 | 188 | /// 189 | /// Mugging states 190 | /// 191 | public enum EMuggingState 192 | { 193 | EnRoute, 194 | OnScene, 195 | DecisionMade 196 | } 197 | } 198 | --------------------------------------------------------------------------------