1
Fork 0
mirror of https://github.com/thegeneralist01/Scene-Manager-DevRepo synced 2026-01-12 08:00:30 +01:00

Merge branch 'Testing'

This commit is contained in:
Rich Dunne 2020-12-06 07:39:31 -07:00
commit 76e265cbe4
39 changed files with 1501 additions and 427 deletions

View file

@ -7,6 +7,9 @@ Drag and drop the contents from within the downloaded GTA V folder into where yo
## GET SUPPORT AND REPORT PROBLEMS ## 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/). 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 ## HOW TO USE SCENE MANAGER
### Using the Menus: ### 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. 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.

View file

@ -4,39 +4,47 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Windows.Forms; using System.Windows.Forms;
using Rage; 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)] [assembly: Rage.Attributes.Plugin("Scene Manager", Author = "Rich", Description = "Control your scenes with custom AI pathing and traffic barrier management.", PrefersSingleInstance = true)]
namespace SceneManager namespace SceneManager
{ {
[Obfuscation(Exclude = false, Feature = "-rename", ApplyToMembers = false)]
public class EntryPoint public class EntryPoint
{ {
[Obfuscation(Exclude = false, Feature = "-rename")]
internal static void Main() internal static void Main()
{ {
if (CheckRNUIVersion()) if(!InputManagerChecker() || !CheckRNUIVersion())
{
AppDomain.CurrentDomain.DomainUnload += MyTerminationHandler;
Settings.LoadSettings();
GetAssemblyVersion();
MenuManager.InstantiateMenus();
DisplayHintsToOpenMenu();
GameFiber UserInputFiber = new GameFiber(() => GetUserInput.LoopForUserInput());
UserInputFiber.Start();
}
else
{ {
Game.UnloadActivePlugin(); Game.UnloadActivePlugin();
return; 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() void GetAssemblyVersion()
{ {
string version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); string version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
Game.LogTrivial($"Scene Manager V{version} is ready."); Game.LogTrivial($"Scene Manager V{version} is ready.");
} }
} }
private static bool CheckRNUIVersion() private static bool CheckRNUIVersion()
{ {
var directory = Directory.GetCurrentDirectory(); var directory = Directory.GetCurrentDirectory();
@ -57,11 +65,25 @@ namespace SceneManager
} }
else 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; 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() private static void DisplayHintsToOpenMenu()
{ {
if (Settings.ModifierKey == Keys.None && Settings.ModifierButton == ControllerButtons.None) if (Settings.ModifierKey == Keys.None && Settings.ModifierButton == ControllerButtons.None)
@ -96,7 +118,7 @@ namespace SceneManager
// Clean up paths // Clean up paths
for (int i = 0; i < PathMainMenu.paths.Count; i++) 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."); Game.LogTrivial($"Plugin has shut down.");

View file

@ -4,6 +4,8 @@ using System.Linq;
using Rage; using Rage;
using RAGENativeUI; using RAGENativeUI;
using RAGENativeUI.Elements; using RAGENativeUI.Elements;
using SceneManager.Objects;
using SceneManager.Utils;
namespace SceneManager namespace SceneManager
{ {
@ -12,11 +14,13 @@ namespace SceneManager
private static List<TrafficLight> trafficLightList = new List<TrafficLight>() { TrafficLight.Green, TrafficLight.Red, TrafficLight.Yellow, TrafficLight.None }; private static List<TrafficLight> trafficLightList = new List<TrafficLight>() { TrafficLight.Green, TrafficLight.Red, TrafficLight.Yellow, TrafficLight.None };
internal static UIMenu barrierMenu = new UIMenu("Scene Manager", "~o~Barrier Management"); internal static UIMenu barrierMenu = new UIMenu("Scene Manager", "~o~Barrier Management");
internal static List<Barrier> barriers = new List<Barrier>(); internal static List<Barrier> barriers = new List<Barrier>();
private static UIMenuListScrollerItem<string> barrierList = new UIMenuListScrollerItem<string>("Spawn Barrier", "", Settings.barrierKeys); private static UIMenuListScrollerItem<string> barrierList = new UIMenuListScrollerItem<string>("Spawn Barrier", "", Settings.barriers.Keys); // Settings.barrierKeys
private static UIMenuNumericScrollerItem<int> rotateBarrier = new UIMenuNumericScrollerItem<int>("Rotate Barrier", "", 0, 350, 10); private static UIMenuNumericScrollerItem<int> rotateBarrier = new UIMenuNumericScrollerItem<int>("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 invincible = new UIMenuCheckboxItem("Indestructible", false);
private static UIMenuCheckboxItem immobile = new UIMenuCheckboxItem("Immobile", false);
private static UIMenuNumericScrollerItem<int> barrierTexture = new UIMenuNumericScrollerItem<int>("Change Texture", "", 0, 15, 1); private static UIMenuNumericScrollerItem<int> barrierTexture = new UIMenuNumericScrollerItem<int>("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<TrafficLight> setBarrierTrafficLight = new UIMenuListScrollerItem<TrafficLight>("Set Barrier Traffic Light", "", trafficLightList); private static UIMenuListScrollerItem<TrafficLight> setBarrierTrafficLight = new UIMenuListScrollerItem<TrafficLight>("Set Barrier Traffic Light", "", trafficLightList);
private static UIMenuListScrollerItem<string> removeBarrierOptions = new UIMenuListScrollerItem<string>("Remove Barrier", "", new[] { "Last Barrier", "Nearest Barrier", "All Barriers" }); private static UIMenuListScrollerItem<string> removeBarrierOptions = new UIMenuListScrollerItem<string>("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"); 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(invincible);
barrierMenu.AddItem(immobile);
if (Settings.EnableAdvancedBarricadeOptions) if (Settings.EnableAdvancedBarricadeOptions)
{ {
barrierMenu.AddItem(barrierTexture); barrierMenu.AddItem(barrierTexture);
@ -49,8 +55,8 @@ namespace SceneManager
barrierMenu.AddItem(setBarrierLights); barrierMenu.AddItem(setBarrierLights);
barrierMenu.AddItem(setBarrierTrafficLight); //barrierMenu.AddItem(setBarrierTrafficLight);
setBarrierTrafficLight.Index = 3; //setBarrierTrafficLight.Index = 3;
} }
barrierMenu.AddItem(removeBarrierOptions); barrierMenu.AddItem(removeBarrierOptions);
@ -69,14 +75,16 @@ namespace SceneManager
shadowBarrier.Delete(); 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) if (!shadowBarrier)
{ {
barrierMenu.Close(); barrierMenu.Close();
Game.DisplayNotification($"~o~Scene Manager ~r~[Error]\n~w~Something went wrong creating the shadow barrier. Please try again."); Game.DisplayNotification($"~o~Scene Manager ~r~[Error]\n~w~Something went wrong creating the shadow barrier. Please try again.");
return; 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); Rage.Native.NativeFunction.Natives.PLACE_OBJECT_ON_GROUND_PROPERLY(shadowBarrier);
shadowBarrier.IsGravityDisabled = true; shadowBarrier.IsGravityDisabled = true;
shadowBarrier.IsCollisionEnabled = false; shadowBarrier.IsCollisionEnabled = false;
@ -94,7 +102,7 @@ namespace SceneManager
{ {
while (barrierMenu.Visible) 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) if (shadowBarrier)
{ {
@ -131,7 +139,7 @@ namespace SceneManager
shadowBarrier.Heading = rotateBarrier.Value; shadowBarrier.Heading = rotateBarrier.Value;
shadowBarrier.Position = MousePositionInWorld.GetPositionForBarrier; shadowBarrier.Position = MousePositionInWorld.GetPositionForBarrier;
Rage.Native.NativeFunction.Natives.PLACE_OBJECT_ON_GROUND_PROPERLY(shadowBarrier); 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() void DisableBarrierMenuOptionsIfShadowConeTooFar()
@ -163,48 +171,64 @@ namespace SceneManager
private static void SpawnBarrier() private static void SpawnBarrier()
{ {
if(barrierList.SelectedItem == "Flare") GameFiber.StartNew(() =>
{ {
SpawnFlare(); if (barrierList.SelectedItem == "Flare")
}
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)
{ {
Rage.Native.NativeFunction.Natives.SET_DISABLE_FRAG_DAMAGE(barrier, true); SpawnFlare();
if(barrier.Model.Name != "prop_barrier_wat_03a")
{
Rage.Native.NativeFunction.Natives.SET_DISABLE_BREAKING(barrier, true);
}
} }
if (Settings.EnableAdvancedBarricadeOptions) else
{ {
Rage.Native.NativeFunction.Natives.x971DA0055324D033(barrier, barrierTexture.Value); var barrier = new Object(shadowBarrier.Model, shadowBarrier.Position, rotateBarrier.Value);
if (setBarrierLights.Checked) 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 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; 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)); }, "Scene Manager Spawn Barrier Fiber");
removeBarrierOptions.Enabled = true;
resetBarriers.Enabled = true;
}
void SpawnFlare() 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; removeBarrierOptions.Enabled = true;
} }
} }
@ -270,31 +294,41 @@ namespace SceneManager
private static void ResetBarriers() private static void ResetBarriers()
{ {
var currentBarriers = barriers.Where(b => b.Model.Name != "0xa2c44e80").ToList(); // 0xa2c44e80 is the flare weapon hash GameFiber.StartNew(() =>
foreach (Barrier barrier in currentBarriers)
{ {
var newBarrier = new Rage.Object(barrier.Model, barrier.Position, barrier.Rotation); var currentBarriers = barriers.Where(b => b.Model.Name != "0xa2c44e80").ToList(); // 0xa2c44e80 is the flare weapon hash
newBarrier.SetPositionWithSnap(barrier.Position); foreach (Barrier barrier in currentBarriers)
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)
{ {
newBarrier.IsPositionFrozen = false; var newBarrier = new Object(barrier.Model, barrier.Position, barrier.Rotation);
} newBarrier.SetPositionWithSnap(barrier.Position);
barriers.Add(new Barrier(newBarrier, newBarrier.Position, newBarrier.Heading)); 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)
if (barrier.Object) {
{ barrier.Object.Delete();
barrier.Object.Delete(); }
barriers.Remove(barrier);
} }
barriers.Remove(barrier); currentBarriers.Clear();
} });
currentBarriers.Clear();
} }
private static void SetBarrierLights() 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_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) private static void BarrierMenu_OnCheckboxChanged(UIMenu sender, UIMenuCheckboxItem checkbox, bool @checked)
@ -378,13 +412,6 @@ namespace SceneManager
private static void BarrierMenu_OnMenuOpen(UIMenu menu) private static void BarrierMenu_OnMenuOpen(UIMenu menu)
{ {
var scrollerItems = new List<UIMenuScrollerItem> { barrierList, barrierTexture, setBarrierTrafficLight, rotateBarrier, removeBarrierOptions }; var scrollerItems = new List<UIMenuScrollerItem> { barrierList, barrierTexture, setBarrierTrafficLight, rotateBarrier, removeBarrierOptions };
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>() { { invincible, null }, {setBarrierLights, SetBarrierLights} };
var selectItems = new Dictionary<UIMenuItem, RNUIMouseInputHandler.Function>()
{
{ 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."); Hints.Display($"~o~Scene Manager ~y~[Hint]\n~w~The shadow barrier will disappear if you aim too far away.");
CreateShadowBarrier(); CreateShadowBarrier();
@ -392,7 +419,7 @@ namespace SceneManager
GameFiber ShadowConeLoopFiber = new GameFiber(() => LoopToDisplayShadowBarrier()); GameFiber ShadowConeLoopFiber = new GameFiber(() => LoopToDisplayShadowBarrier());
ShadowConeLoopFiber.Start(); ShadowConeLoopFiber.Start();
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems); RNUIMouseInputHandler.Initialize(menu, scrollerItems);
} }
internal static float SetMenuWidth() internal static float SetMenuWidth()

View file

@ -1,17 +1,16 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using Rage; using Rage;
using RAGENativeUI; using RAGENativeUI;
using RAGENativeUI.Elements; using RAGENativeUI.Elements;
using SceneManager.Utils;
namespace SceneManager namespace SceneManager
{ {
class EditPathMenu class EditPathMenu
{ {
internal static UIMenu editPathMenu = new UIMenu("Scene Manager", "~o~Edit Path"); 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 UIMenuCheckboxItem disablePath;
internal static void InstantiateMenu() internal static void InstantiateMenu()
@ -30,7 +29,8 @@ namespace SceneManager
editPathWaypoints.ForeColor = Color.Gold; editPathWaypoints.ForeColor = Color.Gold;
editPathMenu.AddItem(deletePath = new UIMenuItem("Delete Path")); editPathMenu.AddItem(deletePath = new UIMenuItem("Delete Path"));
deletePath.ForeColor = Color.Gold; deletePath.ForeColor = Color.Gold;
//editPathMenu.AddItem(exportPath = new UIMenuItem("Export Path"));
//exportPath.ForeColor = Color.Gold;
editPathMenu.RefreshIndex(); editPathMenu.RefreshIndex();
} }
@ -46,7 +46,7 @@ namespace SceneManager
private static void DeletePath() private static void DeletePath()
{ {
var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index]; var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index];
PathMainMenu.DeletePath(currentPath, PathMainMenu.Delete.Single); PathMainMenu.DeletePath(currentPath, Delete.Single);
} }
private static void DisablePath() 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) private static void EditPath_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
{ {
if (selectedItem == editPathWaypoints) if (selectedItem == editPathWaypoints)
@ -75,6 +92,11 @@ namespace SceneManager
{ {
DeletePath(); DeletePath();
} }
if(selectedItem == exportPath)
{
ExportPath();
}
} }
private static void EditPath_OnCheckboxChange(UIMenu sender, UIMenuCheckboxItem checkboxItem, bool @checked) private static void EditPath_OnCheckboxChange(UIMenu sender, UIMenuCheckboxItem checkboxItem, bool @checked)
@ -88,14 +110,7 @@ namespace SceneManager
private static void EditPath_OnMenuOpen(UIMenu menu) private static void EditPath_OnMenuOpen(UIMenu menu)
{ {
var scrollerItems = new List<UIMenuScrollerItem> { }; var scrollerItems = new List<UIMenuScrollerItem> { };
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>() { { disablePath, DisablePath } }; RNUIMouseInputHandler.Initialize(menu, scrollerItems);
var selectItems = new Dictionary<UIMenuItem, RNUIMouseInputHandler.Function>()
{
{ editPathWaypoints, EditPathWaypoints },
{ deletePath, DeletePath }
};
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems);
} }
} }
} }

View file

@ -4,6 +4,8 @@ using System.Linq;
using Rage; using Rage;
using RAGENativeUI; using RAGENativeUI;
using RAGENativeUI.Elements; using RAGENativeUI.Elements;
using SceneManager.Objects;
using SceneManager.Utils;
namespace SceneManager namespace SceneManager
{ {
@ -128,7 +130,7 @@ namespace SceneManager
if (currentPath.Waypoints.Count == 1) if (currentPath.Waypoints.Count == 1)
{ {
Game.LogTrivial($"Deleting the last waypoint from the path."); Game.LogTrivial($"Deleting the last waypoint from the path.");
PathMainMenu.DeletePath(currentPath, PathMainMenu.Delete.Single); PathMainMenu.DeletePath(currentPath, Delete.Single);
editWaypointMenu.Visible = false; editWaypointMenu.Visible = false;
PathMainMenu.pathMainMenu.Visible = true; PathMainMenu.pathMainMenu.Visible = true;
@ -291,21 +293,7 @@ namespace SceneManager
private static void EditWaypoint_OnMenuOpen(UIMenu menu) private static void EditWaypoint_OnMenuOpen(UIMenu menu)
{ {
var scrollerItems = new List<UIMenuScrollerItem> { editWaypoint, changeWaypointSpeed, changeCollectorRadius, changeSpeedZoneRadius }; var scrollerItems = new List<UIMenuScrollerItem> { editWaypoint, changeWaypointSpeed, changeCollectorRadius, changeSpeedZoneRadius };
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>() RNUIMouseInputHandler.Initialize(menu, scrollerItems);
{
{ collectorWaypoint, UpdateCollectorMenuOptionsStatus },
{ stopWaypointType, null },
{ directWaypointBehavior, null },
{ updateWaypointPosition, null }
};
var selectItems = new Dictionary<UIMenuItem, RNUIMouseInputHandler.Function>()
{
{ updateWaypoint, UpdateWaypoint },
{ removeWaypoint, RemoveWaypoint },
{ addAsNewWaypoint, AddAsNewWaypoint }
};
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems);
} }
private static float SetDriveSpeedForWaypoint() private static float SetDriveSpeedForWaypoint()

View file

@ -1,16 +1,14 @@
using Rage; using RAGENativeUI;
using RAGENativeUI;
using RAGENativeUI.Elements; using RAGENativeUI.Elements;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; using SceneManager.Utils;
using System.Windows.Forms;
namespace SceneManager namespace SceneManager
{ {
class MainMenu class MainMenu
{ {
public static UIMenu mainMenu { get; private set; } internal static UIMenu mainMenu { get; private set; }
private static UIMenuItem navigateToPathMenu, navigateToBarrierMenu, navigateToSettingsMenu; private static UIMenuItem navigateToPathMenu, navigateToBarrierMenu, navigateToSettingsMenu;
internal static void InstantiateMenu() internal static void InstantiateMenu()
@ -24,9 +22,11 @@ namespace SceneManager
mainMenu.AddItem(navigateToPathMenu = new UIMenuItem("Path Menu")); mainMenu.AddItem(navigateToPathMenu = new UIMenuItem("Path Menu"));
navigateToPathMenu.ForeColor = Color.Gold; navigateToPathMenu.ForeColor = Color.Gold;
mainMenu.BindMenuToItem(PathMainMenu.pathMainMenu, navigateToPathMenu); mainMenu.BindMenuToItem(PathMainMenu.pathMainMenu, navigateToPathMenu);
mainMenu.AddItem(navigateToBarrierMenu = new UIMenuItem("Barrier Menu")); mainMenu.AddItem(navigateToBarrierMenu = new UIMenuItem("Barrier Menu"));
navigateToBarrierMenu.ForeColor = Color.Gold; navigateToBarrierMenu.ForeColor = Color.Gold;
mainMenu.BindMenuToItem(BarrierMenu.barrierMenu, navigateToBarrierMenu); mainMenu.BindMenuToItem(BarrierMenu.barrierMenu, navigateToBarrierMenu);
mainMenu.AddItem(navigateToSettingsMenu = new UIMenuItem("Settings")); mainMenu.AddItem(navigateToSettingsMenu = new UIMenuItem("Settings"));
navigateToSettingsMenu.ForeColor = Color.Gold; navigateToSettingsMenu.ForeColor = Color.Gold;
mainMenu.BindMenuToItem(SettingsMenu.settingsMenu, navigateToSettingsMenu); mainMenu.BindMenuToItem(SettingsMenu.settingsMenu, navigateToSettingsMenu);
@ -35,33 +35,10 @@ namespace SceneManager
mainMenu.OnMenuOpen += MainMenu_OnMenuOpen; 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) private static void MainMenu_OnMenuOpen(UIMenu menu)
{ {
var scrollerItems = new List<UIMenuScrollerItem> { }; var scrollerItems = new List<UIMenuScrollerItem> { };
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>() { }; RNUIMouseInputHandler.Initialize(menu, scrollerItems);
var selectItems = new Dictionary<UIMenuItem, RNUIMouseInputHandler.Function>()
{
{ navigateToPathMenu, ShowPathMainMenu },
{ navigateToBarrierMenu, ShowBarrierMenu },
{ navigateToSettingsMenu, ShowSettingsMenu }
};
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems);
} }
} }
} }

View file

@ -1,12 +1,16 @@
using RAGENativeUI; using RAGENativeUI;
using RAGENativeUI.Elements;
using System.Collections.Generic;
using System.Drawing;
namespace SceneManager 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<UIMenu, List<UIMenuItem>> menus = new Dictionary<UIMenu, List<UIMenuItem>>();
public static void InstantiateMenus() internal static void InstantiateMenus()
{ {
MainMenu.InstantiateMenu(); MainMenu.InstantiateMenu();
SettingsMenu.InstantiateMenu(); SettingsMenu.InstantiateMenu();

View file

@ -1,12 +1,11 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using System.Net.Configuration;
using System.Windows.Forms;
using Rage; using Rage;
using RAGENativeUI; using RAGENativeUI;
using RAGENativeUI.Elements; using RAGENativeUI.Elements;
using SceneManager.Utils;
using SceneManager.Objects;
namespace SceneManager namespace SceneManager
{ {
@ -313,20 +312,7 @@ namespace SceneManager
private static void PathCreation_OnMenuOpen(UIMenu menu) private static void PathCreation_OnMenuOpen(UIMenu menu)
{ {
var scrollerItems = new List<UIMenuScrollerItem> { collectorRadius, speedZoneRadius, waypointSpeed }; var scrollerItems = new List<UIMenuScrollerItem> { collectorRadius, speedZoneRadius, waypointSpeed };
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>() RNUIMouseInputHandler.Initialize(menu, scrollerItems);
{
{ collectorWaypoint, UpdateCollectorMenuOptionsStatus},
{ stopWaypointType, null},
{ directWaypointBehavior, null}
};
var selectItems = new Dictionary<UIMenuItem, RNUIMouseInputHandler.Function>()
{
{ trafficAddWaypoint, AddNewWaypoint },
{ trafficRemoveWaypoint, RemoveWaypoint },
{ trafficEndPath, EndPath }
};
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems);
} }
} }
} }

View file

@ -1,37 +1,29 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using System.Windows.Forms;
using Rage; using Rage;
using RAGENativeUI; using RAGENativeUI;
using RAGENativeUI.Elements; using RAGENativeUI.Elements;
using SceneManager.Objects;
using SceneManager.Utils;
namespace SceneManager namespace SceneManager
{ {
internal static class PathMainMenu
static class PathMainMenu
{ {
internal static List<Path> paths = new List<Path>() { }; internal static List<Path> paths = new List<Path>();
internal static List<string> importedPaths = new List<string>();
private static string[] dismissOptions = new string[] { "From path", "From waypoint", "From world" }; private static string[] dismissOptions = new string[] { "From path", "From waypoint", "From world" };
//private static List<string> dismissOptions = new List<string>() { "From path", "From waypoint", "From world" };
internal static UIMenu pathMainMenu = new UIMenu("Scene Manager", "~o~Path Manager Main Menu"); internal static UIMenu pathMainMenu = new UIMenu("Scene Manager", "~o~Path Manager Main Menu");
internal static UIMenuItem createNewPath; internal static UIMenuItem createNewPath;
internal static UIMenuListScrollerItem<string> importPath;
internal static UIMenuItem deleteAllPaths = new UIMenuItem("Delete All Paths"); internal static UIMenuItem deleteAllPaths = new UIMenuItem("Delete All Paths");
internal static UIMenuNumericScrollerItem<int> editPath; internal static UIMenuNumericScrollerItem<int> editPath;
internal static UIMenuListScrollerItem<string> directOptions = new UIMenuListScrollerItem<string>("Direct driver to path's", "", new[] { "First waypoint", "Nearest waypoint" }); internal static UIMenuListScrollerItem<string> directOptions = new UIMenuListScrollerItem<string>("Direct driver to path's", "", new[] { "First waypoint", "Nearest waypoint" });
internal static UIMenuNumericScrollerItem<int> directDriver; internal static UIMenuNumericScrollerItem<int> directDriver;
internal static UIMenuListScrollerItem<string> dismissDriver = new UIMenuListScrollerItem<string>("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<string> dismissDriver = new UIMenuListScrollerItem<string>("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 static UIMenuCheckboxItem disableAllPaths = new UIMenuCheckboxItem("Disable All Paths", false);
internal enum Delete
{
Single,
All
}
internal static void InstantiateMenu() internal static void InstantiateMenu()
{ {
pathMainMenu.ParentMenu = MainMenu.mainMenu; pathMainMenu.ParentMenu = MainMenu.mainMenu;
@ -48,8 +40,9 @@ namespace SceneManager
pathMainMenu.AddItem(createNewPath = new UIMenuItem("Create New Path")); pathMainMenu.AddItem(createNewPath = new UIMenuItem("Create New Path"));
createNewPath.ForeColor = Color.Gold; createNewPath.ForeColor = Color.Gold;
//pathMainMenu.AddItem(importPath = new UIMenuListScrollerItem<string>("Import Path", "Import a saved path", importedPaths));
//importPath.ForeColor = Color.Gold;
pathMainMenu.AddItem(editPath = new UIMenuNumericScrollerItem<int>("Edit Path", "", 1, paths.Count, 1)); pathMainMenu.AddItem(editPath = new UIMenuNumericScrollerItem<int>("Edit Path", "", 1, paths.Count, 1));
editPath.Index = 0;
editPath.ForeColor = Color.Gold; editPath.ForeColor = Color.Gold;
pathMainMenu.AddItem(disableAllPaths); pathMainMenu.AddItem(disableAllPaths);
disableAllPaths.Enabled = true; disableAllPaths.Enabled = true;
@ -421,21 +414,7 @@ namespace SceneManager
private static void PathMenu_OnMenuOpen(UIMenu menu) private static void PathMenu_OnMenuOpen(UIMenu menu)
{ {
var scrollerItems = new List<UIMenuScrollerItem> { directOptions, directDriver, dismissDriver, editPath }; var scrollerItems = new List<UIMenuScrollerItem> { directOptions, directDriver, dismissDriver, editPath };
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>() RNUIMouseInputHandler.Initialize(menu, scrollerItems);
{
{ disableAllPaths, DisableAllPaths }
};
var selectItems = new Dictionary<UIMenuItem, RNUIMouseInputHandler.Function>()
{
{ createNewPath, GoToPathCreationMenu },
{ editPath, GoToEditPathMenu },
{ deleteAllPaths, DeleteAllPaths },
{ directDriver, DirectDriver },
{ dismissDriver, DismissDriver }
};
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems);
} }
} }
} }

View file

@ -3,8 +3,8 @@ using RAGENativeUI;
using RAGENativeUI.Elements; using RAGENativeUI.Elements;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using SceneManager.Objects;
using System.Windows.Forms; using SceneManager.Utils;
namespace SceneManager namespace SceneManager
{ {
@ -109,18 +109,7 @@ namespace SceneManager
private static void SettingsMenu_OnMenuOpen(UIMenu menu) private static void SettingsMenu_OnMenuOpen(UIMenu menu)
{ {
var scrollerItems = new List<UIMenuScrollerItem> { speedUnits }; var scrollerItems = new List<UIMenuScrollerItem> { speedUnits };
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>() RNUIMouseInputHandler.Initialize(menu, scrollerItems);
{
{ threeDWaypoints, null},
{ mapBlips, ToggleMapBlips},
{ hints, ToggleHints}
};
var selectItems = new Dictionary<UIMenuItem, RNUIMouseInputHandler.Function>()
{
{ saveSettings, ToggleSettings }
};
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems);
} }
} }
} }

