diff --git a/README.md b/README.md index 2f64c99..120fbfb 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ Drag and drop the contents from within the downloaded GTA V folder into where yo ## GET SUPPORT AND REPORT PROBLEMS For the fastest support, [join my Discord](https://discord.gg/cUQaTNQ) and ask your question in the **correct category/channel**. For slower support, [use this thread on the LSPDFR forums](https://www.lcpdfr.com/forums/topic/107730-richs-plugin-support-thread/). +## GET SUPPORT AND REPORT PROBLEMS +For the fastest support, [join my Discord](https://discord.gg/cUQaTNQ) and ask your question in the **correct category/channel**. For slower support, [use this thread on the LSPDFR forums](https://www.lcpdfr.com/forums/topic/107730-richs-plugin-support-thread/). + ## HOW TO USE SCENE MANAGER ### Using the Menus: Menu options with gold colored text are selectable, which means when you select these menu items, something will happen (opening a new menu, adding a waypoint, placing a barrier, etc). Menu options with white colored text are interactable (can be scrolled through, for example), but nothing will happen if you try to select them. diff --git a/SceneManager/EntryPoint.cs b/SceneManager/EntryPoint.cs index a0d4d86..51c88d8 100644 --- a/SceneManager/EntryPoint.cs +++ b/SceneManager/EntryPoint.cs @@ -4,39 +4,47 @@ using System.Linq; using System.Reflection; using System.Windows.Forms; using Rage; +using SceneManager.Objects; +using SceneManager.Utils; [assembly: Rage.Attributes.Plugin("Scene Manager", Author = "Rich", Description = "Control your scenes with custom AI pathing and traffic barrier management.", PrefersSingleInstance = true)] namespace SceneManager { + [Obfuscation(Exclude = false, Feature = "-rename", ApplyToMembers = false)] public class EntryPoint { + [Obfuscation(Exclude = false, Feature = "-rename")] internal static void Main() { - if (CheckRNUIVersion()) - { - AppDomain.CurrentDomain.DomainUnload += MyTerminationHandler; - Settings.LoadSettings(); - GetAssemblyVersion(); - MenuManager.InstantiateMenus(); - - DisplayHintsToOpenMenu(); - - GameFiber UserInputFiber = new GameFiber(() => GetUserInput.LoopForUserInput()); - UserInputFiber.Start(); - } - else + if(!InputManagerChecker() || !CheckRNUIVersion()) { Game.UnloadActivePlugin(); return; } + while (Game.IsLoading) + { + GameFiber.Yield(); + } + + AppDomain.CurrentDomain.DomainUnload += MyTerminationHandler; + Settings.LoadSettings(); + GetAssemblyVersion(); + MenuManager.InstantiateMenus(); + + DisplayHintsToOpenMenu(); + + GameFiber UserInputFiber = new GameFiber(() => GetUserInput.LoopForUserInput()); + UserInputFiber.Start(); + void GetAssemblyVersion() { string version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); Game.LogTrivial($"Scene Manager V{version} is ready."); } } + private static bool CheckRNUIVersion() { var directory = Directory.GetCurrentDirectory(); @@ -57,11 +65,25 @@ namespace SceneManager } else { - Game.DisplayNotification($"~o~Scene Manager~r~[Error]\n~w~ Your RAGENativeUI.dll version is below 1.7, please update RAGENativeUI and try again."); + Game.DisplayNotification($"~o~Scene Manager~r~[Error]\n~w~Your RAGENativeUI.dll version is below 1.7. Please update RAGENativeUI and try again."); return false; } } + + private static bool InputManagerChecker() + { + var directory = Directory.GetCurrentDirectory(); + var exists = File.Exists(directory + @"\InputManager.dll"); + if (!exists) + { + Game.LogTrivial($"InputManager was not found in the user's GTA V directory."); + Game.DisplayNotification($"~o~Scene Manager ~r~[Error]\n~w~InputManager.dll was not found in your GTA V directory. Please install InputManager.dll and try again."); + return false; + } + return true; + } + private static void DisplayHintsToOpenMenu() { if (Settings.ModifierKey == Keys.None && Settings.ModifierButton == ControllerButtons.None) @@ -96,7 +118,7 @@ namespace SceneManager // Clean up paths for (int i = 0; i < PathMainMenu.paths.Count; i++) { - PathMainMenu.DeletePath(PathMainMenu.paths[i], PathMainMenu.Delete.All); + PathMainMenu.DeletePath(PathMainMenu.paths[i], Delete.All); } Game.LogTrivial($"Plugin has shut down."); diff --git a/SceneManager/Menus/BarrierMenu.cs b/SceneManager/Menus/BarrierMenu.cs index 9cc4e58..1cc1539 100644 --- a/SceneManager/Menus/BarrierMenu.cs +++ b/SceneManager/Menus/BarrierMenu.cs @@ -4,6 +4,8 @@ using System.Linq; using Rage; using RAGENativeUI; using RAGENativeUI.Elements; +using SceneManager.Objects; +using SceneManager.Utils; namespace SceneManager { @@ -12,11 +14,13 @@ namespace SceneManager private static List trafficLightList = new List() { TrafficLight.Green, TrafficLight.Red, TrafficLight.Yellow, TrafficLight.None }; internal static UIMenu barrierMenu = new UIMenu("Scene Manager", "~o~Barrier Management"); internal static List barriers = new List(); - private static UIMenuListScrollerItem barrierList = new UIMenuListScrollerItem("Spawn Barrier", "", Settings.barrierKeys); + private static UIMenuListScrollerItem barrierList = new UIMenuListScrollerItem("Spawn Barrier", "", Settings.barriers.Keys); // Settings.barrierKeys private static UIMenuNumericScrollerItem rotateBarrier = new UIMenuNumericScrollerItem("Rotate Barrier", "", 0, 350, 10); + // ADD CHECKBOX FOR BARRIER TO STOP TRAFFIC? ADD 3D MARKER TO SHOW WHERE TRAFFIC WILL STOP. ONLY NEED ONE CONE TO DO IT PER LANE private static UIMenuCheckboxItem invincible = new UIMenuCheckboxItem("Indestructible", false); + private static UIMenuCheckboxItem immobile = new UIMenuCheckboxItem("Immobile", false); private static UIMenuNumericScrollerItem barrierTexture = new UIMenuNumericScrollerItem("Change Texture", "", 0, 15, 1); - private static UIMenuCheckboxItem setBarrierLights = new UIMenuCheckboxItem("Enable Barrier Lights", false); + private static UIMenuCheckboxItem setBarrierLights = new UIMenuCheckboxItem("Enable Barrier Lights", Settings.EnableBarrierLightsDefaultOn); private static UIMenuListScrollerItem setBarrierTrafficLight = new UIMenuListScrollerItem("Set Barrier Traffic Light", "", trafficLightList); private static UIMenuListScrollerItem removeBarrierOptions = new UIMenuListScrollerItem("Remove Barrier", "", new[] { "Last Barrier", "Nearest Barrier", "All Barriers" }); private static UIMenuItem resetBarriers = new UIMenuItem("Reset Barriers", "Reset all spawned barriers to their original position and rotation"); @@ -42,6 +46,8 @@ namespace SceneManager barrierMenu.AddItem(invincible); + barrierMenu.AddItem(immobile); + if (Settings.EnableAdvancedBarricadeOptions) { barrierMenu.AddItem(barrierTexture); @@ -49,8 +55,8 @@ namespace SceneManager barrierMenu.AddItem(setBarrierLights); - barrierMenu.AddItem(setBarrierTrafficLight); - setBarrierTrafficLight.Index = 3; + //barrierMenu.AddItem(setBarrierTrafficLight); + //setBarrierTrafficLight.Index = 3; } barrierMenu.AddItem(removeBarrierOptions); @@ -69,14 +75,16 @@ namespace SceneManager shadowBarrier.Delete(); } - shadowBarrier = new Object(Settings.barrierValues[barrierList.Index], MousePositionInWorld.GetPosition, rotateBarrier.Value); + var barrierKey = Settings.barriers.Where(x => x.Key == barrierList.SelectedItem).FirstOrDefault().Key; + var barrierValue = Settings.barriers[barrierKey].Name; + shadowBarrier = new Object(barrierValue, MousePositionInWorld.GetPosition, rotateBarrier.Value); // Settings.barrierValues[barrierList.Index] if (!shadowBarrier) { barrierMenu.Close(); Game.DisplayNotification($"~o~Scene Manager ~r~[Error]\n~w~Something went wrong creating the shadow barrier. Please try again."); return; } - Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index); + //Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index); Rage.Native.NativeFunction.Natives.PLACE_OBJECT_ON_GROUND_PROPERLY(shadowBarrier); shadowBarrier.IsGravityDisabled = true; shadowBarrier.IsCollisionEnabled = false; @@ -94,7 +102,7 @@ namespace SceneManager { while (barrierMenu.Visible) { - if (barrierList.Selected || rotateBarrier.Selected || invincible.Selected || barrierTexture.Selected || setBarrierLights.Selected || setBarrierTrafficLight.Selected) + if (barrierList.Selected || rotateBarrier.Selected || invincible.Selected || immobile.Selected || barrierTexture.Selected || setBarrierLights.Selected || setBarrierTrafficLight.Selected) { if (shadowBarrier) { @@ -131,7 +139,7 @@ namespace SceneManager shadowBarrier.Heading = rotateBarrier.Value; shadowBarrier.Position = MousePositionInWorld.GetPositionForBarrier; Rage.Native.NativeFunction.Natives.PLACE_OBJECT_ON_GROUND_PROPERLY(shadowBarrier); - Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index); + //Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index); } void DisableBarrierMenuOptionsIfShadowConeTooFar() @@ -163,48 +171,64 @@ namespace SceneManager private static void SpawnBarrier() { - if(barrierList.SelectedItem == "Flare") + GameFiber.StartNew(() => { - SpawnFlare(); - } - else - { - var barrier = new Object(shadowBarrier.Model, shadowBarrier.Position, rotateBarrier.Value); - barrier.SetPositionWithSnap(shadowBarrier.Position); - Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(barrier, true); - barrier.IsPositionFrozen = false; - if (invincible.Checked) + if (barrierList.SelectedItem == "Flare") { - Rage.Native.NativeFunction.Natives.SET_DISABLE_FRAG_DAMAGE(barrier, true); - if(barrier.Model.Name != "prop_barrier_wat_03a") - { - Rage.Native.NativeFunction.Natives.SET_DISABLE_BREAKING(barrier, true); - } + SpawnFlare(); } - if (Settings.EnableAdvancedBarricadeOptions) + else { - Rage.Native.NativeFunction.Natives.x971DA0055324D033(barrier, barrierTexture.Value); - if (setBarrierLights.Checked) + var barrier = new Object(shadowBarrier.Model, shadowBarrier.Position, rotateBarrier.Value); + barrier.SetPositionWithSnap(shadowBarrier.Position); + Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(barrier, true); + if (invincible.Checked) { - Rage.Native.NativeFunction.Natives.SET_ENTITY_LIGHTS(barrier, false); + Rage.Native.NativeFunction.Natives.SET_DISABLE_FRAG_DAMAGE(barrier, true); + if (barrier.Model.Name != "prop_barrier_wat_03a") + { + Rage.Native.NativeFunction.Natives.SET_DISABLE_BREAKING(barrier, true); + } + } + if (immobile.Checked) + { + barrier.IsPositionFrozen = true; } else { - Rage.Native.NativeFunction.Natives.SET_ENTITY_LIGHTS(barrier, true); - } - Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(barrier, setBarrierTrafficLight.Index); - barrier.IsPositionFrozen = true; - GameFiber.Sleep(50); - if (barrier) - { barrier.IsPositionFrozen = false; } + if (Settings.EnableAdvancedBarricadeOptions) + { + Rage.Native.NativeFunction.Natives.x971DA0055324D033(barrier, barrierTexture.Value); + if (setBarrierLights.Checked) + { + Rage.Native.NativeFunction.Natives.SET_ENTITY_LIGHTS(barrier, false); + } + else + { + Rage.Native.NativeFunction.Natives.SET_ENTITY_LIGHTS(barrier, true); + } + + //Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(barrier, setBarrierTrafficLight.Index); + barrier.IsPositionFrozen = true; + GameFiber.Sleep(50); + if (barrier && !immobile.Checked) + { + barrier.IsPositionFrozen = false; + } + } + barriers.Add(new Barrier(barrier, barrier.Position, barrier.Heading, invincible.Checked, immobile.Checked)); + //if (barriers.First().Object == barrier) + //{ + // barriers.First().GoAround(); + //} + removeBarrierOptions.Enabled = true; + resetBarriers.Enabled = true; } - barriers.Add(new Barrier(barrier, barrier.Position, barrier.Heading)); - removeBarrierOptions.Enabled = true; - resetBarriers.Enabled = true; - } + }, "Scene Manager Spawn Barrier Fiber"); + void SpawnFlare() { @@ -224,7 +248,7 @@ namespace SceneManager } }); - barriers.Add(new Barrier(flare, flare.Position, flare.Heading)); + barriers.Add(new Barrier(flare, flare.Position, flare.Heading, invincible.Checked, immobile.Checked)); removeBarrierOptions.Enabled = true; } } @@ -270,31 +294,41 @@ namespace SceneManager private static void ResetBarriers() { - var currentBarriers = barriers.Where(b => b.Model.Name != "0xa2c44e80").ToList(); // 0xa2c44e80 is the flare weapon hash - foreach (Barrier barrier in currentBarriers) + GameFiber.StartNew(() => { - var newBarrier = new Rage.Object(barrier.Model, barrier.Position, barrier.Rotation); - newBarrier.SetPositionWithSnap(barrier.Position); - Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(newBarrier, true); - newBarrier.IsPositionFrozen = false; - Rage.Native.NativeFunction.Natives.SET_DISABLE_FRAG_DAMAGE(newBarrier, true); - Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(newBarrier, setBarrierTrafficLight.Index); - newBarrier.IsPositionFrozen = true; - GameFiber.Sleep(50); - if (newBarrier) + var currentBarriers = barriers.Where(b => b.Model.Name != "0xa2c44e80").ToList(); // 0xa2c44e80 is the flare weapon hash + foreach (Barrier barrier in currentBarriers) { - newBarrier.IsPositionFrozen = false; - } - barriers.Add(new Barrier(newBarrier, newBarrier.Position, newBarrier.Heading)); + var newBarrier = new Object(barrier.Model, barrier.Position, barrier.Rotation); + newBarrier.SetPositionWithSnap(barrier.Position); + Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(newBarrier, true); + newBarrier.IsPositionFrozen = barrier.Immobile; + if (barrier.Invincible) + { + Rage.Native.NativeFunction.Natives.SET_DISABLE_FRAG_DAMAGE(newBarrier, true); + if (newBarrier.Model.Name != "prop_barrier_wat_03a") + { + Rage.Native.NativeFunction.Natives.SET_DISABLE_BREAKING(newBarrier, true); + } + } + //Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(newBarrier, setBarrierTrafficLight.Index); + newBarrier.IsPositionFrozen = true; + GameFiber.Sleep(50); + if (newBarrier && !barrier.Immobile) + { + newBarrier.IsPositionFrozen = false; + } + barriers.Add(new Barrier(newBarrier, newBarrier.Position, newBarrier.Heading, barrier.Invincible, barrier.Immobile)); - - if (barrier.Object) - { - barrier.Object.Delete(); + if (barrier.Object) + { + barrier.Object.Delete(); + } + barriers.Remove(barrier); } - barriers.Remove(barrier); - } - currentBarriers.Clear(); + currentBarriers.Clear(); + }); + } private static void SetBarrierLights() @@ -308,7 +342,7 @@ namespace SceneManager Rage.Native.NativeFunction.Natives.SET_ENTITY_LIGHTS(shadowBarrier, true); } - Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index); + //Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index); } private static void BarrierMenu_OnCheckboxChanged(UIMenu sender, UIMenuCheckboxItem checkbox, bool @checked) @@ -378,13 +412,6 @@ namespace SceneManager private static void BarrierMenu_OnMenuOpen(UIMenu menu) { var scrollerItems = new List { barrierList, barrierTexture, setBarrierTrafficLight, rotateBarrier, removeBarrierOptions }; - var checkboxItems = new Dictionary() { { invincible, null }, {setBarrierLights, SetBarrierLights} }; - var selectItems = new Dictionary() - { - { barrierList, SpawnBarrier }, - { removeBarrierOptions, RemoveBarrier }, - { resetBarriers, ResetBarriers }, - }; Hints.Display($"~o~Scene Manager ~y~[Hint]\n~w~The shadow barrier will disappear if you aim too far away."); CreateShadowBarrier(); @@ -392,7 +419,7 @@ namespace SceneManager GameFiber ShadowConeLoopFiber = new GameFiber(() => LoopToDisplayShadowBarrier()); ShadowConeLoopFiber.Start(); - RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems); + RNUIMouseInputHandler.Initialize(menu, scrollerItems); } internal static float SetMenuWidth() diff --git a/SceneManager/Menus/EditPathMenu.cs b/SceneManager/Menus/EditPathMenu.cs index 52fb1e2..01a672f 100644 --- a/SceneManager/Menus/EditPathMenu.cs +++ b/SceneManager/Menus/EditPathMenu.cs @@ -1,17 +1,16 @@ using System.Collections.Generic; using System.Drawing; -using System.Linq; -using System.Windows.Forms; using Rage; using RAGENativeUI; using RAGENativeUI.Elements; +using SceneManager.Utils; namespace SceneManager { class EditPathMenu { internal static UIMenu editPathMenu = new UIMenu("Scene Manager", "~o~Edit Path"); - private static UIMenuItem editPathWaypoints, deletePath; + private static UIMenuItem editPathWaypoints, deletePath, exportPath; internal static UIMenuCheckboxItem disablePath; internal static void InstantiateMenu() @@ -30,7 +29,8 @@ namespace SceneManager editPathWaypoints.ForeColor = Color.Gold; editPathMenu.AddItem(deletePath = new UIMenuItem("Delete Path")); deletePath.ForeColor = Color.Gold; - + //editPathMenu.AddItem(exportPath = new UIMenuItem("Export Path")); + //exportPath.ForeColor = Color.Gold; editPathMenu.RefreshIndex(); } @@ -46,7 +46,7 @@ namespace SceneManager private static void DeletePath() { var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index]; - PathMainMenu.DeletePath(currentPath, PathMainMenu.Delete.Single); + PathMainMenu.DeletePath(currentPath, Delete.Single); } private static void DisablePath() @@ -64,6 +64,23 @@ namespace SceneManager } } + private static void ExportPath() + { + var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index]; + // Reference PNWParks's UserInput class from LiveLights + var filename = PNWUserInput.GetUserInput("Type the name you would like to save your file as", "Enter a filename", 100) + ".xml"; + + // If filename != null or empty, check if export directory exists (GTA V/Plugins/SceneManager/Saved Paths) + if(string.IsNullOrWhiteSpace(filename)) + { + Game.DisplayHelp($"Invalid filename given. Filename cannot be null, empty, or consist of just white spaces."); + Game.LogTrivial($"Invalid filename given. Filename cannot be null, empty, or consist of just white spaces."); + return; + } + Game.LogTrivial($"Filename: {filename}"); + currentPath.Save(filename); + } + private static void EditPath_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index) { if (selectedItem == editPathWaypoints) @@ -75,6 +92,11 @@ namespace SceneManager { DeletePath(); } + + if(selectedItem == exportPath) + { + ExportPath(); + } } private static void EditPath_OnCheckboxChange(UIMenu sender, UIMenuCheckboxItem checkboxItem, bool @checked) @@ -88,14 +110,7 @@ namespace SceneManager private static void EditPath_OnMenuOpen(UIMenu menu) { var scrollerItems = new List { }; - var checkboxItems = new Dictionary() { { disablePath, DisablePath } }; - var selectItems = new Dictionary() - { - { editPathWaypoints, EditPathWaypoints }, - { deletePath, DeletePath } - }; - - RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems); + RNUIMouseInputHandler.Initialize(menu, scrollerItems); } } } diff --git a/SceneManager/Menus/EditWaypointMenu.cs b/SceneManager/Menus/EditWaypointMenu.cs index 1b3615b..4413b08 100644 --- a/SceneManager/Menus/EditWaypointMenu.cs +++ b/SceneManager/Menus/EditWaypointMenu.cs @@ -4,6 +4,8 @@ using System.Linq; using Rage; using RAGENativeUI; using RAGENativeUI.Elements; +using SceneManager.Objects; +using SceneManager.Utils; namespace SceneManager { @@ -128,7 +130,7 @@ namespace SceneManager if (currentPath.Waypoints.Count == 1) { Game.LogTrivial($"Deleting the last waypoint from the path."); - PathMainMenu.DeletePath(currentPath, PathMainMenu.Delete.Single); + PathMainMenu.DeletePath(currentPath, Delete.Single); editWaypointMenu.Visible = false; PathMainMenu.pathMainMenu.Visible = true; @@ -291,21 +293,7 @@ namespace SceneManager private static void EditWaypoint_OnMenuOpen(UIMenu menu) { var scrollerItems = new List { editWaypoint, changeWaypointSpeed, changeCollectorRadius, changeSpeedZoneRadius }; - var checkboxItems = new Dictionary() - { - { collectorWaypoint, UpdateCollectorMenuOptionsStatus }, - { stopWaypointType, null }, - { directWaypointBehavior, null }, - { updateWaypointPosition, null } - }; - var selectItems = new Dictionary() - { - { updateWaypoint, UpdateWaypoint }, - { removeWaypoint, RemoveWaypoint }, - { addAsNewWaypoint, AddAsNewWaypoint } - }; - - RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems); + RNUIMouseInputHandler.Initialize(menu, scrollerItems); } private static float SetDriveSpeedForWaypoint() diff --git a/SceneManager/Menus/MainMenu.cs b/SceneManager/Menus/MainMenu.cs index a0b0841..229ce5f 100644 --- a/SceneManager/Menus/MainMenu.cs +++ b/SceneManager/Menus/MainMenu.cs @@ -1,16 +1,14 @@ -using Rage; -using RAGENativeUI; +using RAGENativeUI; using RAGENativeUI.Elements; using System.Collections.Generic; using System.Drawing; -using System.Linq; -using System.Windows.Forms; +using SceneManager.Utils; namespace SceneManager { class MainMenu { - public static UIMenu mainMenu { get; private set; } + internal static UIMenu mainMenu { get; private set; } private static UIMenuItem navigateToPathMenu, navigateToBarrierMenu, navigateToSettingsMenu; internal static void InstantiateMenu() @@ -24,9 +22,11 @@ namespace SceneManager mainMenu.AddItem(navigateToPathMenu = new UIMenuItem("Path Menu")); navigateToPathMenu.ForeColor = Color.Gold; mainMenu.BindMenuToItem(PathMainMenu.pathMainMenu, navigateToPathMenu); + mainMenu.AddItem(navigateToBarrierMenu = new UIMenuItem("Barrier Menu")); navigateToBarrierMenu.ForeColor = Color.Gold; mainMenu.BindMenuToItem(BarrierMenu.barrierMenu, navigateToBarrierMenu); + mainMenu.AddItem(navigateToSettingsMenu = new UIMenuItem("Settings")); navigateToSettingsMenu.ForeColor = Color.Gold; mainMenu.BindMenuToItem(SettingsMenu.settingsMenu, navigateToSettingsMenu); @@ -35,33 +35,10 @@ namespace SceneManager mainMenu.OnMenuOpen += MainMenu_OnMenuOpen; } - private static void ShowPathMainMenu() - { - PathMainMenu.pathMainMenu.Visible = true; - } - - private static void ShowBarrierMenu() - { - BarrierMenu.barrierMenu.Visible = true; - } - - private static void ShowSettingsMenu() - { - SettingsMenu.settingsMenu.Visible = true; - } - private static void MainMenu_OnMenuOpen(UIMenu menu) { var scrollerItems = new List { }; - var checkboxItems = new Dictionary() { }; - var selectItems = new Dictionary() - { - { navigateToPathMenu, ShowPathMainMenu }, - { navigateToBarrierMenu, ShowBarrierMenu }, - { navigateToSettingsMenu, ShowSettingsMenu } - }; - - RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems); + RNUIMouseInputHandler.Initialize(menu, scrollerItems); } } } diff --git a/SceneManager/Menus/MenuManager.cs b/SceneManager/Menus/MenuManager.cs index 4bbe856..6b8edf1 100644 --- a/SceneManager/Menus/MenuManager.cs +++ b/SceneManager/Menus/MenuManager.cs @@ -1,12 +1,16 @@ using RAGENativeUI; +using RAGENativeUI.Elements; +using System.Collections.Generic; +using System.Drawing; namespace SceneManager { - public static class MenuManager + internal static class MenuManager { - public static MenuPool menuPool = new MenuPool(); + internal static MenuPool menuPool = new MenuPool(); + internal static Dictionary> menus = new Dictionary>(); - public static void InstantiateMenus() + internal static void InstantiateMenus() { MainMenu.InstantiateMenu(); SettingsMenu.InstantiateMenu(); diff --git a/SceneManager/Menus/PathCreationMenu.cs b/SceneManager/Menus/PathCreationMenu.cs index 285f73f..efea706 100644 --- a/SceneManager/Menus/PathCreationMenu.cs +++ b/SceneManager/Menus/PathCreationMenu.cs @@ -1,12 +1,11 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Drawing; using System.Linq; -using System.Net.Configuration; -using System.Windows.Forms; using Rage; using RAGENativeUI; using RAGENativeUI.Elements; +using SceneManager.Utils; +using SceneManager.Objects; namespace SceneManager { @@ -313,20 +312,7 @@ namespace SceneManager private static void PathCreation_OnMenuOpen(UIMenu menu) { var scrollerItems = new List { collectorRadius, speedZoneRadius, waypointSpeed }; - var checkboxItems = new Dictionary() - { - { collectorWaypoint, UpdateCollectorMenuOptionsStatus}, - { stopWaypointType, null}, - { directWaypointBehavior, null} - }; - var selectItems = new Dictionary() - { - { trafficAddWaypoint, AddNewWaypoint }, - { trafficRemoveWaypoint, RemoveWaypoint }, - { trafficEndPath, EndPath } - }; - - RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems); + RNUIMouseInputHandler.Initialize(menu, scrollerItems); } } } diff --git a/SceneManager/Menus/PathMainMenu.cs b/SceneManager/Menus/PathMainMenu.cs index 7fb2c35..79b0c8a 100644 --- a/SceneManager/Menus/PathMainMenu.cs +++ b/SceneManager/Menus/PathMainMenu.cs @@ -1,37 +1,29 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Drawing; using System.Linq; -using System.Windows.Forms; using Rage; using RAGENativeUI; using RAGENativeUI.Elements; +using SceneManager.Objects; +using SceneManager.Utils; namespace SceneManager { - - - static class PathMainMenu + internal static class PathMainMenu { - internal static List paths = new List() { }; + internal static List paths = new List(); + internal static List importedPaths = new List(); private static string[] dismissOptions = new string[] { "From path", "From waypoint", "From world" }; - //private static List dismissOptions = new List() { "From path", "From waypoint", "From world" }; - internal static UIMenu pathMainMenu = new UIMenu("Scene Manager", "~o~Path Manager Main Menu"); internal static UIMenuItem createNewPath; + internal static UIMenuListScrollerItem importPath; internal static UIMenuItem deleteAllPaths = new UIMenuItem("Delete All Paths"); internal static UIMenuNumericScrollerItem editPath; internal static UIMenuListScrollerItem directOptions = new UIMenuListScrollerItem("Direct driver to path's", "", new[] { "First waypoint", "Nearest waypoint" }); internal static UIMenuNumericScrollerItem directDriver; - internal static UIMenuListScrollerItem dismissDriver = new UIMenuListScrollerItem("Dismiss nearest driver", $"~b~From path: ~w~AI will be released from the path{Environment.NewLine}~b~From waypoint: ~w~AI will skip their current waypoint task{Environment.NewLine}~b~From world: ~w~AI will be removed from the world.", dismissOptions); + internal static UIMenuListScrollerItem dismissDriver = new UIMenuListScrollerItem("Dismiss nearest driver", $"~b~From path: ~w~AI will be released from the path\n~b~From waypoint: ~w~AI will skip their current waypoint task\n~b~From world: ~w~AI will be removed from the world.", dismissOptions); internal static UIMenuCheckboxItem disableAllPaths = new UIMenuCheckboxItem("Disable All Paths", false); - internal enum Delete - { - Single, - All - } - internal static void InstantiateMenu() { pathMainMenu.ParentMenu = MainMenu.mainMenu; @@ -48,8 +40,9 @@ namespace SceneManager pathMainMenu.AddItem(createNewPath = new UIMenuItem("Create New Path")); createNewPath.ForeColor = Color.Gold; + //pathMainMenu.AddItem(importPath = new UIMenuListScrollerItem("Import Path", "Import a saved path", importedPaths)); + //importPath.ForeColor = Color.Gold; pathMainMenu.AddItem(editPath = new UIMenuNumericScrollerItem("Edit Path", "", 1, paths.Count, 1)); - editPath.Index = 0; editPath.ForeColor = Color.Gold; pathMainMenu.AddItem(disableAllPaths); disableAllPaths.Enabled = true; @@ -421,21 +414,7 @@ namespace SceneManager private static void PathMenu_OnMenuOpen(UIMenu menu) { var scrollerItems = new List { directOptions, directDriver, dismissDriver, editPath }; - var checkboxItems = new Dictionary() - { - { disableAllPaths, DisableAllPaths } - }; - - var selectItems = new Dictionary() - { - { createNewPath, GoToPathCreationMenu }, - { editPath, GoToEditPathMenu }, - { deleteAllPaths, DeleteAllPaths }, - { directDriver, DirectDriver }, - { dismissDriver, DismissDriver } - }; - - RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems); + RNUIMouseInputHandler.Initialize(menu, scrollerItems); } } } diff --git a/SceneManager/Menus/SettingsMenu.cs b/SceneManager/Menus/SettingsMenu.cs index a1012ce..34cf754 100644 --- a/SceneManager/Menus/SettingsMenu.cs +++ b/SceneManager/Menus/SettingsMenu.cs @@ -3,8 +3,8 @@ using RAGENativeUI; using RAGENativeUI.Elements; using System; using System.Collections.Generic; -using System.Linq; -using System.Windows.Forms; +using SceneManager.Objects; +using SceneManager.Utils; namespace SceneManager { @@ -109,18 +109,7 @@ namespace SceneManager private static void SettingsMenu_OnMenuOpen(UIMenu menu) { var scrollerItems = new List { speedUnits }; - var checkboxItems = new Dictionary() - { - { threeDWaypoints, null}, - { mapBlips, ToggleMapBlips}, - { hints, ToggleHints} - }; - var selectItems = new Dictionary() - { - { saveSettings, ToggleSettings } - }; - - RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems); + RNUIMouseInputHandler.Initialize(menu, scrollerItems); } } } \ No newline at end of file diff --git a/SceneManager/Object Classes/Barrier.cs b/SceneManager/Object Classes/Barrier.cs deleted file mode 100644 index d894caf..0000000 --- a/SceneManager/Object Classes/Barrier.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using Rage; - -namespace SceneManager -{ - class Barrier - { - internal Rage.Object Object { get; } - internal Model @Model{ get; } - internal Vector3 Position { get; } - internal float Rotation { get; } - - internal Barrier(Rage.Object barrier, Vector3 barrierPosition, float barrierRotation) - { - Object = barrier; - @Model = barrier.Model; - Position = barrierPosition; - Rotation = barrierRotation; - } - } -} diff --git a/SceneManager/Objects/Barrier.cs b/SceneManager/Objects/Barrier.cs new file mode 100644 index 0000000..327c852 --- /dev/null +++ b/SceneManager/Objects/Barrier.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Rage; +using SceneManager.Utils; + +namespace SceneManager.Objects +{ + class Barrier + { + internal Rage.Object Object { get; } + internal Model @Model{ get; } + internal Vector3 Position { get; } + internal float Rotation { get; } + internal bool Invincible { get; } + + internal bool Immobile { get; } + + internal Barrier(Rage.Object barrier, Vector3 barrierPosition, float barrierRotation, bool invincible, bool immobile) + { + Object = barrier; + @Model = barrier.Model; + Position = barrierPosition; + Rotation = barrierRotation; + Invincible = invincible; + Immobile = immobile; + //AddBlocker(); + } + + private void AddBlocker() + { + var blocker = new Rage.Object("prop_barier_conc_01a", Position, Rotation); + blocker.AttachTo(Object, 0, new Vector3(0, 0, 0), new Rotator()); + GameFiber.StartNew(() => + { + while (Object) + { + GameFiber.Yield(); + } + blocker.Delete(); + }); + } + + internal void GoAround() + { + GameFiber.StartNew(() => + { + var collected = new List(); + while (Object) + { + foreach (Vehicle v in World.GetAllVehicles()) + { + if(v && v.IsEngineOn) + { + if(v.HasDriver && v.Driver && v.Driver.IsAlive) + { + if (!collected.Contains(v)) + { + v.Driver.Tasks.Clear(); + v.Driver.Tasks.CruiseWithVehicle(5f, (VehicleDrivingFlags)17039872); + v.Driver.KeepTasks = true; + collected.Add(v); + } + } + } + } + GameFiber.Sleep(1000); + } + }); + } + } +} diff --git a/SceneManager/Object Classes/CollectedVehicle.cs b/SceneManager/Objects/CollectedVehicle.cs similarity index 94% rename from SceneManager/Object Classes/CollectedVehicle.cs rename to SceneManager/Objects/CollectedVehicle.cs index 46d6df0..a43ca29 100644 --- a/SceneManager/Object Classes/CollectedVehicle.cs +++ b/SceneManager/Objects/CollectedVehicle.cs @@ -1,8 +1,9 @@ using Rage; using System.Collections.Generic; using System.Linq; +using SceneManager.Utils; -namespace SceneManager +namespace SceneManager.Objects { internal class CollectedVehicle { @@ -64,7 +65,7 @@ namespace SceneManager DriveToNextWaypoint(); } - if (!VehicleAndDriverAreValid() || Directed) + if (!Dismissed && !VehicleAndDriverAreValid() || Directed) { return; } @@ -211,6 +212,7 @@ namespace SceneManager { if (oldPosition != Path.Waypoints[currentWaypointTask].Position) { + Game.LogTrivial($"Waypoint position has changed, updating drive task."); oldPosition = Path.Waypoints[currentWaypointTask].Position; Driver.Tasks.DriveToPosition(Path.Waypoints[currentWaypointTask].Position, Path.Waypoints[currentWaypointTask].Speed, (VehicleDrivingFlags)Path.Waypoints[currentWaypointTask].DrivingFlagType, acceptedDistance); } @@ -250,11 +252,6 @@ namespace SceneManager void StopAtWaypoint() { - if (!VehicleAndDriverAreValid()) - { - return; - } - var stoppingDistance = GetAcceptedStoppingDistance(currentWaypoint.Path.Waypoints, currentWaypoint.Path.Waypoints.IndexOf(currentWaypoint)); Game.LogTrivial($"{Vehicle.Model.Name} stopping at path {currentWaypoint.Path.Number} waypoint."); Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Vehicle, stoppingDistance, -1, true); @@ -279,14 +276,15 @@ namespace SceneManager Game.LogTrivial($"CollectedVehicle is null"); return false; } - if (!Vehicle && !Dismissed) + if (!Vehicle)// && !Dismissed) { Game.LogTrivial($"Vehicle is null"); Dismiss(); return false; } - if (!Driver || !Driver.IsAlive) + if (!Driver || !Driver.CurrentVehicle || !Driver.IsAlive) { + Game.LogTrivial($"Driver is null or dead or not in a vehicle"); Dismiss(); return false; } @@ -296,8 +294,14 @@ namespace SceneManager internal void Dismiss(DismissOption dismissOption = DismissOption.FromPath, Path newPath = null) { - if (!Vehicle || !Driver) + if (!Vehicle) { + Game.LogTrivial($"Vehicle is null."); + return; + } + if (!Driver) + { + Game.LogTrivial($"Driver is null."); return; } @@ -310,27 +314,27 @@ namespace SceneManager if (dismissOption == DismissOption.FromPlayer) { Dismissed = true; - if (Driver) - { + //if (Driver) + //{ Driver.Dismiss(); - } - if (Vehicle) - { + //} + //if (Vehicle) + //{ Vehicle.Dismiss(); Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Vehicle, 0f, 1, true); - } + //} Path.CollectedVehicles.Remove(this); return; } - if(Vehicle && StoppedAtWaypoint) + if(Driver.CurrentVehicle && StoppedAtWaypoint) { StoppedAtWaypoint = false; - Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Driver.CurrentVehicle, 0f, 1, true); - if (Driver?.CurrentVehicle) - { + Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Driver.LastVehicle, 0f, 1, true); + //if (Driver) + //{ Driver.Tasks.CruiseWithVehicle(5f); - } + //} } Driver.Tasks.Clear(); diff --git a/SceneManager/Object Classes/Path.cs b/SceneManager/Objects/Path.cs similarity index 83% rename from SceneManager/Object Classes/Path.cs rename to SceneManager/Objects/Path.cs index e13410b..ac59c7f 100644 --- a/SceneManager/Object Classes/Path.cs +++ b/SceneManager/Objects/Path.cs @@ -3,16 +3,26 @@ using System; using System.Collections.Generic; using System.Drawing; using System.Linq; +using System.Xml.Serialization; +using SceneManager.Utils; +using System.IO; -namespace SceneManager +namespace SceneManager.Objects { - public class Path + internal class Path // Change this to Public for import/export { internal int Number { get; set; } internal bool IsEnabled { get; set; } internal State State { get; set; } - internal List Waypoints = new List(); + + [XmlArray("Waypoints")] + [XmlArrayItem("Waypoint")] + public List Waypoints { get; set; } = new List(); + internal List CollectedVehicles = new List(); + private List _blacklistedVehicles = new List(); + + private Path() { } internal Path(int pathNum, State pathState) { @@ -21,6 +31,18 @@ namespace SceneManager DrawLinesBetweenWaypoints(); } + internal void Save(string filename) + { + var GAME_DIRECTORY = Directory.GetCurrentDirectory(); + var SAVED_PATHS_DIRECTORY = GAME_DIRECTORY + "/plugins/SceneManager/Saved Paths/"; + if (!Directory.Exists(SAVED_PATHS_DIRECTORY)) + { + Directory.CreateDirectory(SAVED_PATHS_DIRECTORY); + Game.LogTrivial($"New directory created at '/plugins/SceneManager/Saved Paths'"); + } + PathXMLManager.SaveItemToXML(this, SAVED_PATHS_DIRECTORY + filename); + } + private void LowerWaypointBlipsOpacity() { foreach (Waypoint wp in Waypoints) @@ -125,6 +147,7 @@ namespace SceneManager } CollectedVehicles.RemoveAll(cv => !cv.Vehicle); + _blacklistedVehicles.RemoveAll(v => !v); GameFiber.Sleep(60000); } }); @@ -188,16 +211,26 @@ namespace SceneManager bool VehicleIsValidForCollection(Vehicle v) { - if (v && v != Game.LocalPlayer.Character.LastVehicle && (v.IsCar || v.IsBike || v.IsBicycle || v.IsQuadBike) && !v.IsSirenOn && v.IsEngineOn && v.IsOnAllWheels && v.Speed > 1 && !CollectedVehicles.Any(cv => cv?.Vehicle == v)) + if (v && v != Game.LocalPlayer.Character.LastVehicle && (v.IsCar || v.IsBike || v.IsBicycle || v.IsQuadBike) && !v.IsSirenOn && v.IsEngineOn && v.IsOnAllWheels && v.Speed > 1 && !CollectedVehicles.Any(cv => cv?.Vehicle == v) && !_blacklistedVehicles.Contains(v)) { var vehicleCollectedOnAnotherPath = PathMainMenu.paths.Any(p => p.Number != Number && p.CollectedVehicles.Any(cv => cv.Vehicle == v)); if (vehicleCollectedOnAnotherPath) { return false; } - if (v.HasDriver && v.Driver && !v.Driver.IsAlive) + if (v.HasDriver && v.Driver) { - return false; + if(!v.Driver.IsAlive) + { + Game.LogTrivial($"Vehicle's driver is dead."); + _blacklistedVehicles.Add(v); + return false; + } + if (v.IsPoliceVehicle && !v.Driver.IsAmbient()) + { + _blacklistedVehicles.Add(v); + return false; + } } if (!v.HasDriver) { diff --git a/SceneManager/Object Classes/Waypoint.cs b/SceneManager/Objects/Waypoint.cs similarity index 72% rename from SceneManager/Object Classes/Waypoint.cs rename to SceneManager/Objects/Waypoint.cs index d84f4b5..1048df4 100644 --- a/SceneManager/Object Classes/Waypoint.cs +++ b/SceneManager/Objects/Waypoint.cs @@ -1,27 +1,27 @@ using Rage; -using System; -using System.Collections.Generic; using System.Drawing; using System.Linq; +using SceneManager.Utils; -namespace SceneManager +namespace SceneManager.Objects { - public class Waypoint + internal class Waypoint // Change this to Public for import/export { internal Path Path { get; set; } - internal int Number { get; set; } - internal Vector3 Position { get; set; } - internal float Speed { get; set; } - internal DrivingFlagType DrivingFlagType { get; private set; } - internal bool IsStopWaypoint { get; set; } + public int Number { get; set; } + public Vector3 Position { get; set; } + public float Speed { get; set; } + public DrivingFlagType DrivingFlagType { get; set; } + public bool IsStopWaypoint { get; set; } internal Blip Blip { get; } - internal bool IsCollector { get; set; } - internal float CollectorRadius { get; set; } + public bool IsCollector { get; set; } + public float CollectorRadius { get; set; } internal Blip CollectorRadiusBlip { get; set; } - internal float SpeedZoneRadius { get; set; } + public float SpeedZoneRadius { get; set; } internal uint SpeedZone { get; set; } internal bool EnableWaypointMarker { get; set; } = true; - internal bool EnableEditMarker { get; set; } + + private Waypoint() { } internal Waypoint(Path path, int waypointNum, Vector3 waypointPos, float speed, DrivingFlagType drivingFlag, bool stopWaypoint, Blip waypointBlip, bool collector = false, float collectorRadius = 1, float speedZoneRadius = 5) { @@ -283,103 +283,6 @@ namespace SceneManager } } - internal void CollectVehicles(List paths) - { - var sleepInterval = 1000; - Game.LogTrivial($"Starting collection loop on waypoint {Number}"); - while (paths.Contains(Path) && Path.Waypoints.Contains(this)) - { - if (Path.IsEnabled && IsCollector) - { - sleepInterval = 100; - LoopForNearbyValidVehicles(); - } - else - { - sleepInterval = 1000; - } - - var collectedVehiclePlayerIsIn = Path.CollectedVehicles.Where(x => x.Vehicle == Game.LocalPlayer.Character.CurrentVehicle).FirstOrDefault(); - if (collectedVehiclePlayerIsIn != null) - { - collectedVehiclePlayerIsIn.Dismiss(DismissOption.FromPlayer); - Game.LogTrivial($"Dismissed a collected vehicle the player was in."); - } - GameFiber.Sleep(sleepInterval); - } - - void LoopForNearbyValidVehicles() - { - foreach (Vehicle vehicle in GetNearbyVehiclesForCollection(Position, CollectorRadius)) - { - if (!vehicle) - { - break; - } - - var collectedVehicle = Path.CollectedVehicles.Where(cv => cv.Vehicle == vehicle).FirstOrDefault(); - if (collectedVehicle == null) - { - CollectedVehicle newCollectedVehicle = AddVehicleToCollection(vehicle); - GameFiber AssignTasksFiber = new GameFiber(() => newCollectedVehicle.AssignWaypointTasks(Path, this)); - //GameFiber AssignTasksFiber = new GameFiber(() => AITasking.AssignWaypointTasks(newCollectedVehicle, Path, this)); - AssignTasksFiber.Start(); - } - } - - Vehicle[] GetNearbyVehiclesForCollection(Vector3 collectorWaypointPosition, float collectorRadius) - { - return (from v in World.GetAllVehicles() where v.FrontPosition.DistanceTo2D(collectorWaypointPosition) <= collectorRadius && Math.Abs(collectorWaypointPosition.Z - v.Position.Z) < 3 && IsValidForCollection(v) select v).ToArray(); - } - } - - CollectedVehicle AddVehicleToCollection(Vehicle vehicle) - { - var collectedVehicle = new CollectedVehicle(vehicle, Path, this); - Path.CollectedVehicles.Add(collectedVehicle); - Game.LogTrivial($"Added {vehicle.Model.Name} to collection from path {Path.Number} waypoint {this.Number}."); - return collectedVehicle; - } - - bool IsValidForCollection(Vehicle v) - { - if (v && v.Speed > 1 && v.IsOnAllWheels && v.IsEngineOn && v != Game.LocalPlayer.Character.CurrentVehicle && v != Game.LocalPlayer.Character.LastVehicle && (v.IsCar || v.IsBike || v.IsBicycle || v.IsQuadBike) && !v.IsSirenOn && !Path.CollectedVehicles.Any(cv => cv?.Vehicle == v)) - { - var vehicleCollectedOnAnotherPath = paths.Any(p => p.Number != Path.Number && p.CollectedVehicles.Any(cv => cv.Vehicle == v)); - if (vehicleCollectedOnAnotherPath) - { - return false; - } - if (v.HasDriver && v.Driver && !v.Driver.IsAlive) - { - return false; - } - if (!v.HasDriver) - { - v.CreateRandomDriver(); - while (!v.HasDriver) - { - GameFiber.Yield(); - } - if (v && v.Driver) - { - v.Driver.IsPersistent = true; - v.Driver.BlockPermanentEvents = true; - } - else - { - return false; - } - } - return true; - } - else - { - return false; - } - } - } - private static Vector3 GetMousePositionInWorld() { HitResult TracePlayerView(float maxTraceDistance = 100f, TraceFlags flags = TraceFlags.IntersectWorld) => TracePlayerView2(out Vector3 v1, out Vector3 v2, maxTraceDistance, flags); diff --git a/SceneManager/Properties/AssemblyInfo.cs b/SceneManager/Properties/AssemblyInfo.cs index 4dbff6c..61eac82 100644 --- a/SceneManager/Properties/AssemblyInfo.cs +++ b/SceneManager/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.1.1.0")] -[assembly: AssemblyFileVersion("2.1.1.0")] +[assembly: AssemblyVersion("2.2.0.0")] +[assembly: AssemblyFileVersion("2.2.0.0")] diff --git a/SceneManager/SceneManager.csproj b/SceneManager/SceneManager.csproj index 02725e6..8181199 100644 --- a/SceneManager/SceneManager.csproj +++ b/SceneManager/SceneManager.csproj @@ -12,6 +12,8 @@ v4.8 512 true + + true @@ -31,17 +33,29 @@ 4 + + ..\packages\InputManager.1.0.0\lib\InputManager.dll + D:\Program Files\Rockstar Games\Grand Theft Auto V\RAGENativeUI.dll + False - - D:\Program Files\Rockstar Games\Grand Theft Auto V\plugins\LSPDFR\RagePluginHookSDK.dll + + ..\..\Modding Resources\References\RagePluginHook.dll + False + + + + + + + @@ -50,26 +64,37 @@ - - - - + + + + + + - + - + + + - + - + + + + + + + + \ No newline at end of file diff --git a/SceneManager/SceneManager.obproj b/SceneManager/SceneManager.obproj new file mode 100644 index 0000000..3bb39c5 --- /dev/null +++ b/SceneManager/SceneManager.obproj @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SceneManager/Settings.cs b/SceneManager/Settings.cs index 08d3b4f..915b472 100644 --- a/SceneManager/Settings.cs +++ b/SceneManager/Settings.cs @@ -1,45 +1,11 @@ using Rage; using System.Collections.Generic; using System.Windows.Forms; +using SceneManager.Utils; +using System.IO; namespace SceneManager { - internal enum State - { - Uninitialized, - Creating, - Finished - } - - internal enum SpeedUnits - { - MPH, - KPH - } - - internal enum DrivingFlagType - { - Normal = 263075, - Direct = 17040259 - } - - internal enum DismissOption - { - FromPath = 0, - FromWaypoint = 1, - FromWorld = 2, - FromPlayer = 3, - FromDirected = 4 - } - - internal enum TrafficLight - { - Green = 0, - Red = 1, - Yellow = 2, - None = 3 - } - internal static class Settings { internal static readonly InitializationFile ini = new InitializationFile("Plugins/SceneManager.ini"); @@ -57,6 +23,7 @@ namespace SceneManager internal static SpeedUnits SpeedUnit = SpeedUnits.MPH; internal static float BarrierPlacementDistance = 30f; internal static bool EnableAdvancedBarricadeOptions = false; + internal static bool EnableBarrierLightsDefaultOn = false; // Default Waypoint Settings internal static int CollectorRadius = 1; @@ -66,8 +33,9 @@ namespace SceneManager internal static int WaypointSpeed = 5; // Barriers - internal static List barrierKeys = new List(); - internal static List barrierValues = new List(); + internal static Dictionary barriers = new Dictionary(); + //internal static List barrierKeys = new List(); + //internal static List barrierValues = new List(); internal static void LoadSettings() { @@ -87,7 +55,8 @@ namespace SceneManager SpeedUnit = ini.ReadEnum("Plugin Settings", "SpeedUnits", SpeedUnits.MPH); BarrierPlacementDistance = ini.ReadInt32("Plugin Settings", "BarrierPlacementDistance", 30); EnableAdvancedBarricadeOptions = ini.ReadBoolean("Plugin Settings", "EnableAdvancedBarricadeOptions", false); - + EnableBarrierLightsDefaultOn = ini.ReadBoolean("Plugin Settings", "EnableBarrierLightsDefaultOn", false); + // Default Waypoint Settings CollectorRadius = ini.ReadInt32("Default Waypoint Settings", "CollectorRadius", 1); SpeedZoneRadius = ini.ReadInt32("Default Waypoint Settings", "SpeedZoneRadius", 5); @@ -97,20 +66,23 @@ namespace SceneManager CheckForValidWaypointSettings(); // Barriers - foreach(string key in ini.GetKeyNames("Barriers")) + foreach(string displayName in ini.GetKeyNames("Barriers")) { - barrierKeys.Add(key.Trim()); - var m = new Model(ini.ReadString("Barriers", key)); - if (m.IsValid) + var model = new Model(ini.ReadString("Barriers", displayName.Trim())); + if (model.IsValid) { - barrierValues.Add(m.Name); + barriers.Add(displayName, model); + //barrierKeys.Add(key.Trim()); + //barrierValues.Add(model); } else { - Game.LogTrivial($"{m.Name} is not valid."); + Game.LogTrivial($"{model.Name} is not valid."); } } + //ImportPaths(); + void CheckForValidWaypointSettings() { if(CollectorRadius > 50 || CollectorRadius < 1) @@ -135,6 +107,33 @@ namespace SceneManager Game.LogTrivial($"Invalid value for WaypointSpeed in user settings, resetting to default."); } } + + void ImportPaths() + { + //read each file name in Saved Paths + var GAME_DIRECTORY = Directory.GetCurrentDirectory(); + var SAVED_PATHS_DIRECTORY = GAME_DIRECTORY + "/plugins/SceneManager/Saved Paths/"; + if (!Directory.Exists(SAVED_PATHS_DIRECTORY)) + { + Game.LogTrivial($"Directory '/plugins/SceneManager/Saved Paths' does not exist. No paths available to import."); + return; + } + + //add file name to PathMainMenu.importedPaths + var paths = Directory.GetFiles(SAVED_PATHS_DIRECTORY); + if (paths.Length == 0) + { + Game.LogTrivial($"No saved paths found."); + return; + } + + foreach (string path in paths) + { + Game.LogTrivial($"Path to import: {Path.GetFileName(path)}"); + + // Check if XML is valid before actually importing + } + } } internal static void UpdateSettings(bool threeDWaypointsEnabled, bool mapBlipsEnabled, bool hintsEnabled, SpeedUnits unit) diff --git a/SceneManager/Utils/ConsoleCommands.cs b/SceneManager/Utils/ConsoleCommands.cs new file mode 100644 index 0000000..e812c52 --- /dev/null +++ b/SceneManager/Utils/ConsoleCommands.cs @@ -0,0 +1,52 @@ +using Rage; +using Rage.Attributes; +using Rage.ConsoleCommands.AutoCompleters; +using System.Linq; +using SceneManager.Objects; +using System; +using System.Collections.Generic; + +namespace SceneManager.Utils +{ + internal static class ConsoleCommands + { + [ConsoleCommand] + internal static void Command_ShowCollectedVehicleInfo([ConsoleCommandParameter(AutoCompleterType = typeof(ConsoleCommandAutoCompleterVehicle), Name = "ShowCollectedVehicleInfo")] Vehicle vehicle) + { + foreach(Path path in PathMainMenu.paths) + { + var collectedVehicle = path.CollectedVehicles.Where(v => v.Vehicle == vehicle).FirstOrDefault(); + if(collectedVehicle != null) + { + Game.LogTrivial($"Vehicle: {collectedVehicle.Vehicle.Model.Name} [{collectedVehicle.Vehicle.Handle}]"); + Rage.Native.NativeFunction.Natives.xA6E9C38DB51D7748(collectedVehicle.Vehicle, out uint script); + Game.LogTrivial($"Vehicle spawned by: {script}"); + Game.LogTrivial($"Driver handle: {collectedVehicle.Driver.Handle}"); + Game.LogTrivial($"Path: {collectedVehicle.Path.Number}"); + Game.LogTrivial($"Current waypoint: {collectedVehicle.CurrentWaypoint.Number}"); + Game.LogTrivial($"StoppedAtWaypoint: {collectedVehicle.StoppedAtWaypoint}"); + Game.LogTrivial($"SkipWaypoint: {collectedVehicle.SkipWaypoint}"); + Game.LogTrivial($"ReadyForDirectTasks: {collectedVehicle.ReadyForDirectTasks}"); + Game.LogTrivial($"Directed: {collectedVehicle.Directed}"); + Game.LogTrivial($"Dismissed: {collectedVehicle.Dismissed}"); + Game.LogTrivial($"Task status: {collectedVehicle.Driver.Tasks.CurrentTaskStatus}"); + return; + } + } + Game.LogTrivial($"{vehicle.Model.Name} [{vehicle.Handle}] was not found collected by any path."); + } + + [ConsoleCommand] + internal static void Command_GetPedsActiveTasks([ConsoleCommandParameter(AutoCompleterType = typeof(ConsoleCommandAutoCompleterPedAliveOnly), Name = "GetPedsActiveTasks")] Ped ped) + { + var tasks = new List(); + foreach (PedTask task in (PedTask[])Enum.GetValues(typeof(PedTask))) + { + if(Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE(ped, (int)task)) + { + Game.LogTrivial($"Ped [{ped.Handle}] active task: {task} ({(int)task})"); + } + } + } + } +} diff --git a/SceneManager/Utils/Enums.cs b/SceneManager/Utils/Enums.cs new file mode 100644 index 0000000..49faf18 --- /dev/null +++ b/SceneManager/Utils/Enums.cs @@ -0,0 +1,480 @@ +namespace SceneManager.Utils +{ + internal enum Delete + { + Single, + All + } + + internal enum PedTask + { + CTaskHandsUp = 0, + CTaskClimbLadder = 1, + CTaskExitVehicle = 2, + CTaskCombatRoll = 3, + CTaskAimGunOnFoot = 4, + CTaskMovePlayer = 5, + CTaskPlayerOnFoot = 6, + CTaskWeapon = 8, + CTaskPlayerWeapon = 9, + CTaskPlayerIdles = 10, + CTaskAimGun = 12, + CTaskComplex = 12, + CTaskFSMClone = 12, + CTaskMotionBase = 12, + CTaskMove = 12, + CTaskMoveBase = 12, + CTaskNMBehaviour = 12, + CTaskNavBase = 12, + CTaskScenario = 12, + CTaskSearchBase = 12, + CTaskSearchInVehicleBase = 12, + CTaskShockingEvent = 12, + CTaskTrainBase = 12, + CTaskVehicleFSM = 12, + CTaskVehicleGoTo = 12, + CTaskVehicleMissionBase = 12, + CTaskVehicleTempAction = 12, + CTaskPause = 14, + CTaskDoNothing = 15, + CTaskGetUp = 16, + CTaskGetUpAndStandStill = 17, + CTaskFallOver = 18, + CTaskFallAndGetUp = 19, + CTaskCrawl = 20, + CTaskComplexOnFire = 25, + CTaskDamageElectric = 26, + CTaskTriggerLookAt = 28, + CTaskClearLookAt = 29, + CTaskSetCharDecisionMaker = 30, + CTaskSetPedDefensiveArea = 31, + CTaskUseSequence = 32, + CTaskMoveStandStill = 34, + CTaskComplexControlMovement = 35, + CTaskMoveSequence = 36, + CTaskAmbientClips = 38, + CTaskMoveInAir = 39, + CTaskNetworkClone = 40, + CTaskUseClimbOnRoute = 41, + CTaskUseDropDownOnRoute = 42, + CTaskUseLadderOnRoute = 43, + CTaskSetBlockingOfNonTemporaryEvents = 44, + CTaskForceMotionState = 45, + CTaskSlopeScramble = 46, + CTaskGoToAndClimbLadder = 47, + CTaskClimbLadderFully = 48, + CTaskRappel = 49, + CTaskVault = 50, + CTaskDropDown = 51, + CTaskAffectSecondaryBehaviour = 52, + CTaskAmbientLookAtEvent = 53, + CTaskOpenDoor = 54, + CTaskShovePed = 55, + CTaskSwapWeapon = 56, + CTaskGeneralSweep = 57, + CTaskPolice = 58, + CTaskPoliceOrderResponse = 59, + CTaskPursueCriminal = 60, + CTaskArrestPed = 62, + CTaskArrestPed2 = 63, + CTaskBusted = 64, + CTaskFirePatrol = 65, + CTaskHeliOrderResponse = 66, + CTaskHeliPassengerRappel = 67, + CTaskAmbulancePatrol = 68, + CTaskPoliceWantedResponse = 69, + CTaskSwat = 70, + CTaskSwatWantedResponse = 72, + CTaskSwatOrderResponse = 73, + CTaskSwatGoToStagingArea = 74, + CTaskSwatFollowInLine = 75, + CTaskWitness = 76, + CTaskGangPatrol = 77, + CTaskArmy = 78, + CTaskShockingEventWatch = 80, + CTaskShockingEventGoto = 82, + CTaskShockingEventHurryAway = 83, + CTaskShockingEventReactToAircraft = 84, + CTaskShockingEventReact = 85, + CTaskShockingEventBackAway = 86, + CTaskShockingPoliceInvestigate = 87, + CTaskShockingEventStopAndStare = 88, + CTaskShockingNiceCarPicture = 89, + CTaskShockingEventThreatResponse = 90, + CTaskTakeOffHelmet = 92, + CTaskCarReactToVehicleCollision = 93, + CTaskCarReactToVehicleCollisionGetOut = 95, + CTaskDyingDead = 97, + CTaskWanderingScenario = 100, + CTaskWanderingInRadiusScenario = 101, + CTaskMoveBetweenPointsScenario = 103, + CTaskChatScenario = 104, + CTaskCowerScenario = 106, + CTaskDeadBodyScenario = 107, + CTaskSayAudio = 114, + CTaskWaitForSteppingOut = 116, + CTaskCoupleScenario = 117, + CTaskUseScenario = 118, + CTaskUseVehicleScenario = 119, + CTaskUnalerted = 120, + CTaskStealVehicle = 121, + CTaskReactToPursuit = 122, + CTaskHitWall = 125, + CTaskCower = 126, + CTaskCrouch = 127, + CTaskMelee = 128, + CTaskMoveMeleeMovement = 129, + CTaskMeleeActionResult = 130, + CTaskMeleeUpperbodyAnims = 131, + CTaskMoVEScripted = 133, + CTaskScriptedAnimation = 134, + CTaskSynchronizedScene = 135, + CTaskComplexEvasiveStep = 137, + CTaskWalkRoundCarWhileWandering = 138, + CTaskComplexStuckInAir = 140, + CTaskWalkRoundEntity = 141, + CTaskMoveWalkRoundVehicle = 142, + CTaskReactToGunAimedAt = 144, + CTaskDuckAndCover = 146, + CTaskAggressiveRubberneck = 147, + CTaskInVehicleBasic = 150, + CTaskCarDriveWander = 151, + CTaskLeaveAnyCar = 152, + CTaskComplexGetOffBoat = 153, + CTaskCarSetTempAction = 155, + CTaskBringVehicleToHalt = 156, + CTaskCarDrive = 157, + CTaskPlayerDrive = 159, + CTaskEnterVehicle = 160, + CTaskEnterVehicleAlign = 161, + CTaskOpenVehicleDoorFromOutside = 162, + CTaskEnterVehicleSeat = 163, + CTaskCloseVehicleDoorFromInside = 164, + CTaskInVehicleSeatShuffle = 165, + CTaskExitVehicleSeat = 167, + CTaskCloseVehicleDoorFromOutside = 168, + CTaskControlVehicle = 169, + CTaskMotionInAutomobile = 170, + CTaskMotionOnBicycle = 171, + CTaskMotionOnBicycleController = 172, + CTaskMotionInVehicle = 173, + CTaskMotionInTurret = 174, + CTaskReactToBeingJacked = 175, + CTaskReactToBeingAskedToLeaveVehicle = 176, + CTaskTryToGrabVehicleDoor = 177, + CTaskGetOnTrain = 178, + CTaskGetOffTrain = 179, + CTaskRideTrain = 180, + CTaskMountThrowProjectile = 190, + CTaskGoToCarDoorAndStandStill = 195, + CTaskMoveGoToVehicleDoor = 196, + CTaskSetPedInVehicle = 197, + CTaskSetPedOutOfVehicle = 198, + CTaskVehicleMountedWeapon = 199, + CTaskVehicleGun = 200, + CTaskVehicleProjectile = 201, + CTaskSmashCarWindow = 204, + CTaskMoveGoToPoint = 205, + CTaskMoveAchieveHeading = 206, + CTaskMoveFaceTarget = 207, + CTaskComplexGoToPointAndStandStillTimed = 208, + CTaskMoveGoToPointAndStandStill = 208, + CTaskMoveFollowPointRoute = 209, + CTaskMoveSeekEntity_CEntitySeekPosCalculatorStandard = 210, + CTaskMoveSeekEntity_CEntitySeekPosCalculatorLastNavMeshIntersection = 211, + CTaskMoveSeekEntity_CEntitySeekPosCalculatorLastNavMeshIntersection2 = 212, + CTaskMoveSeekEntity_CEntitySeekPosCalculatorXYOffsetFixed = 213, + CTaskMoveSeekEntity_CEntitySeekPosCalculatorXYOffsetFixed2 = 214, + CTaskExhaustedFlee = 215, + CTaskGrowlAndFlee = 216, + CTaskScenarioFlee = 217, + CTaskSmartFlee = 218, + CTaskFlyAway = 219, + CTaskWalkAway = 220, + CTaskWander = 221, + CTaskWanderInArea = 222, + CTaskFollowLeaderInFormation = 223, + CTaskGoToPointAnyMeans = 224, + CTaskTurnToFaceEntityOrCoord = 225, + CTaskFollowLeaderAnyMeans = 226, + CTaskFlyToPoint = 228, + CTaskFlyingWander = 229, + CTaskGoToPointAiming = 230, + CTaskGoToScenario = 231, + CTaskSeekEntityAiming = 233, + CTaskSlideToCoord = 234, + CTaskSwimmingWander = 235, + CTaskMoveTrackingEntity = 237, + CTaskMoveFollowNavMesh = 238, + CTaskMoveGoToPointOnRoute = 239, + CTaskEscapeBlast = 240, + CTaskMoveWander = 241, + CTaskMoveBeInFormation = 242, + CTaskMoveCrowdAroundLocation = 243, + CTaskMoveCrossRoadAtTrafficLights = 244, + CTaskMoveWaitForTraffic = 245, + CTaskMoveGoToPointStandStillAchieveHeading = 246, + CTaskMoveGetOntoMainNavMesh = 251, + CTaskMoveSlideToCoord = 252, + CTaskMoveGoToPointRelativeToEntityAndStandStill = 253, + CTaskHelicopterStrafe = 254, + CTaskGetOutOfWater = 256, + CTaskMoveFollowEntityOffset = 259, + CTaskFollowWaypointRecording = 261, + CTaskMotionPed = 264, + CTaskMotionPedLowLod = 265, + CTaskHumanLocomotion = 268, + CTaskMotionBasicLocomotionLowLod = 269, + CTaskMotionStrafing = 270, + CTaskMotionTennis = 271, + CTaskMotionAiming = 272, + CTaskBirdLocomotion = 273, + CTaskFlightlessBirdLocomotion = 274, + CTaskFishLocomotion = 278, + CTaskQuadLocomotion = 279, + CTaskMotionDiving = 280, + CTaskMotionSwimming = 281, + CTaskMotionParachuting = 282, + CTaskMotionDrunk = 283, + CTaskRepositionMove = 284, + CTaskMotionAimingTransition = 285, + CTaskThrowProjectile = 286, + CTaskCover = 287, + CTaskMotionInCover = 288, + CTaskAimAndThrowProjectile = 289, + CTaskGun = 290, + CTaskAimFromGround = 291, + CTaskAimGunVehicleDriveBy = 295, + CTaskAimGunScripted = 296, + CTaskReloadGun = 298, + CTaskWeaponBlocked = 299, + CTaskEnterCover = 300, + CTaskExitCover = 301, + CTaskAimGunFromCoverIntro = 302, + CTaskAimGunFromCoverOutro = 303, + CTaskAimGunBlindFire = 304, + CTaskCombatClosestTargetInArea = 307, + CTaskCombatAdditionalTask = 308, + CTaskInCover = 309, + CTaskAimSweep = 313, + CTaskSharkCircle = 319, + CTaskSharkAttack = 320, + CTaskAgitated = 321, + CTaskAgitatedAction = 322, + CTaskConfront = 323, + CTaskIntimidate = 324, + CTaskShove = 325, + CTaskShoved = 326, + CTaskCrouchToggle = 328, + CTaskRevive = 329, + CTaskParachute = 335, + CTaskParachuteObject = 336, + CTaskTakeOffPedVariation = 337, + CTaskCombatSeekCover = 340, + CTaskCombatFlank = 342, + CTaskCombat = 343, + CTaskCombatMounted = 344, + CTaskMoveCircle = 345, + CTaskMoveCombatMounted = 346, + CTaskSearch = 347, + CTaskSearchOnFoot = 348, + CTaskSearchInAutomobile = 349, + CTaskSearchInBoat = 350, + CTaskSearchInHeli = 351, + CTaskThreatResponse = 352, + CTaskInvestigate = 353, + CTaskStandGuardFSM = 354, + CTaskPatrol = 355, + CTaskShootAtTarget = 356, + CTaskSetAndGuardArea = 357, + CTaskStandGuard = 358, + CTaskSeparate = 359, + CTaskStayInCover = 360, + CTaskVehicleCombat = 361, + CTaskVehiclePersuit = 362, + CTaskVehicleChase = 363, + CTaskDraggingToSafety = 364, + CTaskDraggedToSafety = 365, + CTaskVariedAimPose = 366, + CTaskMoveWithinAttackWindow = 367, + CTaskMoveWithinDefensiveArea = 368, + CTaskShootOutTire = 369, + CTaskShellShocked = 370, + CTaskBoatChase = 371, + CTaskBoatCombat = 372, + CTaskBoatStrafe = 373, + CTaskHeliChase = 374, + CTaskHeliCombat = 375, + CTaskSubmarineCombat = 376, + CTaskSubmarineChase = 377, + CTaskPlaneChase = 378, + CTaskTargetUnreachable = 379, + CTaskTargetUnreachableInInterior = 380, + CTaskTargetUnreachableInExterior = 381, + CTaskStealthKill = 382, + CTaskWrithe = 383, + CTaskAdvance = 384, + CTaskCharge = 385, + CTaskMoveToTacticalPoint = 386, + CTaskToHurtTransit = 387, + CTaskAnimatedHitByExplosion = 388, + CTaskNMRelax = 389, + CTaskNMPose = 391, + CTaskNMBrace = 392, + CTaskNMBuoyancy = 393, + CTaskNMInjuredOnGround = 394, + CTaskNMShot = 395, + CTaskNMHighFall = 396, + CTaskNMBalance = 397, + CTaskNMElectrocute = 398, + CTaskNMPrototype = 399, + CTaskNMExplosion = 400, + CTaskNMOnFire = 401, + CTaskNMScriptControl = 402, + CTaskNMJumpRollFromRoadVehicle = 403, + CTaskNMFlinch = 404, + CTaskNMSit = 405, + CTaskNMFallDown = 406, + CTaskBlendFromNM = 407, + CTaskNMControl = 408, + CTaskNMDangle = 409, + CTaskNMGenericAttach = 412, + CTaskNMDraggingToSafety = 414, + CTaskNMThroughWindscreen = 415, + CTaskNMRiverRapids = 416, + CTaskNMSimple = 417, + CTaskRageRagdoll = 418, + CTaskJumpVault = 421, + CTaskJump = 422, + CTaskFall = 423, + CTaskReactAimWeapon = 425, + CTaskChat = 426, + CTaskMobilePhone = 427, + CTaskReactToDeadPed = 428, + CTaskSearchForUnknownThreat = 430, + CTaskBomb = 432, + CTaskDetonator = 433, + CTaskAnimatedAttach = 435, + CTaskCutScene = 441, + CTaskReactToExplosion = 442, + CTaskReactToImminentExplosion = 443, + CTaskDiveToGround = 444, + CTaskReactAndFlee = 445, + CTaskSidestep = 446, + CTaskCallPolice = 447, + CTaskReactInDirection = 448, + CTaskReactToBuddyShot = 449, + CTaskVehicleGoToAutomobileNew = 454, + CTaskVehicleGoToPlane = 455, + CTaskVehicleGoToHelicopter = 456, + CTaskVehicleGoToSubmarine = 457, + CTaskVehicleGoToBoat = 458, + CTaskVehicleGoToPointAutomobile = 459, + CTaskVehicleGoToPointWithAvoidanceAutomobile = 460, + CTaskVehiclePursue = 461, + CTaskVehicleRam = 462, + CTaskVehicleSpinOut = 463, + CTaskVehicleApproach = 464, + CTaskVehicleThreePointTurn = 465, + CTaskVehicleDeadDriver = 466, + CTaskVehicleCruiseNew = 467, + CTaskVehicleCruiseBoat = 468, + CTaskVehicleStop = 469, + CTaskVehiclePullOver = 470, + CTaskVehiclePassengerExit = 471, + CTaskVehicleFlee = 472, + CTaskVehicleFleeAirborne = 473, + CTaskVehicleFleeBoat = 474, + CTaskVehicleFollowRecording = 475, + CTaskVehicleFollow = 476, + CTaskVehicleBlock = 477, + CTaskVehicleBlockCruiseInFront = 478, + CTaskVehicleBlockBrakeInFront = 479, + CTaskVehicleBlockBackAndForth = 478, + CTaskVehicleCrash = 481, + CTaskVehicleLand = 482, + CTaskVehicleLandPlane = 483, + CTaskVehicleHover = 484, + CTaskVehicleAttack = 485, + CTaskVehicleAttackTank = 486, + CTaskVehicleCircle = 487, + CTaskVehiclePoliceBehaviour = 488, + CTaskVehiclePoliceBehaviourHelicopter = 489, + CTaskVehiclePoliceBehaviourBoat = 490, + CTaskVehicleEscort = 491, + CTaskVehicleHeliProtect = 492, + CTaskVehiclePlayerDriveAutomobile = 494, + CTaskVehiclePlayerDriveBike = 495, + CTaskVehiclePlayerDriveBoat = 496, + CTaskVehiclePlayerDriveSubmarine = 497, + CTaskVehiclePlayerDriveSubmarineCar = 498, + CTaskVehiclePlayerDriveAmphibiousAutomobile = 499, + CTaskVehiclePlayerDrivePlane = 500, + CTaskVehiclePlayerDriveHeli = 501, + CTaskVehiclePlayerDriveAutogyro = 502, + CTaskVehiclePlayerDriveDiggerArm = 503, + CTaskVehiclePlayerDriveTrain = 504, + CTaskVehiclePlaneChase = 505, + CTaskVehicleNoDriver = 506, + CTaskVehicleAnimation = 507, + CTaskVehicleConvertibleRoof = 508, + CTaskVehicleParkNew = 509, + CTaskVehicleFollowWaypointRecording = 510, + CTaskVehicleGoToNavmesh = 511, + CTaskVehicleReactToCopSiren = 512, + CTaskVehicleGotoLongRange = 513, + CTaskVehicleWait = 514, + CTaskVehicleReverse = 515, + CTaskVehicleBrake = 516, + CTaskVehicleHandBrake = 517, + CTaskVehicleTurn = 518, + CTaskVehicleGoForward = 519, + CTaskVehicleSwerve = 520, + CTaskVehicleFlyDirection = 521, + CTaskVehicleHeadonCollision = 522, + CTaskVehicleBoostUseSteeringAngle = 523, + CTaskVehicleShotTire = 524, + CTaskVehicleBurnout = 525, + CTaskVehicleRevEngine = 526, + CTaskVehicleSurfaceInSubmarine = 527, + CTaskVehiclePullAlongside = 528, + CTaskVehicleTransformToSubmarine = 529, + CTaskAnimatedFallback = 530 + }; + + internal enum State + { + Uninitialized, + Creating, + Finished + } + + internal enum SpeedUnits + { + MPH, + KPH + } + + internal enum DrivingFlagType + { + Normal = 263075, + Direct = 17040259 + } // Change this to Public for import/export? + + internal enum DismissOption + { + FromPath = 0, + FromWaypoint = 1, + FromWorld = 2, + FromPlayer = 3, + FromDirected = 4 + } + + internal enum TrafficLight + { + Green = 0, + Red = 1, + Yellow = 2, + None = 3 + } +} diff --git a/SceneManager/Utils/Extensions.cs b/SceneManager/Utils/Extensions.cs new file mode 100644 index 0000000..2656499 --- /dev/null +++ b/SceneManager/Utils/Extensions.cs @@ -0,0 +1,100 @@ +using Rage; + +namespace SceneManager.Utils +{ + internal enum PedType + { + /// Any ped + /// + Any = 0, + /// Cop peds + /// + Cop = 1, + //Firefigher = 2, + //EMS = 3 + } + + /// A collection of potentially useful code snippets for GTA/LSPDFR development. + /// + internal static class Extensions + { + /// Determines if a ped can be considered ambient. Checks any type of ped by default. + /// + internal static bool IsAmbient(this Ped ped, PedType pedType = 0) + { + // Universal tasks (virtually all peds seem have this) + var taskAmbientClips = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE(ped, 38); + + // Universal on-foot tasks (virtually all ambient walking peds seem to have this) + var taskComplexControlMovement = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE(ped, 35); + + // Universal in-vehicle tasks (virtually all ambient driver peds seem to have this) + var taskInVehicleBasic = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE(ped, 150); + var taskCarDriveWander = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE(ped, 151); + + // On-foot ambient tasks + var taskPolice = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE(ped, 58); // From ambient cop (non-freemode) walking around + var taskWanderingScenario = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE(ped, 100); // From ambient cop walking around + var taskUseScenario = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE(ped, 118); // From ambient cop standing still + var taskScriptedAnimation = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE(ped, 134); // From UB ped waiting for interaction + + // In-vehicle controlled tasks + var taskControlVehicle = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE(ped, 169); // From backup unit driving to player + + // If ped relationship group does not contain "cop" then this extension doesn't apply + if (pedType == PedType.Cop && !ped.RelationshipGroup.Name.ToLower().Contains("cop")) + { + Game.LogTrivial($"Ped does not belong to a cop relationship group."); + return false; + } + + // Ped is in a vehicle + if (taskInVehicleBasic) + { + Game.LogTrivial($"Ped is in a vehicle."); + // Ped has a controlled driving task + if (taskControlVehicle) + { + Game.LogTrivial($"Ped has a controlled driving task. (non-ambient)"); + return false; + } + + // Ped has a wander driving task + if (taskCarDriveWander) + { + Game.LogTrivial($"Ped has a wander driving task. (ambient)"); + return true; + } + + // If the ped is in a vehicle but doesn't have a driving task, then it's a passenger. Check if the vehicle's driver has a driving wander task + var driverHasWanderTask = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE(ped.CurrentVehicle.Driver, 151); + if (driverHasWanderTask) + { + Game.LogTrivial($"Ped is a passenger. Vehicle's driver has a wander driving task. (ambient)"); + return true; + } + } + + if (ped.IsOnFoot) + { + // UB unit on-foot, waiting for interaction + if (ped.RelationshipGroup.Name == "UBCOP") + { + Game.LogTrivial($"Cop is UB unit. (non-ambient)"); + return false; + } + + // Cop ped walking around or standing still + if ((taskComplexControlMovement && taskWanderingScenario) || (taskAmbientClips && taskUseScenario)) + { + Game.LogTrivial($"Ped is wandering around or standing still. (ambient)"); + return true; + } + } + + // If nothing else returns true before now, then the ped is probably being controlled and doing something else + Game.LogTrivial($"Nothing else has returned true by this point. (non-ambient)"); + return false; + } + } +} diff --git a/SceneManager/GetUserInput.cs b/SceneManager/Utils/GetUserInput.cs similarity index 83% rename from SceneManager/GetUserInput.cs rename to SceneManager/Utils/GetUserInput.cs index 3cfb264..b1277f1 100644 --- a/SceneManager/GetUserInput.cs +++ b/SceneManager/Utils/GetUserInput.cs @@ -1,6 +1,6 @@ using Rage; -namespace SceneManager +namespace SceneManager.Utils { class GetUserInput { @@ -8,8 +8,16 @@ namespace SceneManager { while (true) { - GetKeyboardInput(); - GetControllerInput(); + bool isTextEntryOpen = (Rage.Native.NativeFunction.Natives.UPDATE_ONSCREEN_KEYBOARD() == 0); + if (!isTextEntryOpen) + { + GetKeyboardInput(); + GetControllerInput(); + } + else + { + Game.LogTrivial($"A text menu is open."); + } #if DEBUG if (MenuManager.menuPool.IsAnyMenuOpen()) diff --git a/SceneManager/Utils/MousePositionInWorld.cs b/SceneManager/Utils/MousePositionInWorld.cs new file mode 100644 index 0000000..4f17043 --- /dev/null +++ b/SceneManager/Utils/MousePositionInWorld.cs @@ -0,0 +1,42 @@ +using Rage; + +namespace SceneManager.Utils +{ + internal static class MousePositionInWorld + { + internal static Vector3 GetPosition { get { return GetMousePositionInWorld(); } } + + internal static Vector3 GetPositionForBarrier { get { return GetMousePositionInWorld(Settings.BarrierPlacementDistance); } } + + private static Vector3 GetMousePositionInWorld(float maxDistance = 100f) + { + HitResult TracePlayerView(float maxTraceDistance = 100f, TraceFlags flags = TraceFlags.IntersectWorld) => TracePlayerView2(out Vector3 v1, out Vector3 v2, maxTraceDistance, flags); + + HitResult TracePlayerView2(out Vector3 start, out Vector3 end, float maxTraceDistance, TraceFlags flags) + { + Vector3 direction = GetPlayerLookingDirection(out start); + end = start + (maxTraceDistance * direction); + return World.TraceLine(start, end, flags); + } + + Vector3 GetPlayerLookingDirection(out Vector3 camPosition) + { + if (Camera.RenderingCamera) + { + camPosition = Camera.RenderingCamera.Position; + return Camera.RenderingCamera.Direction; + } + else + { + float pitch = Rage.Native.NativeFunction.Natives.GET_GAMEPLAY_CAM_RELATIVE_PITCH(); + float heading = Rage.Native.NativeFunction.Natives.GET_GAMEPLAY_CAM_RELATIVE_HEADING(); + + camPosition = Rage.Native.NativeFunction.Natives.GET_GAMEPLAY_CAM_COORD(); + return (Game.LocalPlayer.Character.Rotation + new Rotator(pitch, 0, heading)).ToVector().ToNormalized(); + } + } + + return TracePlayerView(maxDistance, TraceFlags.IntersectWorld).HitPosition; + } + } +} diff --git a/SceneManager/Utils/PNWUserInput.cs b/SceneManager/Utils/PNWUserInput.cs new file mode 100644 index 0000000..78e20e0 --- /dev/null +++ b/SceneManager/Utils/PNWUserInput.cs @@ -0,0 +1,28 @@ +using Rage; +using Rage.Native; + +namespace SceneManager.Utils +{ + internal static class PNWUserInput + { + public static string GetUserInput(string windowTitle, string defaultText, int maxLength) + { + NativeFunction.Natives.DISABLE_ALL_CONTROL_ACTIONS(2); + + NativeFunction.Natives.DISPLAY_ONSCREEN_KEYBOARD(true, windowTitle, 0, defaultText, 0, 0, 0, maxLength); + Game.DisplayHelp("Enter the filename you would like to save your path as\n~INPUT_FRONTEND_ACCEPT~ Export path\n~INPUT_FRONTEND_CANCEL~ Cancel", true); + Game.DisplaySubtitle(windowTitle, 100000); + + while (NativeFunction.Natives.UPDATE_ONSCREEN_KEYBOARD() == 0) + { + GameFiber.Yield(); + } + + NativeFunction.Natives.ENABLE_ALL_CONTROL_ACTIONS(2); + Game.DisplaySubtitle("", 5); + Game.HideHelp(); + + return NativeFunction.Natives.GET_ONSCREEN_KEYBOARD_RESULT(); + } + } +} \ No newline at end of file diff --git a/SceneManager/Utils/PathXMLManager.cs b/SceneManager/Utils/PathXMLManager.cs new file mode 100644 index 0000000..5f1b311 --- /dev/null +++ b/SceneManager/Utils/PathXMLManager.cs @@ -0,0 +1,153 @@ +using Rage; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Xml; +using System.Xml.Serialization; + +namespace SceneManager.Utils +{ + internal static class PathXMLManager + { + private static Dictionary _serializerCache = new Dictionary(); + private static XmlSerializer _getOrCreateSerializer(XmlAttributeOverrides overrides = null) + { + if (_serializerCache.ContainsKey(typeof(T))) + { + Game.LogTrivialDebug("Serializer cache already contains " + typeof(T).Name); + return _serializerCache[typeof(T)]; + } + else + { + Game.LogTrivialDebug("Adding " + typeof(T).Name + " to serializer cache"); + Game.LogTrivialDebug("Overrides specified: " + (overrides != null)); + var s = new XmlSerializer(typeof(T), overrides); + _serializerCache.Add(typeof(T), s); + return s; + } + } + + public static void SaveToNode(string file, string node, string value) + { + XmlNode n = SelectNodeFromXml(file, node); + + if (n == null) throw new KeyNotFoundException($"{nameof(SaveToNode)}: specified node does not exists!"); + + n.InnerText = value; + var doc = new XmlDocument(); + doc.Save(file); + } + + public static string ReadFromNode(string file, string node) + { + return SelectNodeFromXml(file, node).InnerText; + } + + private static XmlNode SelectNodeFromXml(string filePath, string node) + { + if (!File.Exists(filePath)) throw new FileNotFoundException($"{nameof(SelectNodeFromXml)}(): specified file does not exist: {filePath}"); + + using (TextReader reader = new StreamReader(filePath)) + { + var doc = new XmlDocument(); + doc.Load(reader); + return doc.SelectSingleNode(node); + } + } + + public static List LoadAllXML(string dirPath, SearchOption searchOption = SearchOption.AllDirectories) + { + if (!Directory.Exists(dirPath)) throw new DirectoryNotFoundException($"{nameof(LoadAllXML)}(): specified directory could not be found: {dirPath}"); + + string[] files = Directory.GetFiles(dirPath, "*.xml", searchOption); + + List result = new List(); + + Array.ForEach(files, f => result.AddRange(LoadFromXML(f))); + + return result; + } + + public static void SaveToXML(List list, string filePath) + { + SaveItemToXML(list, filePath); + } + + public static void SaveItemToXML(T item, string path, XmlAttributeOverrides overrides) + { + Encoding utf8NoBom = new UTF8Encoding(false); + using (TextWriter writer = new StreamWriter(path, false, utf8NoBom)) + { + XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); + ns.Add("", ""); + + // new XmlSerializer(typeof(T)).Serialize(writer, item); + _getOrCreateSerializer(overrides).Serialize(writer, item, ns); + } + } + + public static void SaveItemToXML(T item, string path) + { + SaveItemToXML(item, path, null); + } + + public static T LoadItemFromXML(string filePath, XmlAttributeOverrides overrides) + { + if (!File.Exists(filePath)) throw new FileNotFoundException($"{nameof(LoadItemFromXML)}(): specified file does not exist: {filePath}"); + + using (TextReader reader = new StreamReader(filePath)) + { + return (T)_getOrCreateSerializer(overrides).Deserialize(reader); + } + } + + public static T LoadItemFromXML(string filePath) + { + return (T)LoadItemFromXML(filePath, null); + } + + public static void ModifyItemInXML(string filePath, Action modification) + { + T item = LoadItemFromXML(filePath); + modification(item); + SaveItemToXML(item, filePath); + } + + public static T GetSelectedListElementFromXml(string file, Func, T> selector) + { + List deserialized = LoadItemFromXML>(file); + return selector(deserialized); + } + + public static List LoadFromXML(string filePath) + { + return LoadItemFromXML>(filePath); + } + + public static void AppendToXML(T objectToAdd, string path) + { + ModifyItemInXML>(path, t => t.Add(objectToAdd)); + } + + ///// + ///// Creates folder in case it doesn't exist and checks file existance. + ///// + ///// + ///// false when a file does not exist. + //private static bool ValidatePath(string path) + //{ + // //TODO: implement + // // - check extension + // // - bool param: createDir + // string dir = Path.GetDirectoryName(path); + // if (!Directory.Exists(dir)) + // { + // Directory.CreateDirectory(dir); + // return false; + // } + + // return File.Exists(path); + //} + } +} diff --git a/SceneManager/Utils/RNUIMouseInputHandler.cs b/SceneManager/Utils/RNUIMouseInputHandler.cs new file mode 100644 index 0000000..440f1f9 --- /dev/null +++ b/SceneManager/Utils/RNUIMouseInputHandler.cs @@ -0,0 +1,131 @@ +using InputManager; +using Rage; +using RAGENativeUI; +using RAGENativeUI.Elements; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + + +namespace SceneManager.Utils +{ + internal class RNUIMouseInputHandler + { + internal delegate void Function(); + + internal static void Initialize(UIMenu menu, List scrollerItems) + { + GameFiber.StartNew(() => + { + while (menu.Visible) + { + var selectedScroller = menu.MenuItems.Where(x => scrollerItems.Contains(x) && x.Selected && x.Enabled).FirstOrDefault(); + if (selectedScroller != null) + { + OnWheelScroll(menu, selectedScroller, scrollerItems); + } + + if (Game.IsKeyDown(Keys.LButton) && Rage.Native.NativeFunction.Natives.UPDATE_ONSCREEN_KEYBOARD() != 0) + { + Keyboard.KeyDown(Keys.Enter); + GameFiber.Wait(1); + Keyboard.KeyUp(Keys.Enter); + } + + if (menu.SubtitleText.Contains("Path Creation Menu")) + { + DrawWaypointMarker(); + } + GameFiber.Yield(); + } + }); + } + + internal static void OnWheelScroll(UIMenu menu, UIMenuItem selectedScroller, List scrollerItems) + { + var menuScrollingDisabled = false; + var menuItems = menu.MenuItems.Where(x => x != selectedScroller); + + while (Game.IsShiftKeyDownRightNow) + { + menu.ResetKey(Common.MenuControls.Up); + menu.ResetKey(Common.MenuControls.Down); + menuScrollingDisabled = true; + ScrollMenuItem(); + if (menu.SubtitleText.Contains("Path Creation Menu") || menu.SubtitleText.Contains("Edit Waypoint")) + { + CompareScrollerValues(); + } + if(menu.SubtitleText.Contains("Path Creation Menu")) + { + DrawWaypointMarker(); + } + GameFiber.Yield(); + } + + if (menuScrollingDisabled) + { + menuScrollingDisabled = false; + menu.SetKey(Common.MenuControls.Up, GameControl.CursorScrollUp); + menu.SetKey(Common.MenuControls.Up, GameControl.CellphoneUp); + menu.SetKey(Common.MenuControls.Down, GameControl.CursorScrollDown); + menu.SetKey(Common.MenuControls.Down, GameControl.CellphoneDown); + } + + void ScrollMenuItem() + { + if (Game.GetMouseWheelDelta() > 0) + { + Keyboard.KeyDown(Keys.Right); + GameFiber.Wait(1); + Keyboard.KeyUp(Keys.Right); + } + else if (Game.GetMouseWheelDelta() < 0) + { + Keyboard.KeyDown(Keys.Left); + GameFiber.Wait(1); + Keyboard.KeyUp(Keys.Left); + } + } + + void CompareScrollerValues() + { + var collectorRadius = (UIMenuNumericScrollerItem)scrollerItems.Where(x => x.Text == "Collection Radius").FirstOrDefault(); + var speedZoneRadius = (UIMenuNumericScrollerItem)scrollerItems.Where(x => x.Text == "Speed Zone Radius").FirstOrDefault(); + + if (selectedScroller.Text == "Collection Radius" || selectedScroller.Text == "Speed Zone Radius") + { + if (selectedScroller == collectorRadius && collectorRadius.Value > speedZoneRadius.Value) + { + while (collectorRadius.Value > speedZoneRadius.Value) + { + speedZoneRadius.ScrollToNextOption(); + } + } + if (selectedScroller == speedZoneRadius && speedZoneRadius.Value < collectorRadius.Value) + { + collectorRadius.Value = speedZoneRadius.Value; + } + } + } + } + + private static void DrawWaypointMarker() + { + var waypointPosition = MousePositionInWorld.GetPosition; + if (SettingsMenu.threeDWaypoints.Checked && PathCreationMenu.collectorWaypoint.Checked) + { + Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, waypointPosition, 0, 0, 0, 0, 0, 0, (float)PathCreationMenu.collectorRadius.Value * 2, (float)PathCreationMenu.collectorRadius.Value * 2, 1f, 80, 130, 255, 80, false, false, 2, false, 0, 0, false); + Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, waypointPosition, 0, 0, 0, 0, 0, 0, (float)PathCreationMenu.speedZoneRadius.Value * 2, (float)PathCreationMenu.speedZoneRadius.Value * 2, 1f, 255, 185, 80, 80, false, false, 2, false, 0, 0, false); + } + else if (PathCreationMenu.stopWaypointType.Checked) + { + Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, waypointPosition, 0, 0, 0, 0, 0, 0, 1f, 1f, 1f, 255, 65, 65, 80, false, false, 2, false, 0, 0, false); + } + else + { + Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, waypointPosition, 0, 0, 0, 0, 0, 0, 1f, 1f, 1f, 65, 255, 65, 80, false, false, 2, false, 0, 0, false); + } + } + } +} diff --git a/SceneManager/_ConfuserEx/CommonServiceLocator.dll b/SceneManager/_ConfuserEx/CommonServiceLocator.dll new file mode 100644 index 0000000..3398d83 Binary files /dev/null and b/SceneManager/_ConfuserEx/CommonServiceLocator.dll differ diff --git a/SceneManager/_ConfuserEx/Confuser.CLI.exe b/SceneManager/_ConfuserEx/Confuser.CLI.exe new file mode 100644 index 0000000..9266c0e Binary files /dev/null and b/SceneManager/_ConfuserEx/Confuser.CLI.exe differ diff --git a/SceneManager/_ConfuserEx/Confuser.Core.dll b/SceneManager/_ConfuserEx/Confuser.Core.dll new file mode 100644 index 0000000..042d052 Binary files /dev/null and b/SceneManager/_ConfuserEx/Confuser.Core.dll differ diff --git a/SceneManager/_ConfuserEx/Confuser.DynCipher.dll b/SceneManager/_ConfuserEx/Confuser.DynCipher.dll new file mode 100644 index 0000000..1282976 Binary files /dev/null and b/SceneManager/_ConfuserEx/Confuser.DynCipher.dll differ diff --git a/SceneManager/_ConfuserEx/Confuser.Protections.dll b/SceneManager/_ConfuserEx/Confuser.Protections.dll new file mode 100644 index 0000000..b08109d Binary files /dev/null and b/SceneManager/_ConfuserEx/Confuser.Protections.dll differ diff --git a/SceneManager/_ConfuserEx/Confuser.Renamer.dll b/SceneManager/_ConfuserEx/Confuser.Renamer.dll new file mode 100644 index 0000000..ee363ac Binary files /dev/null and b/SceneManager/_ConfuserEx/Confuser.Renamer.dll differ diff --git a/SceneManager/_ConfuserEx/Confuser.Runtime.dll b/SceneManager/_ConfuserEx/Confuser.Runtime.dll new file mode 100644 index 0000000..3edbf19 Binary files /dev/null and b/SceneManager/_ConfuserEx/Confuser.Runtime.dll differ diff --git a/SceneManager/_ConfuserEx/c.crproj b/SceneManager/_ConfuserEx/c.crproj new file mode 100644 index 0000000..9a9f1f7 --- /dev/null +++ b/SceneManager/_ConfuserEx/c.crproj @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + +..\..\..\packages\InputManager.1.0.0\lib +D:\Program Files\Rockstar Games\Grand Theft Auto V +C:\Users\Rich\Desktop\Mod Stuff\Mod Development\Modding Resources\References +C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8 +C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\Facades + diff --git a/SceneManager/_ConfuserEx/dnlib.dll b/SceneManager/_ConfuserEx/dnlib.dll new file mode 100644 index 0000000..f7347ec Binary files /dev/null and b/SceneManager/_ConfuserEx/dnlib.dll differ diff --git a/SceneManager/app.config b/SceneManager/app.config new file mode 100644 index 0000000..fbfff6f --- /dev/null +++ b/SceneManager/app.config @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SceneManager/packages.config b/SceneManager/packages.config new file mode 100644 index 0000000..9eb48c7 --- /dev/null +++ b/SceneManager/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/SceneManager/smprotected.crproj b/SceneManager/smprotected.crproj new file mode 100644 index 0000000..5982c27 --- /dev/null +++ b/SceneManager/smprotected.crproj @@ -0,0 +1,3 @@ + + + \ No newline at end of file