View file

@ -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;
}
}
}

View file

@ -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<Vehicle>();
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);
}
});
}
}
}

View file

@ -1,8 +1,9 @@
using Rage; using Rage;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using SceneManager.Utils;
namespace SceneManager namespace SceneManager.Objects
{ {
internal class CollectedVehicle internal class CollectedVehicle
{ {
@ -64,7 +65,7 @@ namespace SceneManager
DriveToNextWaypoint(); DriveToNextWaypoint();
} }
if (!VehicleAndDriverAreValid() || Directed) if (!Dismissed && !VehicleAndDriverAreValid() || Directed)
{ {
return; return;
} }
@ -211,6 +212,7 @@ namespace SceneManager
{ {
if (oldPosition != Path.Waypoints[currentWaypointTask].Position) if (oldPosition != Path.Waypoints[currentWaypointTask].Position)
{ {
Game.LogTrivial($"Waypoint position has changed, updating drive task.");
oldPosition = Path.Waypoints[currentWaypointTask].Position; oldPosition = Path.Waypoints[currentWaypointTask].Position;
Driver.Tasks.DriveToPosition(Path.Waypoints[currentWaypointTask].Position, Path.Waypoints[currentWaypointTask].Speed, (VehicleDrivingFlags)Path.Waypoints[currentWaypointTask].DrivingFlagType, acceptedDistance); 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() void StopAtWaypoint()
{ {
if (!VehicleAndDriverAreValid())
{
return;
}
var stoppingDistance = GetAcceptedStoppingDistance(currentWaypoint.Path.Waypoints, currentWaypoint.Path.Waypoints.IndexOf(currentWaypoint)); var stoppingDistance = GetAcceptedStoppingDistance(currentWaypoint.Path.Waypoints, currentWaypoint.Path.Waypoints.IndexOf(currentWaypoint));
Game.LogTrivial($"{Vehicle.Model.Name} stopping at path {currentWaypoint.Path.Number} waypoint."); Game.LogTrivial($"{Vehicle.Model.Name} stopping at path {currentWaypoint.Path.Number} waypoint.");
Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Vehicle, stoppingDistance, -1, true); Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Vehicle, stoppingDistance, -1, true);
@ -279,14 +276,15 @@ namespace SceneManager
Game.LogTrivial($"CollectedVehicle is null"); Game.LogTrivial($"CollectedVehicle is null");
return false; return false;
} }
if (!Vehicle && !Dismissed) if (!Vehicle)// && !Dismissed)
{ {
Game.LogTrivial($"Vehicle is null"); Game.LogTrivial($"Vehicle is null");
Dismiss(); Dismiss();
return false; 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(); Dismiss();
return false; return false;
} }
@ -296,8 +294,14 @@ namespace SceneManager
internal void Dismiss(DismissOption dismissOption = DismissOption.FromPath, Path newPath = null) 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; return;
} }
@ -310,27 +314,27 @@ namespace SceneManager
if (dismissOption == DismissOption.FromPlayer) if (dismissOption == DismissOption.FromPlayer)
{ {
Dismissed = true; Dismissed = true;
if (Driver) //if (Driver)
{ //{
Driver.Dismiss(); Driver.Dismiss();
} //}
if (Vehicle) //if (Vehicle)
{ //{
Vehicle.Dismiss(); Vehicle.Dismiss();
Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Vehicle, 0f, 1, true); Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Vehicle, 0f, 1, true);
} //}
Path.CollectedVehicles.Remove(this); Path.CollectedVehicles.Remove(this);
return; return;
} }
if(Vehicle && StoppedAtWaypoint) if(Driver.CurrentVehicle && StoppedAtWaypoint)
{ {
StoppedAtWaypoint = false; StoppedAtWaypoint = false;
Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Driver.CurrentVehicle, 0f, 1, true); Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Driver.LastVehicle, 0f, 1, true);
if (Driver?.CurrentVehicle) //if (Driver)
{ //{
Driver.Tasks.CruiseWithVehicle(5f); Driver.Tasks.CruiseWithVehicle(5f);
} //}
} }
Driver.Tasks.Clear(); Driver.Tasks.Clear();

View file

@ -3,16 +3,26 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; 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 int Number { get; set; }
internal bool IsEnabled { get; set; } internal bool IsEnabled { get; set; }
internal State State { get; set; } internal State State { get; set; }
internal List<Waypoint> Waypoints = new List<Waypoint>();
[XmlArray("Waypoints")]
[XmlArrayItem("Waypoint")]
public List<Waypoint> Waypoints { get; set; } = new List<Waypoint>();
internal List<CollectedVehicle> CollectedVehicles = new List<CollectedVehicle>(); internal List<CollectedVehicle> CollectedVehicles = new List<CollectedVehicle>();
private List<Vehicle> _blacklistedVehicles = new List<Vehicle>();
private Path() { }
internal Path(int pathNum, State pathState) internal Path(int pathNum, State pathState)
{ {
@ -21,6 +31,18 @@ namespace SceneManager
DrawLinesBetweenWaypoints(); 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() private void LowerWaypointBlipsOpacity()
{ {
foreach (Waypoint wp in Waypoints) foreach (Waypoint wp in Waypoints)
@ -125,6 +147,7 @@ namespace SceneManager
} }
CollectedVehicles.RemoveAll(cv => !cv.Vehicle); CollectedVehicles.RemoveAll(cv => !cv.Vehicle);
_blacklistedVehicles.RemoveAll(v => !v);
GameFiber.Sleep(60000); GameFiber.Sleep(60000);
} }
}); });
@ -188,16 +211,26 @@ namespace SceneManager
bool VehicleIsValidForCollection(Vehicle v) 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)); var vehicleCollectedOnAnotherPath = PathMainMenu.paths.Any(p => p.Number != Number && p.CollectedVehicles.Any(cv => cv.Vehicle == v));
if (vehicleCollectedOnAnotherPath) if (vehicleCollectedOnAnotherPath)
{ {
return false; 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) if (!v.HasDriver)
{ {

View file

@ -1,27 +1,27 @@
using Rage; using Rage;
using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; 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 Path Path { get; set; }
internal int Number { get; set; } public int Number { get; set; }
internal Vector3 Position { get; set; } public Vector3 Position { get; set; }
internal float Speed { get; set; } public float Speed { get; set; }
internal DrivingFlagType DrivingFlagType { get; private set; } public DrivingFlagType DrivingFlagType { get; set; }
internal bool IsStopWaypoint { get; set; } public bool IsStopWaypoint { get; set; }
internal Blip Blip { get; } internal Blip Blip { get; }
internal bool IsCollector { get; set; } public bool IsCollector { get; set; }
internal float CollectorRadius { get; set; } public float CollectorRadius { get; set; }
internal Blip CollectorRadiusBlip { get; set; } internal Blip CollectorRadiusBlip { get; set; }
internal float SpeedZoneRadius { get; set; } public float SpeedZoneRadius { get; set; }
internal uint SpeedZone { get; set; } internal uint SpeedZone { get; set; }
internal bool EnableWaypointMarker { get; set; } = true; 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) 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<Path> 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() private static Vector3 GetMousePositionInWorld()
{ {
HitResult TracePlayerView(float maxTraceDistance = 100f, TraceFlags flags = TraceFlags.IntersectWorld) => TracePlayerView2(out Vector3 v1, out Vector3 v2, maxTraceDistance, flags); HitResult TracePlayerView(float maxTraceDistance = 100f, TraceFlags flags = TraceFlags.IntersectWorld) => TracePlayerView2(out Vector3 v1, out Vector3 v2, maxTraceDistance, flags);

View file

@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.1.1.0")] [assembly: AssemblyVersion("2.2.0.0")]
[assembly: AssemblyFileVersion("2.1.1.0")] [assembly: AssemblyFileVersion("2.2.0.0")]

View file

@ -12,6 +12,8 @@
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion> <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic> <Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@ -31,17 +33,29 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="InputManager, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\InputManager.1.0.0\lib\InputManager.dll</HintPath>
</Reference>
<Reference Include="RAGENativeUI"> <Reference Include="RAGENativeUI">
<HintPath>D:\Program Files\Rockstar Games\Grand Theft Auto V\RAGENativeUI.dll</HintPath> <HintPath>D:\Program Files\Rockstar Games\Grand Theft Auto V\RAGENativeUI.dll</HintPath>
<Private>False</Private>
</Reference> </Reference>
<Reference Include="RagePluginHookSDK"> <Reference Include="RagePluginHook">
<HintPath>D:\Program Files\Rockstar Games\Grand Theft Auto V\plugins\LSPDFR\RagePluginHookSDK.dll</HintPath> <HintPath>..\..\Modding Resources\References\RagePluginHook.dll</HintPath>
<Private>False</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Management" /> <Reference Include="System.Management" />
<Reference Include="System.Numerics" />
<Reference Include="System.Reflection" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Security" />
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
@ -50,26 +64,37 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="ConsoleCommands.cs" /> <Compile Include="Utils\ConsoleCommands.cs" />
<Compile Include="MousePositionInWorld.cs" /> <Compile Include="Utils\Enums.cs" />
<Compile Include="Object Classes\CollectedVehicle.cs" /> <Compile Include="Utils\Extensions.cs" />
<Compile Include="Object Classes\Barrier.cs" /> <Compile Include="Utils\MousePositionInWorld.cs" />
<Compile Include="Objects\CollectedVehicle.cs" />
<Compile Include="Objects\Barrier.cs" />
<Compile Include="Hints.cs" /> <Compile Include="Hints.cs" />
<Compile Include="Menus\BarrierMenu.cs" /> <Compile Include="Menus\BarrierMenu.cs" />
<Compile Include="Menus\EditPathMenu.cs" /> <Compile Include="Menus\EditPathMenu.cs" />
<Compile Include="Menus\EditWaypointMenu.cs" /> <Compile Include="Menus\EditWaypointMenu.cs" />
<Compile Include="EntryPoint.cs" /> <Compile Include="EntryPoint.cs" />
<Compile Include="GetUserInput.cs" /> <Compile Include="Utils\GetUserInput.cs" />
<Compile Include="Menus\MainMenu.cs" /> <Compile Include="Menus\MainMenu.cs" />
<Compile Include="Menus\MenuManager.cs" /> <Compile Include="Menus\MenuManager.cs" />
<Compile Include="Object Classes\Path.cs" /> <Compile Include="Objects\Path.cs" />
<Compile Include="Menus\PathCreationMenu.cs" /> <Compile Include="Menus\PathCreationMenu.cs" />
<Compile Include="Utils\PathXMLManager.cs" />
<Compile Include="Utils\PNWUserInput.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Menus\PathMainMenu.cs" /> <Compile Include="Menus\PathMainMenu.cs" />
<Compile Include="Menus\SettingsMenu.cs" /> <Compile Include="Menus\SettingsMenu.cs" />
<Compile Include="RNUIMouseInputHandler.cs" /> <Compile Include="Utils\RNUIMouseInputHandler.cs" />
<Compile Include="Settings.cs" /> <Compile Include="Settings.cs" />
<Compile Include="Object Classes\Waypoint.cs" /> <Compile Include="Objects\Waypoint.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="AfterCompile">
<Exec Command="if &quot;$(ConfigurationName)&quot; == &quot;Release&quot; (&quot;$(ProjectDir)_ConfuserEx\Confuser.CLI.exe&quot; &quot;$(ProjectDir)_ConfuserEx\c.crproj&quot;)&#xD;&#xA;" />
</Target>
</Project> </Project>

View file

@ -0,0 +1,18 @@
<Project ProjectFileVersion="4" UseRelativePaths="True" CheckVersionsWhileResolvingAssemblies="True" DisabledFromMSBuild="False" ID="{b35d9f3f-3f2b-4c66-9dbe-4b237999d6ba}">
<SearchDirectories />
<OutputSettings OutputPath=".\CryptoObfuscator_Output" MainAssemblyPath="" RunAssemblyPath="" SNPath="" SignToolPath="" LicensingDLLPath="" OverwriteInputFiles="False" BuildID="" MapFilesLocation="" FullParamNamesInMappingFile="False">
<AdditionalAssemblies />
</OutputSettings>
<ExceptionReporting ExceptionReportingServiceURL="" TryToContinueOnException="True" LocalReportPath=".\SceneManager_ExceptionReports" ApplicationName="" CompanyName="" ShowUI="True" EnableSaveToFileButton="True" EnableSendReportButton="True" DeleteDownloadedReportsFromServer="True" />
<ObfuscationSettings RenamingScheme="0" UseOverloadedFieldNames="False" UseOverloadedMethodNames="False" HonorObfuscationAttributes="True" ExcludeSerializedTypes="True" ProcessInlineStrings="True" ForceXAMLProcessingModeExclude="False" ForceRenameParams="False" SymbolPrefix="" SymbolSuffix="" FakeFields="" FakeTypes="" FakeMethods="" EncryptionActive="True" CompressionActive="True" RemoveAccessedThroughPropertyAttribute="False" UseSaltForCryptographicRenaming="False" />
<ObfuscationRules />
<InclusionExclusionRules />
<Assembly Load="true" Path="D:\Program Files\Rockstar Games\Grand Theft Auto V\plugins\SceneManager.dll" XapEntryName="" KeyFilePath="" KeyFileContainsPublicKeyOnly="False" CertFilePath="" TimeStampURL="" Rfc3161TimestampURL="False" SHA256SigningAlgorithm="False" Embed="True" AddExceptionReporting="False" PfxPassword="" PfxPasswordCert="" IsWinRTAssembly="False">
<ObfuscationSettings EncryptStrings="True" EncryptMethods="False" EncryptConstants="False" SuppressReflector="False" ReduceMetaData="False" ObfuscationDisposition="1" FlowObfuscation="2" CodeMasking="0" SuppressILDASM="True" SuppressReflection="False" CombineResources="True" EncryptResources="True" CompressResources="True" MarkAsSealed="False" EnableTamperDetection="True" EnableAntiDebugging="False" SymbolRenaming="True" HideExternalCalls="False" HideInternalCalls="False" GeneratePdbFile="True" ObfuscatePdbFileNames="True" IncludeLocalVariablesInPdbFile="False" Encrypt="False" Compress="False" MSBuild="False" ObfuscatedNamespace="A" RetainNamespace="False" ModuleInitializationMethod="" LicensingMerge="False" RemoveConstants="False" ProcessSatelliteAssemblies="True">
<Watermarks Watermark0="" Watermark1="" Watermark2="" Watermark3="" Watermark4="" Watermark5="" Watermark6="" Watermark7="" Watermark8="" Watermark9="" />
</ObfuscationSettings>
</Assembly>
<WarningSuppressions />
<Warnings SaveWarningsToFile="" FailOnUnsuppressedWarning="False" SaveSuppressedWarnings="True" SaveUnsuppressedWarnings="True" />
<Filters />
</Project>

View file

@ -1,45 +1,11 @@
using Rage; using Rage;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows.Forms; using System.Windows.Forms;
using SceneManager.Utils;
using System.IO;
namespace SceneManager 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 class Settings
{ {
internal static readonly InitializationFile ini = new InitializationFile("Plugins/SceneManager.ini"); internal static readonly InitializationFile ini = new InitializationFile("Plugins/SceneManager.ini");
@ -57,6 +23,7 @@ namespace SceneManager
internal static SpeedUnits SpeedUnit = SpeedUnits.MPH; internal static SpeedUnits SpeedUnit = SpeedUnits.MPH;
internal static float BarrierPlacementDistance = 30f; internal static float BarrierPlacementDistance = 30f;
internal static bool EnableAdvancedBarricadeOptions = false; internal static bool EnableAdvancedBarricadeOptions = false;
internal static bool EnableBarrierLightsDefaultOn = false;
// Default Waypoint Settings // Default Waypoint Settings
internal static int CollectorRadius = 1; internal static int CollectorRadius = 1;
@ -66,8 +33,9 @@ namespace SceneManager
internal static int WaypointSpeed = 5; internal static int WaypointSpeed = 5;
// Barriers // Barriers
internal static List<string> barrierKeys = new List<string>(); internal static Dictionary<string, Model> barriers = new Dictionary<string, Model>();
internal static List<string> barrierValues = new List<string>(); //internal static List<string> barrierKeys = new List<string>();
//internal static List<Model> barrierValues = new List<Model>();
internal static void LoadSettings() internal static void LoadSettings()
{ {
@ -87,7 +55,8 @@ namespace SceneManager
SpeedUnit = ini.ReadEnum("Plugin Settings", "SpeedUnits", SpeedUnits.MPH); SpeedUnit = ini.ReadEnum("Plugin Settings", "SpeedUnits", SpeedUnits.MPH);
BarrierPlacementDistance = ini.ReadInt32("Plugin Settings", "BarrierPlacementDistance", 30); BarrierPlacementDistance = ini.ReadInt32("Plugin Settings", "BarrierPlacementDistance", 30);
EnableAdvancedBarricadeOptions = ini.ReadBoolean("Plugin Settings", "EnableAdvancedBarricadeOptions", false); EnableAdvancedBarricadeOptions = ini.ReadBoolean("Plugin Settings", "EnableAdvancedBarricadeOptions", false);
EnableBarrierLightsDefaultOn = ini.ReadBoolean("Plugin Settings", "EnableBarrierLightsDefaultOn", false);
// Default Waypoint Settings // Default Waypoint Settings
CollectorRadius = ini.ReadInt32("Default Waypoint Settings", "CollectorRadius", 1); CollectorRadius = ini.ReadInt32("Default Waypoint Settings", "CollectorRadius", 1);
SpeedZoneRadius = ini.ReadInt32("Default Waypoint Settings", "SpeedZoneRadius", 5); SpeedZoneRadius = ini.ReadInt32("Default Waypoint Settings", "SpeedZoneRadius", 5);
@ -97,20 +66,23 @@ namespace SceneManager
CheckForValidWaypointSettings(); CheckForValidWaypointSettings();
// Barriers // Barriers
foreach(string key in ini.GetKeyNames("Barriers")) foreach(string displayName in ini.GetKeyNames("Barriers"))
{ {
barrierKeys.Add(key.Trim()); var model = new Model(ini.ReadString("Barriers", displayName.Trim()));
var m = new Model(ini.ReadString("Barriers", key)); if (model.IsValid)
if (m.IsValid)
{ {
barrierValues.Add(m.Name); barriers.Add(displayName, model);
//barrierKeys.Add(key.Trim());
//barrierValues.Add(model);
} }
else else
{ {
Game.LogTrivial($"{m.Name} is not valid."); Game.LogTrivial($"{model.Name} is not valid.");
} }
} }
//ImportPaths();
void CheckForValidWaypointSettings() void CheckForValidWaypointSettings()
{ {
if(CollectorRadius > 50 || CollectorRadius < 1) if(CollectorRadius > 50 || CollectorRadius < 1)
@ -135,6 +107,33 @@ namespace SceneManager
Game.LogTrivial($"Invalid value for WaypointSpeed in user settings, resetting to default."); 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) internal static void UpdateSettings(bool threeDWaypointsEnabled, bool mapBlipsEnabled, bool hintsEnabled, SpeedUnits unit)

View file

@ -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<PedTask>();
foreach (PedTask task in (PedTask[])Enum.GetValues(typeof(PedTask)))
{
if(Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, (int)task))
{
Game.LogTrivial($"Ped [{ped.Handle}] active task: {task} ({(int)task})");
}
}
}
}
}

480
SceneManager/Utils/Enums.cs Normal file
View file

@ -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
}
}

View file

@ -0,0 +1,100 @@
using Rage;
namespace SceneManager.Utils
{
internal enum PedType
{
/// <summary>Any ped
/// </summary>
Any = 0,
/// <summary>Cop peds
/// </summary>
Cop = 1,
//Firefigher = 2,
//EMS = 3
}
/// <summary>A collection of potentially useful code snippets for GTA/LSPDFR development.
/// </summary>
internal static class Extensions
{
/// <summary>Determines if a ped can be considered ambient. Checks any type of ped by default.
/// </summary>
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<bool>(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<bool>(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<bool>(ped, 150);
var taskCarDriveWander = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 151);
// On-foot ambient tasks
var taskPolice = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 58); // From ambient cop (non-freemode) walking around
var taskWanderingScenario = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 100); // From ambient cop walking around
var taskUseScenario = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 118); // From ambient cop standing still
var taskScriptedAnimation = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(ped, 134); // From UB ped waiting for interaction
// In-vehicle controlled tasks
var taskControlVehicle = Rage.Native.NativeFunction.Natives.GET_IS_TASK_ACTIVE<bool>(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<bool>(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;
}
}
}

View file

@ -1,6 +1,6 @@
using Rage; using Rage;
namespace SceneManager namespace SceneManager.Utils
{ {
class GetUserInput class GetUserInput
{ {
@ -8,8 +8,16 @@ namespace SceneManager
{ {
while (true) while (true)
{ {
GetKeyboardInput(); bool isTextEntryOpen = (Rage.Native.NativeFunction.Natives.UPDATE_ONSCREEN_KEYBOARD<int>() == 0);
GetControllerInput(); if (!isTextEntryOpen)
{
GetKeyboardInput();
GetControllerInput();
}
else
{
Game.LogTrivial($"A text menu is open.");
}
#if DEBUG #if DEBUG
if (MenuManager.menuPool.IsAnyMenuOpen()) if (MenuManager.menuPool.IsAnyMenuOpen())

View file

@ -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>();
float heading = Rage.Native.NativeFunction.Natives.GET_GAMEPLAY_CAM_RELATIVE_HEADING<float>();
camPosition = Rage.Native.NativeFunction.Natives.GET_GAMEPLAY_CAM_COORD<Vector3>();
return (Game.LocalPlayer.Character.Rotation + new Rotator(pitch, 0, heading)).ToVector().ToNormalized();
}
}
return TracePlayerView(maxDistance, TraceFlags.IntersectWorld).HitPosition;
}
}
}

View file

@ -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<int>() == 0)
{
GameFiber.Yield();
}
NativeFunction.Natives.ENABLE_ALL_CONTROL_ACTIONS(2);
Game.DisplaySubtitle("", 5);
Game.HideHelp();
return NativeFunction.Natives.GET_ONSCREEN_KEYBOARD_RESULT<string>();
}
}
}

View file

@ -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<Type, XmlSerializer> _serializerCache = new Dictionary<Type, XmlSerializer>();
private static XmlSerializer _getOrCreateSerializer<T>(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<T> LoadAllXML<T>(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<T> result = new List<T>();
Array.ForEach(files, f => result.AddRange(LoadFromXML<T>(f)));
return result;
}
public static void SaveToXML<T>(List<T> list, string filePath)
{
SaveItemToXML(list, filePath);
}
public static void SaveItemToXML<T>(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<T>(overrides).Serialize(writer, item, ns);
}
}
public static void SaveItemToXML<T>(T item, string path)
{
SaveItemToXML<T>(item, path, null);
}
public static T LoadItemFromXML<T>(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<T>(overrides).Deserialize(reader);
}
}
public static T LoadItemFromXML<T>(string filePath)
{
return (T)LoadItemFromXML<T>(filePath, null);
}
public static void ModifyItemInXML<T>(string filePath, Action<T> modification)
{
T item = LoadItemFromXML<T>(filePath);
modification(item);
SaveItemToXML<T>(item, filePath);
}
public static T GetSelectedListElementFromXml<T>(string file, Func<List<T>, T> selector)
{
List<T> deserialized = LoadItemFromXML<List<T>>(file);
return selector(deserialized);
}
public static List<T> LoadFromXML<T>(string filePath)
{
return LoadItemFromXML<List<T>>(filePath);
}
public static void AppendToXML<T>(T objectToAdd, string path)
{
ModifyItemInXML<List<T>>(path, t => t.Add(objectToAdd));
}
///// <summary>
///// Creates folder in case it doesn't exist and checks file existance.
///// </summary>
///// <param name="path"></param>
///// <returns>false when a file does not exist.</returns>
//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);
//}
}
}

View file

@ -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<UIMenuScrollerItem> 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<int>() != 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<UIMenuScrollerItem> 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<int>)scrollerItems.Where(x => x.Text == "Collection Radius").FirstOrDefault();
var speedZoneRadius = (UIMenuNumericScrollerItem<int>)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);
}
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,27 @@
<project outputDir="C:\Users\Rich\Desktop\Mod Stuff\Mod Development\SceneManager\SceneManager\obj\Release" baseDir="C:\Users\Rich\Desktop\Mod Stuff\Mod Development\SceneManager\SceneManager\obj\Release" xmlns="http://confuser.codeplex.com">
<rule pattern="true" />
<module path="SceneManager.dll">
<rule pattern="true">
<protection id="anti ildasm" />
<protection id="anti tamper" />
<protection id="constants" />
<protection id="ctrl flow" />
<protection id="anti dump" />
<protection id="anti debug" />
<protection id="invalid metadata" />
<protection id="ref proxy" />
<protection id="resources" />
<protection id = "rename" >
<argument name = "mode" value = "decodable" />
<argument name = "renPublic" value = "false" />
<argument name = "renEnum" value = "false" />
<argument name = "renameArgs" value = "false" />
</protection >
</rule>
</module>
<probePath>..\..\..\packages\InputManager.1.0.0\lib</probePath>
<probePath>D:\Program Files\Rockstar Games\Grand Theft Auto V</probePath>
<probePath>C:\Users\Rich\Desktop\Mod Stuff\Mod Development\Modding Resources\References</probePath>
<probePath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8</probePath>
<probePath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\Facades</probePath>
</project>

Binary file not shown.

23
SceneManager/app.config Normal file
View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Dataflow" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Resources.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="InputManager" version="1.0.0" targetFramework="net48" />
</packages>

View file

@ -0,0 +1,3 @@
<project outputDir="C:\Users\Rich\Desktop\Mod Stuff\Mod Development\SceneManager\SceneManager\Confused" baseDir="C:\Users\Rich\Desktop\Mod Stuff\Mod Development\SceneManager\SceneManager" xmlns="http://confuser.codeplex.com">
<rule pattern="true" preset="maximum" inherit="false" />
</project>