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

Big refactor

This commit is contained in:
Rich Dunne 2021-01-10 08:35:21 -07:00
parent 6769ca815e
commit f1554a4aea
8 changed files with 557 additions and 1365 deletions

View file

@ -7,428 +7,158 @@ using RAGENativeUI.Elements;
using SceneManager.Objects;
using SceneManager.Utils;
namespace SceneManager
namespace SceneManager.Menus
{
class BarrierMenu
{
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 List<Barrier> barriers = new List<Barrier>();
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 List<TrafficLight> TrafficLightList { get; } = new List<TrafficLight>() { TrafficLight.Green, TrafficLight.Red, TrafficLight.Yellow, TrafficLight.None };
internal static UIMenu Menu { get; } = new UIMenu("Scene Manager", "~o~Barrier Management");
internal static UIMenuListScrollerItem<string> BarrierList { get; } = new UIMenuListScrollerItem<string>("Spawn Barrier", "", Settings.Barriers.Keys); // Settings.barrierKeys
internal static UIMenuNumericScrollerItem<int> RotateBarrier { get; } = 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 immobile = new UIMenuCheckboxItem("Immobile", false);
private static UIMenuNumericScrollerItem<int> barrierTexture = new UIMenuNumericScrollerItem<int>("Change Texture", "", 0, 15, 1);
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<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");
internal static Object shadowBarrier;
internal static UIMenuCheckboxItem Invincible { get; } = new UIMenuCheckboxItem("Indestructible", false);
internal static UIMenuCheckboxItem Immobile { get; } = new UIMenuCheckboxItem("Immobile", false);
internal static UIMenuNumericScrollerItem<int> BarrierTexture { get; } = new UIMenuNumericScrollerItem<int>("Change Texture", "", 0, 15, 1);
internal static UIMenuCheckboxItem SetBarrierLights { get; } = new UIMenuCheckboxItem("Enable Barrier Lights", Settings.EnableBarrierLightsDefaultOn);
internal static UIMenuListScrollerItem<TrafficLight> SetBarrierTrafficLight { get; } = new UIMenuListScrollerItem<TrafficLight>("Set Barrier Traffic Light", "", TrafficLightList);
internal static UIMenuListScrollerItem<string> RemoveBarrierOptions { get; } = new UIMenuListScrollerItem<string>("Remove Barrier", "", new[] { "Last Barrier", "Nearest Barrier", "All Barriers" });
internal static UIMenuItem ResetBarriers { get; } = new UIMenuItem("Reset Barriers", "Reset all spawned barriers to their original position and rotation");
internal static void InstantiateMenu()
internal static void Initialize()
{
barrierMenu.ParentMenu = MainMenu.mainMenu;
MenuManager.menuPool.Add(barrierMenu);
Menu.ParentMenu = MainMenu.Menu;
MenuManager.MenuPool.Add(Menu);
barrierMenu.OnItemSelect += BarrierMenu_OnItemSelected;
barrierMenu.OnScrollerChange += BarrierMenu_OnScrollerChanged;
barrierMenu.OnCheckboxChange += BarrierMenu_OnCheckboxChanged;
barrierMenu.OnMenuOpen += BarrierMenu_OnMenuOpen;
Menu.OnItemSelect += BarrierMenu_OnItemSelected;
Menu.OnScrollerChange += BarrierMenu_OnScrollerChanged;
Menu.OnCheckboxChange += BarrierMenu_OnCheckboxChanged;
Menu.OnMenuOpen += BarrierMenu_OnMenuOpen;
}
internal static void BuildBarrierMenu()
{
barrierMenu.AddItem(barrierList);
barrierList.ForeColor = Color.Gold;
Menu.AddItem(BarrierList);
BarrierList.ForeColor = Color.Gold;
barrierMenu.AddItem(rotateBarrier);
barrierMenu.AddItem(invincible);
barrierMenu.AddItem(immobile);
Menu.AddItem(RotateBarrier);
Menu.AddItem(Invincible);
Menu.AddItem(Immobile);
if (Settings.EnableAdvancedBarricadeOptions)
{
barrierMenu.AddItem(barrierTexture);
barrierTexture.Index = 0;
Menu.AddItem(BarrierTexture);
BarrierTexture.Index = 0;
barrierMenu.AddItem(setBarrierLights);
Menu.AddItem(SetBarrierLights);
//barrierMenu.AddItem(setBarrierTrafficLight);
//setBarrierTrafficLight.Index = 3;
}
barrierMenu.AddItem(removeBarrierOptions);
removeBarrierOptions.ForeColor = Color.Gold;
removeBarrierOptions.Enabled = false;
Menu.AddItem(RemoveBarrierOptions);
RemoveBarrierOptions.ForeColor = Color.Gold;
RemoveBarrierOptions.Enabled = false;
barrierMenu.AddItem(resetBarriers);
resetBarriers.ForeColor = Color.Gold;
resetBarriers.Enabled = false;
Menu.AddItem(ResetBarriers);
ResetBarriers.ForeColor = Color.Gold;
ResetBarriers.Enabled = false;
}
internal static void CreateShadowBarrier()
internal static void ScrollBarrierList()
{
if (shadowBarrier)
if (BarrierManager.PlaceholderBarrier)
{
shadowBarrier.Delete();
BarrierManager.PlaceholderBarrier.Delete();
}
BarrierTexture.Index = 0;
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 (BarrierList.SelectedItem == "Flare")
{
barrierMenu.Close();
Game.DisplayNotification($"~o~Scene Manager ~r~[Error]\n~w~Something went wrong creating the shadow barrier. Please try again.");
return;
}
//Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index);
Rage.Native.NativeFunction.Natives.PLACE_OBJECT_ON_GROUND_PROPERLY(shadowBarrier);
shadowBarrier.IsGravityDisabled = true;
shadowBarrier.IsCollisionEnabled = false;
shadowBarrier.Opacity = 0.7f;
// Start with lights off for Parks's objects
if (Settings.EnableAdvancedBarricadeOptions)
{
Rage.Native.NativeFunction.Natives.x971DA0055324D033(shadowBarrier, barrierTexture.Value);
SetBarrierLights();
}
}
private static void LoopToDisplayShadowBarrier()
{
while (barrierMenu.Visible)
{
if (barrierList.Selected || rotateBarrier.Selected || invincible.Selected || immobile.Selected || barrierTexture.Selected || setBarrierLights.Selected || setBarrierTrafficLight.Selected)
{
if (shadowBarrier)
{
UpdateShadowBarrierPosition();
}
else if(MousePositionInWorld.GetPositionForBarrier.DistanceTo2D(Game.LocalPlayer.Character.Position) <= Settings.BarrierPlacementDistance)
{
CreateShadowBarrier();
}
}
else
{
if (shadowBarrier)
{
shadowBarrier.Delete();
}
}
GameFiber.Yield();
}
if (shadowBarrier)
{
shadowBarrier.Delete();
}
void UpdateShadowBarrierPosition()
{
DisableBarrierMenuOptionsIfShadowConeTooFar();
if (shadowBarrier)
{
// Delete and re-create for testing purposes.. Parks' stop light prop
//shadowBarrier.Delete();
//CreateShadowBarrier();
shadowBarrier.Heading = rotateBarrier.Value;
shadowBarrier.Position = MousePositionInWorld.GetPositionForBarrier;
Rage.Native.NativeFunction.Natives.PLACE_OBJECT_ON_GROUND_PROPERLY(shadowBarrier);
//Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index);
}
void DisableBarrierMenuOptionsIfShadowConeTooFar()
{
if (!shadowBarrier && MousePositionInWorld.GetPositionForBarrier.DistanceTo2D(Game.LocalPlayer.Character.Position) <= Settings.BarrierPlacementDistance)
{
CreateShadowBarrier();
}
else if (shadowBarrier && shadowBarrier.Position.DistanceTo2D(Game.LocalPlayer.Character.Position) > Settings.BarrierPlacementDistance)
{
barrierList.Enabled = false;
rotateBarrier.Enabled = false;
shadowBarrier.Delete();
}
else if (shadowBarrier && shadowBarrier.Position.DistanceTo2D(Game.LocalPlayer.Character.Position) <= Settings.BarrierPlacementDistance && barrierList.SelectedItem == "Flare")
{
barrierList.Enabled = true;
rotateBarrier.Enabled = false;
}
else
{
barrierList.Enabled = true;
rotateBarrier.Enabled = true;
}
}
}
}
private static void SpawnBarrier()
{
GameFiber.StartNew(() =>
{
if (barrierList.SelectedItem == "Flare")
{
SpawnFlare();
}
else
{
var barrier = new Object(shadowBarrier.Model, shadowBarrier.Position, rotateBarrier.Value);
barrier.SetPositionWithSnap(shadowBarrier.Position);
Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(barrier, true);
if (invincible.Checked)
{
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
{
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;
}
}, "Scene Manager Spawn Barrier Fiber");
void SpawnFlare()
{
var flare = new Weapon("weapon_flare", shadowBarrier.Position, 1);
Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(flare, true);
GameFiber.Sleep(1);
GameFiber.StartNew(() =>
{
while (flare && flare.HeightAboveGround > 0.05f)
{
GameFiber.Yield();
}
GameFiber.Sleep(1000);
if (flare)
{
flare.IsPositionFrozen = true;
}
});
barriers.Add(new Barrier(flare, flare.Position, flare.Heading, invincible.Checked, immobile.Checked));
removeBarrierOptions.Enabled = true;
}
}
internal static void RotateBarrier()
{
shadowBarrier.Heading = rotateBarrier.Value;
shadowBarrier.Position = MousePositionInWorld.GetPositionForBarrier;
Rage.Native.NativeFunction.Natives.PLACE_OBJECT_ON_GROUND_PROPERLY(shadowBarrier);
}
private static void RemoveBarrier()
{
switch (removeBarrierOptions.Index)
{
case 0:
barriers[barriers.Count - 1].Object.Delete();
barriers.RemoveAt(barriers.Count - 1);
break;
case 1:
var nearestBarrier = barriers.OrderBy(b => b.Object.DistanceTo2D(Game.LocalPlayer.Character)).FirstOrDefault();
if (nearestBarrier != null)
{
nearestBarrier.Object.Delete();
barriers.Remove(nearestBarrier);
}
break;
case 2:
foreach (Barrier b in barriers.Where(b => b.Object))
{
b.Object.Delete();
}
if (barriers.Count > 0)
{
barriers.Clear();
}
break;
}
removeBarrierOptions.Enabled = barriers.Count == 0 ? false : true;
resetBarriers.Enabled = barriers.Count == 0 ? false : true;
}
private static void ResetBarriers()
{
GameFiber.StartNew(() =>
{
var currentBarriers = barriers.Where(b => b.Model.Name != "0xa2c44e80").ToList(); // 0xa2c44e80 is the flare weapon hash
foreach (Barrier barrier in currentBarriers)
{
var newBarrier = new Object(barrier.Model, barrier.Position, barrier.Rotation);
newBarrier.SetPositionWithSnap(barrier.Position);
Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(newBarrier, true);
newBarrier.IsPositionFrozen = barrier.Immobile;
if (barrier.Invincible)
{
Rage.Native.NativeFunction.Natives.SET_DISABLE_FRAG_DAMAGE(newBarrier, true);
if (newBarrier.Model.Name != "prop_barrier_wat_03a")
{
Rage.Native.NativeFunction.Natives.SET_DISABLE_BREAKING(newBarrier, true);
}
}
//Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(newBarrier, setBarrierTrafficLight.Index);
newBarrier.IsPositionFrozen = true;
GameFiber.Sleep(50);
if (newBarrier && !barrier.Immobile)
{
newBarrier.IsPositionFrozen = false;
}
barriers.Add(new Barrier(newBarrier, newBarrier.Position, newBarrier.Heading, barrier.Invincible, barrier.Immobile));
if (barrier.Object)
{
barrier.Object.Delete();
}
barriers.Remove(barrier);
}
currentBarriers.Clear();
});
}
private static void SetBarrierLights()
{
if (setBarrierLights.Checked)
{
Rage.Native.NativeFunction.Natives.SET_ENTITY_LIGHTS(shadowBarrier, false);
RotateBarrier.Enabled = false;
}
else
{
Rage.Native.NativeFunction.Natives.SET_ENTITY_LIGHTS(shadowBarrier, true);
RotateBarrier.Enabled = true;
}
//Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index);
Menu.Width = SetMenuWidth();
}
private static void BarrierMenu_OnCheckboxChanged(UIMenu sender, UIMenuCheckboxItem checkbox, bool @checked)
{
if(checkbox == setBarrierLights)
if(checkbox == SetBarrierLights)
{
SetBarrierLights();
//SetBarrierLights();
BarrierManager.SetBarrierLights();
}
}
private static void BarrierMenu_OnScrollerChanged(UIMenu sender, UIMenuScrollerItem scrollerItem, int oldIndex, int newIndex)
{
if (scrollerItem == barrierList)
if (scrollerItem == BarrierList)
{
if (shadowBarrier)
{
shadowBarrier.Delete();
}
barrierTexture.Index = 0;
if(barrierList.SelectedItem == "Flare")
{
rotateBarrier.Enabled = false;
}
else
{
rotateBarrier.Enabled = true;
}
barrierMenu.Width = SetMenuWidth();
ScrollBarrierList();
}
if (scrollerItem == barrierTexture)
if (scrollerItem == BarrierTexture)
{
Rage.Native.NativeFunction.Natives.x971DA0055324D033(shadowBarrier, barrierTexture.Value);
Rage.Native.NativeFunction.Natives.x971DA0055324D033(BarrierManager.PlaceholderBarrier, BarrierTexture.Value);
}
if (scrollerItem == setBarrierTrafficLight)
if (scrollerItem == SetBarrierTrafficLight)
{
Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index);
Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(BarrierManager.PlaceholderBarrier, SetBarrierTrafficLight.Index);
}
if (scrollerItem == rotateBarrier)
if (scrollerItem == RotateBarrier)
{
RotateBarrier();
//RotateBarrier();
BarrierManager.RotateBarrier();
}
}
private static void BarrierMenu_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
{
if (selectedItem == barrierList)
if (selectedItem == BarrierList)
{
SpawnBarrier();
//SpawnBarrier();
BarrierManager.SpawnBarrier();
}
if (selectedItem == removeBarrierOptions)
if (selectedItem == RemoveBarrierOptions)
{
RemoveBarrier();
//RemoveBarrier();
BarrierManager.RemoveBarrier(RemoveBarrierOptions.Index);
}
if (selectedItem == resetBarriers)
if (selectedItem == ResetBarriers)
{
ResetBarriers();
//ResetBarriers();
BarrierManager.ResetBarriers();
}
}
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 };
Hints.Display($"~o~Scene Manager ~y~[Hint]\n~w~The shadow barrier will disappear if you aim too far away.");
CreateShadowBarrier();
//CreatePlaceholderBarrier();
BarrierManager.CreatePlaceholderBarrier();
GameFiber ShadowConeLoopFiber = new GameFiber(() => LoopToDisplayShadowBarrier());
ShadowConeLoopFiber.Start();
//GameFiber PlaceholderBarrierRenderFiber = new GameFiber(() => LoopToDisplayShadowBarrier());
GameFiber PlaceholderBarrierRenderFiber = new GameFiber(() => BarrierManager.LoopToRenderPlaceholderBarrier(), "Render Placeholder Barrier Loop Fiber");
PlaceholderBarrierRenderFiber.Start();
RNUIMouseInputHandler.Initialize(menu, scrollerItems);
GameFiber.StartNew(() => UserInput.InitializeMenuMouseControl(menu, scrollerItems), "RNUI Mouse Input Fiber");
}
internal static float SetMenuWidth()
private static float SetMenuWidth()
{
float defaultWidth = UIMenu.DefaultWidth;
barrierList.TextStyle.Apply();
BarrierList.TextStyle.Apply();
Rage.Native.NativeFunction.Natives.x54CE8AC98E120CAB("STRING"); // _BEGIN_TEXT_COMMAND_GET_WIDTH
Rage.Native.NativeFunction.Natives.ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(barrierList.SelectedItem);
Rage.Native.NativeFunction.Natives.ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(BarrierList.SelectedItem);
float textWidth = Rage.Native.NativeFunction.Natives.x85F061DA64ED2F67<float>(true); // _END_TEXT_COMMAND_GET_WIDTH
float padding = 0.00390625f * 2; // typical padding used in RNUI
@ -442,5 +172,17 @@ namespace SceneManager
return selectedItemWidth * 1.6f;
}
}
internal static void Cleanup()
{
foreach (Barrier barrier in BarrierManager.Barriers.Where(x => x.Object))
{
barrier.Object.Delete();
}
if (BarrierManager.PlaceholderBarrier)
{
BarrierManager.PlaceholderBarrier.Delete();
}
}
}
}

View file

@ -3,114 +3,89 @@ using System.Drawing;
using Rage;
using RAGENativeUI;
using RAGENativeUI.Elements;
using SceneManager.Menus;
using SceneManager.Utils;
namespace SceneManager
{
class EditPathMenu
internal class EditPathMenu
{
internal static UIMenu editPathMenu = new UIMenu("Scene Manager", "~o~Edit Path");
private static UIMenuItem editPathWaypoints, deletePath, exportPath;
internal static UIMenuCheckboxItem disablePath;
internal static UIMenu Menu { get; } = new UIMenu("Scene Manager", "~o~Edit Path");
internal static UIMenuCheckboxItem DisablePath { get; } = new UIMenuCheckboxItem("Disable Path", false);
private static UIMenuItem EditWaypoints { get; } = new UIMenuItem("Edit Waypoints");
private static UIMenuItem deletePath { get; } = new UIMenuItem("Delete Path");
private static UIMenuItem ExportPath { get; } = new UIMenuItem("Export Path");
internal static void InstantiateMenu()
internal static void Initialize()
{
editPathMenu.ParentMenu = PathMainMenu.pathMainMenu;
MenuManager.menuPool.Add(editPathMenu);
editPathMenu.OnItemSelect += EditPath_OnItemSelected;
editPathMenu.OnCheckboxChange += EditPath_OnCheckboxChange;
editPathMenu.OnMenuOpen += EditPath_OnMenuOpen;
Menu.ParentMenu = PathMainMenu.Menu;
MenuManager.MenuPool.Add(Menu);
Menu.OnItemSelect += EditPath_OnItemSelected;
Menu.OnCheckboxChange += EditPath_OnCheckboxChange;
Menu.OnMenuOpen += EditPath_OnMenuOpen;
}
internal static void BuildEditPathMenu()
{
editPathMenu.AddItem(disablePath = new UIMenuCheckboxItem("Disable Path", false));
editPathMenu.AddItem(editPathWaypoints = new UIMenuItem("Edit Waypoints"));
editPathWaypoints.ForeColor = Color.Gold;
editPathMenu.AddItem(deletePath = new UIMenuItem("Delete Path"));
Menu.AddItem(DisablePath);
Menu.AddItem(EditWaypoints);
EditWaypoints.ForeColor = Color.Gold;
Menu.AddItem(deletePath);
deletePath.ForeColor = Color.Gold;
//editPathMenu.AddItem(exportPath = new UIMenuItem("Export Path"));
//exportPath.ForeColor = Color.Gold;
editPathMenu.RefreshIndex();
}
private static void EditPathWaypoints()
{
if (!SettingsMenu.threeDWaypoints.Checked)
{
Hints.Display($"~o~Scene Manager ~y~[Hint]\n~w~You have 3D waypoints disabled in your settings. It's recommended to enable 3D waypoints while working with waypoints.");
}
EditWaypointMenu.BuildEditWaypointMenu();
}
private static void DeletePath()
{
var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index];
PathMainMenu.DeletePath(currentPath, Delete.Single);
}
private static void DisablePath()
{
var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index];
if (disablePath.Checked)
{
currentPath.DisablePath();
Game.LogTrivial($"Path {currentPath.Number} disabled.");
}
else
{
currentPath.EnablePath();
Game.LogTrivial($"Path {currentPath.Number} enabled.");
}
}
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);
Menu.AddItem(ExportPath);
ExportPath.ForeColor = Color.Gold;
Menu.RefreshIndex();
}
private static void EditPath_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
{
if (selectedItem == editPathWaypoints)
if (selectedItem == EditWaypoints)
{
EditPathWaypoints();
if (!SettingsMenu.ThreeDWaypoints.Checked)
{
Hints.Display($"~o~Scene Manager ~y~[Hint]\n~w~You have 3D waypoints disabled in your settings. It's recommended to enable 3D waypoints while working with waypoints.");
}
EditWaypointMenu.BuildEditWaypointMenu();
}
if (selectedItem == deletePath)
{
DeletePath();
var currentPath = PathManager.Paths[PathMainMenu.EditPath.Index];
currentPath.Delete();
PathManager.Paths.Remove(currentPath);
PathMainMenu.BuildPathMenu();
PathMainMenu.Menu.Visible = true;
}
if(selectedItem == exportPath)
if(selectedItem == ExportPath)
{
ExportPath();
PathManager.ExportPath();
}
}
private static void EditPath_OnCheckboxChange(UIMenu sender, UIMenuCheckboxItem checkboxItem, bool @checked)
{
if (checkboxItem == disablePath)
if (checkboxItem == DisablePath)
{
DisablePath();
var currentPath = PathManager.Paths[PathMainMenu.EditPath.Index];
if (DisablePath.Checked)
{
currentPath.DisablePath();
Game.LogTrivial($"Path {currentPath.Number} disabled.");
}
else
{
currentPath.EnablePath();
Game.LogTrivial($"Path {currentPath.Number} enabled.");
}
}
}
private static void EditPath_OnMenuOpen(UIMenu menu)
{
var scrollerItems = new List<UIMenuScrollerItem> { };
RNUIMouseInputHandler.Initialize(menu, scrollerItems);
GameFiber.StartNew(() => UserInput.InitializeMenuMouseControl(menu, scrollerItems), "RNUI Mouse Input Fiber");
}
}
}

View file

@ -7,308 +7,194 @@ using RAGENativeUI.Elements;
using SceneManager.Objects;
using SceneManager.Utils;
namespace SceneManager
namespace SceneManager.Menus
{
class EditWaypointMenu
{
internal static UIMenu editWaypointMenu = new UIMenu("Scene Manager", "~o~Edit Waypoint");
internal static UIMenuItem updateWaypoint = new UIMenuItem("Update Waypoint");
internal static UIMenuItem removeWaypoint = new UIMenuItem("Remove Waypoint");
internal static UIMenuItem addAsNewWaypoint = new UIMenuItem("Add as New Waypoint", "Adds a new waypoint to the end of the path with these settings");
internal static UIMenuNumericScrollerItem<int> editWaypoint;
private static UIMenuNumericScrollerItem<int> changeWaypointSpeed;
internal static UIMenuCheckboxItem stopWaypointType;
internal static UIMenuCheckboxItem directWaypointBehavior = new UIMenuCheckboxItem("Drive directly to waypoint?", false, "If checked, vehicles will ignore traffic rules and drive directly to this waypoint.");
internal static UIMenuCheckboxItem collectorWaypoint;
internal static UIMenuNumericScrollerItem<int> changeCollectorRadius = new UIMenuNumericScrollerItem<int>("Collection Radius", "The distance from this waypoint (in meters) vehicles will be collected", 1, 50, 1);
internal static UIMenuNumericScrollerItem<int> changeSpeedZoneRadius = new UIMenuNumericScrollerItem<int>("Speed Zone Radius", "The distance from this collector waypoint (in meters) non-collected vehicles will drive at this waypoint's speed", 5, 200, 5);
internal static UIMenuCheckboxItem updateWaypointPosition = new UIMenuCheckboxItem("Update Waypoint Position", false, "Updates the waypoint's position to the player's chosen position. You should turn this on if you're planning on adding this waypoint as a new waypoint.");
internal static UIMenu Menu = new UIMenu("Scene Manager", "~o~Edit Waypoint");
internal static UIMenuItem UpdateWaypoint { get; } = new UIMenuItem("Update Waypoint");
internal static UIMenuItem RemoveWaypoint { get; } = new UIMenuItem("Remove Waypoint");
internal static UIMenuItem AddNewWaypoint { get; } = new UIMenuItem("Add as New Waypoint", "Adds a new waypoint to the end of the path with these settings");
internal static UIMenuNumericScrollerItem<int> EditWaypoint { get; set; }
internal static UIMenuNumericScrollerItem<int> ChangeWaypointSpeed { get; private set; }
internal static UIMenuCheckboxItem StopWaypointType { get; private set; }
internal static UIMenuCheckboxItem DirectWaypointBehavior { get; } = new UIMenuCheckboxItem("Drive directly to waypoint?", false, "If checked, vehicles will ignore traffic rules and drive directly to this waypoint.");
internal static UIMenuCheckboxItem CollectorWaypoint { get; private set; }
internal static UIMenuNumericScrollerItem<int> ChangeCollectorRadius { get; } = new UIMenuNumericScrollerItem<int>("Collection Radius", "The distance from this waypoint (in meters) vehicles will be collected", 1, 50, 1);
internal static UIMenuNumericScrollerItem<int> ChangeSpeedZoneRadius { get; } = new UIMenuNumericScrollerItem<int>("Speed Zone Radius", "The distance from this collector waypoint (in meters) non-collected vehicles will drive at this waypoint's speed", 5, 200, 5);
internal static UIMenuCheckboxItem UpdateWaypointPosition { get; } = new UIMenuCheckboxItem("Update Waypoint Position", false, "Updates the waypoint's position to the player's chosen position. You should turn this on if you're planning on adding this waypoint as a new waypoint.");
internal static void InstantiateMenu()
internal static void Initialize()
{
editWaypointMenu.ParentMenu = EditPathMenu.editPathMenu;
MenuManager.menuPool.Add(editWaypointMenu);
Menu.ParentMenu = EditPathMenu.Menu;
MenuManager.MenuPool.Add(Menu);
editWaypointMenu.OnScrollerChange += EditWaypoint_OnScrollerChanged;
editWaypointMenu.OnCheckboxChange += EditWaypoint_OnCheckboxChanged;
editWaypointMenu.OnItemSelect += EditWaypoint_OnItemSelected;
editWaypointMenu.OnMenuOpen += EditWaypoint_OnMenuOpen;
Menu.OnScrollerChange += EditWaypoint_OnScrollerChanged;
Menu.OnCheckboxChange += EditWaypoint_OnCheckboxChanged;
Menu.OnItemSelect += EditWaypoint_OnItemSelected;
Menu.OnMenuOpen += EditWaypoint_OnMenuOpen;
}
internal static void BuildEditWaypointMenu()
{
var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Value-1];
Menu.MenuItems.Clear();
var currentPath = PathManager.Paths[PathMainMenu.EditPath.Value-1];
editWaypoint = new UIMenuNumericScrollerItem<int>("Edit Waypoint", "", currentPath.Waypoints.First().Number, currentPath.Waypoints.Last().Number, 1);
editWaypointMenu.Clear();
editWaypointMenu.AddItem(editWaypoint);
editWaypoint.Index = 0;
Menu.AddItem(EditWaypoint = new UIMenuNumericScrollerItem<int>("Edit Waypoint", "", currentPath.Waypoints.First().Number, currentPath.Waypoints.Last().Number, 1));
EditWaypoint.Index = 0;
var currentWaypoint = currentPath.Waypoints.Where(wp => wp.Number == editWaypoint.Value).FirstOrDefault();
if(currentWaypoint != null)
var currentWaypoint = currentPath.Waypoints.Where(wp => wp.Number == EditWaypoint.Value).FirstOrDefault();
if(currentWaypoint == null)
{
editWaypointMenu.AddItem(collectorWaypoint = new UIMenuCheckboxItem("Collector", currentWaypoint.IsCollector, "If this waypoint will collect vehicles to follow the path"));
editWaypointMenu.AddItem(changeCollectorRadius);
changeCollectorRadius.Value = currentWaypoint.CollectorRadius != 0
? (int)currentWaypoint.CollectorRadius
: changeCollectorRadius.Minimum;
editWaypointMenu.AddItem(changeSpeedZoneRadius);
changeSpeedZoneRadius.Value = currentWaypoint.CollectorRadius != 0
? (int)currentWaypoint.SpeedZoneRadius
: changeSpeedZoneRadius.Minimum;
changeCollectorRadius.Enabled = collectorWaypoint.Checked ? true : false;
changeSpeedZoneRadius.Enabled = collectorWaypoint.Checked ? true : false;
editWaypointMenu.AddItem(stopWaypointType = new UIMenuCheckboxItem("Is this a Stop waypoint?", currentWaypoint.IsStopWaypoint, "If checked, vehicles will drive to this waypoint, then stop."));
editWaypointMenu.AddItem(directWaypointBehavior);
if(currentWaypoint.DrivingFlagType == DrivingFlagType.Direct)
{
directWaypointBehavior.Checked = true;
}
editWaypointMenu.AddItem(changeWaypointSpeed = new UIMenuNumericScrollerItem<int>("Waypoint Speed", $"How fast the AI will drive to the waypoint in ~b~{SettingsMenu.speedUnits.SelectedItem}", 5, 100, 5));
changeWaypointSpeed.Value = (int)MathHelper.ConvertMetersPerSecondToMilesPerHour(currentWaypoint.Speed);
editWaypointMenu.AddItem(updateWaypointPosition);
editWaypointMenu.AddItem(updateWaypoint);
updateWaypoint.ForeColor = Color.Gold;
editWaypointMenu.AddItem(removeWaypoint);
removeWaypoint.ForeColor = Color.Gold;
editWaypointMenu.AddItem(addAsNewWaypoint);
addAsNewWaypoint.ForeColor = Color.Gold;
EditPathMenu.editPathMenu.Visible = false;
editWaypointMenu.RefreshIndex();
editWaypointMenu.Visible = true;
Game.LogTrivial($"Current waypoint is null.");
return;
}
Menu.AddItem(CollectorWaypoint = new UIMenuCheckboxItem("Collector", currentWaypoint.IsCollector, "If this waypoint will collect vehicles to follow the path"));
Menu.AddItem(ChangeCollectorRadius);
ChangeCollectorRadius.Value = currentWaypoint.CollectorRadius != 0
? (int)currentWaypoint.CollectorRadius
: ChangeCollectorRadius.Minimum;
Menu.AddItem(ChangeSpeedZoneRadius);
ChangeSpeedZoneRadius.Value = currentWaypoint.CollectorRadius != 0
? (int)currentWaypoint.SpeedZoneRadius
: ChangeSpeedZoneRadius.Minimum;
ChangeCollectorRadius.Enabled = CollectorWaypoint.Checked ? true : false;
ChangeSpeedZoneRadius.Enabled = CollectorWaypoint.Checked ? true : false;
Menu.AddItem(StopWaypointType = new UIMenuCheckboxItem("Is this a Stop waypoint?", currentWaypoint.IsStopWaypoint, "If checked, vehicles will drive to this waypoint, then stop."));
Menu.AddItem(DirectWaypointBehavior);
if(currentWaypoint.DrivingFlagType == DrivingFlagType.Direct)
{
DirectWaypointBehavior.Checked = true;
}
Menu.AddItem(ChangeWaypointSpeed = new UIMenuNumericScrollerItem<int>("Waypoint Speed", $"How fast the AI will drive to the waypoint in ~b~{SettingsMenu.SpeedUnits.SelectedItem}", 5, 100, 5));
ChangeWaypointSpeed.Value = (int)MathHelper.ConvertMetersPerSecondToMilesPerHour(currentWaypoint.Speed);
Menu.AddItem(UpdateWaypointPosition);
Menu.AddItem(UpdateWaypoint);
UpdateWaypoint.ForeColor = Color.Gold;
Menu.AddItem(RemoveWaypoint);
RemoveWaypoint.ForeColor = Color.Gold;
Menu.AddItem(AddNewWaypoint);
AddNewWaypoint.ForeColor = Color.Gold;
EditPathMenu.Menu.Visible = false;
Menu.RefreshIndex();
Menu.Visible = true;
}
private static void UpdateCollectorMenuOptionsStatus()
private static void UpdateMenuSettings(Waypoint currentWaypoint)
{
if (collectorWaypoint.Checked)
{
changeCollectorRadius.Enabled = true;
changeSpeedZoneRadius.Enabled = true;
}
else
{
changeCollectorRadius.Enabled = false;
changeSpeedZoneRadius.Enabled = false;
}
ChangeWaypointSpeed.Value = (int)MathHelper.ConvertMetersPerSecondToMilesPerHour(currentWaypoint.Speed);
StopWaypointType.Checked = currentWaypoint.IsStopWaypoint;
DirectWaypointBehavior.Checked = currentWaypoint.DrivingFlagType == DrivingFlagType.Direct ? true : false;
CollectorWaypoint.Checked = currentWaypoint.IsCollector;
ChangeCollectorRadius.Enabled = CollectorWaypoint.Checked ? true : false;
ChangeCollectorRadius.Value = (int)currentWaypoint.CollectorRadius;
ChangeSpeedZoneRadius.Enabled = CollectorWaypoint.Checked ? true : false;
ChangeSpeedZoneRadius.Value = (int)currentWaypoint.SpeedZoneRadius;
UpdateWaypointPosition.Checked = false;
}
private static void UpdateWaypoint()
private static void ValidateCollectorRadiusSettings()
{
var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index];
var currentWaypoint = currentPath.Waypoints[editWaypoint.Index];
DrivingFlagType drivingFlag = directWaypointBehavior.Checked ? DrivingFlagType.Direct : DrivingFlagType.Normal;
if (currentPath.Waypoints.Count == 1)
if (ChangeCollectorRadius.Value > ChangeSpeedZoneRadius.Value)
{
currentWaypoint.UpdateWaypoint(currentWaypoint, MousePositionInWorld.GetPosition, drivingFlag, stopWaypointType.Checked, SetDriveSpeedForWaypoint(), true, changeCollectorRadius.Value, changeSpeedZoneRadius.Value, updateWaypointPosition.Checked);
}
else
{
currentWaypoint.UpdateWaypoint(currentWaypoint, MousePositionInWorld.GetPosition, drivingFlag, stopWaypointType.Checked, SetDriveSpeedForWaypoint(), collectorWaypoint.Checked, changeCollectorRadius.Value, changeSpeedZoneRadius.Value, updateWaypointPosition.Checked);
}
Game.LogTrivial($"Path {currentPath.Number} Waypoint {currentWaypoint.Number} updated [Driving style: {drivingFlag} | Stop waypoint: {stopWaypointType.Checked} | Speed: {changeWaypointSpeed.Value} | Collector: {currentWaypoint.IsCollector}]");
updateWaypointPosition.Checked = false;
Game.DisplayNotification($"~o~Scene Manager ~g~[Success]~w~\nWaypoint {currentWaypoint.Number} updated.");
}
private static void RemoveWaypoint()
{
var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index];
var currentWaypoint = currentPath.Waypoints[editWaypoint.Index];
DrivingFlagType drivingFlag = directWaypointBehavior.Checked ? DrivingFlagType.Direct : DrivingFlagType.Normal;
if (currentPath.Waypoints.Count == 1)
{
Game.LogTrivial($"Deleting the last waypoint from the path.");
PathMainMenu.DeletePath(currentPath, Delete.Single);
editWaypointMenu.Visible = false;
PathMainMenu.pathMainMenu.Visible = true;
}
else
{
currentWaypoint.Remove();
currentPath.Waypoints.Remove(currentWaypoint);
Game.LogTrivial($"[Path {currentPath.Number}] Waypoint {currentWaypoint.Number} ({currentWaypoint.DrivingFlagType}) removed");
foreach (Waypoint wp in currentPath.Waypoints)
while (ChangeCollectorRadius.Value > ChangeSpeedZoneRadius.Value)
{
wp.Number = currentPath.Waypoints.IndexOf(wp) + 1;
}
editWaypointMenu.Clear();
BuildEditWaypointMenu();
if (currentPath.Waypoints.Count == 1)
{
Hints.Display($"~o~Scene Manager ~y~[Hint]~w~\nYour path's first waypoint ~b~must~w~ be a collector. If it's not, it will automatically be made into one.");
Game.LogTrivial($"The path only has 1 waypoint left, this waypoint must be a collector.");
currentPath.Waypoints[0].UpdateWaypoint(currentWaypoint, MousePositionInWorld.GetPosition, drivingFlag, stopWaypointType.Checked, SetDriveSpeedForWaypoint(), true, changeCollectorRadius.Value, changeSpeedZoneRadius.Value, updateWaypointPosition.Checked);
collectorWaypoint.Checked = true;
changeCollectorRadius.Enabled = true;
changeSpeedZoneRadius.Enabled = true;
ChangeSpeedZoneRadius.ScrollToNextOption();
}
}
}
private static void AddAsNewWaypoint()
private static void ValidateSpeedZoneRadiusSettings()
{
var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index];
DrivingFlagType drivingFlag = directWaypointBehavior.Checked ? DrivingFlagType.Direct : DrivingFlagType.Normal;
var pathIndex = PathMainMenu.paths.IndexOf(currentPath);
var newWaypointBlip = CreateNewWaypointBlip();
if (!currentPath.IsEnabled)
if (ChangeSpeedZoneRadius.Value < ChangeCollectorRadius.Value)
{
newWaypointBlip.Alpha = 0.5f;
}
if (collectorWaypoint.Checked)
{
currentPath.Waypoints.Add(new Waypoint(currentPath, currentPath.Waypoints.Last().Number + 1, MousePositionInWorld.GetPosition, SetDriveSpeedForWaypoint(), drivingFlag, stopWaypointType.Checked, newWaypointBlip, true, changeCollectorRadius.Value, changeSpeedZoneRadius.Value));
}
else
{
currentPath.Waypoints.Add(new Waypoint(currentPath, currentPath.Waypoints.Last().Number + 1, MousePositionInWorld.GetPosition, SetDriveSpeedForWaypoint(), drivingFlag, stopWaypointType.Checked, newWaypointBlip));
}
editWaypointMenu.RemoveItemAt(0);
editWaypoint = new UIMenuNumericScrollerItem<int>("Edit Waypoint", "", currentPath.Waypoints.First().Number, currentPath.Waypoints.Last().Number, 1);
editWaypointMenu.AddItem(editWaypoint, 0);
editWaypoint.Index = editWaypoint.OptionCount - 1;
editWaypointMenu.RefreshIndex();
updateWaypointPosition.Checked = false;
Game.LogTrivial($"New waypoint (#{currentPath.Waypoints.Last().Number}) added.");
Blip CreateNewWaypointBlip()
{
var spriteNumericalEnum = pathIndex + 17; // 17 because the numerical value of these sprites are always 17 more than the path index
var blip = new Blip(MousePositionInWorld.GetPosition)
{
Scale = 0.5f,
Sprite = (BlipSprite)spriteNumericalEnum
};
if (collectorWaypoint.Checked)
{
blip.Color = Color.Blue;
}
else if (stopWaypointType.Checked)
{
blip.Color = Color.Red;
}
else
{
blip.Color = Color.Green;
}
if (!SettingsMenu.mapBlips.Checked)
{
blip.Alpha = 0f;
}
return blip;
ChangeCollectorRadius.Value = ChangeSpeedZoneRadius.Value;
}
}
private static void EditWaypoint_OnScrollerChanged(UIMenu sender, UIMenuScrollerItem scrollerItem, int first, int last)
{
var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index];
var currentWaypoint = currentPath.Waypoints[editWaypoint.Value - 1];
var currentPath = PathManager.Paths[PathMainMenu.EditPath.Index];
var currentWaypoint = currentPath.Waypoints[EditWaypoint.Value - 1];
if (scrollerItem == editWaypoint)
if (scrollerItem == EditWaypoint)
{
changeWaypointSpeed.Value = (int)MathHelper.ConvertMetersPerSecondToMilesPerHour(currentWaypoint.Speed);
stopWaypointType.Checked = currentWaypoint.IsStopWaypoint;
directWaypointBehavior.Checked = currentWaypoint.DrivingFlagType == DrivingFlagType.Direct ? true : false;
collectorWaypoint.Checked = currentWaypoint.IsCollector;
changeCollectorRadius.Enabled = collectorWaypoint.Checked ? true : false;
changeCollectorRadius.Value = (int)currentWaypoint.CollectorRadius;
changeSpeedZoneRadius.Enabled = collectorWaypoint.Checked ? true : false;
changeSpeedZoneRadius.Value = (int)currentWaypoint.SpeedZoneRadius;
updateWaypointPosition.Checked = false;
UpdateMenuSettings(currentWaypoint);
}
if (scrollerItem == changeCollectorRadius)
if (scrollerItem == ChangeCollectorRadius)
{
if (changeCollectorRadius.Value > changeSpeedZoneRadius.Value)
{
while(changeCollectorRadius.Value > changeSpeedZoneRadius.Value)
{
changeSpeedZoneRadius.ScrollToNextOption();
}
}
ValidateCollectorRadiusSettings();
}
if (scrollerItem == changeSpeedZoneRadius)
if (scrollerItem == ChangeSpeedZoneRadius)
{
if (changeSpeedZoneRadius.Value < changeCollectorRadius.Value)
{
changeCollectorRadius.Value = changeSpeedZoneRadius.Value;
}
ValidateSpeedZoneRadiusSettings();
}
}
private static void EditWaypoint_OnCheckboxChanged(UIMenu sender, UIMenuCheckboxItem checkboxItem, bool @checked)
{
if (checkboxItem == collectorWaypoint)
if (checkboxItem == CollectorWaypoint)
{
changeCollectorRadius.Enabled = collectorWaypoint.Checked ? true : false;
changeSpeedZoneRadius.Enabled = collectorWaypoint.Checked ? true : false;
ChangeCollectorRadius.Enabled = CollectorWaypoint.Checked ? true : false;
ChangeSpeedZoneRadius.Enabled = CollectorWaypoint.Checked ? true : false;
}
}
private static void EditWaypoint_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
{
var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index];
var currentWaypoint = currentPath.Waypoints[editWaypoint.Index];
DrivingFlagType drivingFlag = directWaypointBehavior.Checked ? DrivingFlagType.Direct : DrivingFlagType.Normal;
var currentPath = PathManager.Paths[PathMainMenu.EditPath.Index];
if (selectedItem == updateWaypoint)
if (selectedItem == UpdateWaypoint)
{
UpdateWaypoint();
PathManager.UpdateWaypoint();
}
if (selectedItem == addAsNewWaypoint)
if (selectedItem == AddNewWaypoint)
{
AddAsNewWaypoint();
PathManager.AddNewEditWaypoint(currentPath);
UpdateEditWaypointMenuItem();
}
if (selectedItem == removeWaypoint)
if (selectedItem == RemoveWaypoint)
{
RemoveWaypoint();
PathManager.RemoveEditWaypoint(currentPath);
if(PathManager.Paths.Count < 1)
{
return;
}
BuildEditWaypointMenu();
}
void UpdateEditWaypointMenuItem()
{
// Need to close and re-open the menu so the mouse scroll works on the re-added menu item.
MenuManager.MenuPool.CloseAllMenus();
Menu.RemoveItemAt(0);
EditWaypoint = new UIMenuNumericScrollerItem<int>("Edit Waypoint", "", currentPath.Waypoints.First().Number, currentPath.Waypoints.Last().Number, 1);
Menu.AddItem(EditWaypoint, 0);
EditWaypoint.Index = EditWaypoint.OptionCount - 1;
Menu.RefreshIndex();
UpdateWaypointPosition.Checked = false;
Menu.Visible = true;
}
}
private static void EditWaypoint_OnMenuOpen(UIMenu menu)
{
var scrollerItems = new List<UIMenuScrollerItem> { editWaypoint, changeWaypointSpeed, changeCollectorRadius, changeSpeedZoneRadius };
RNUIMouseInputHandler.Initialize(menu, scrollerItems);
}
private static float SetDriveSpeedForWaypoint()
{
float convertedSpeed;
if (SettingsMenu.speedUnits.SelectedItem == SpeedUnits.MPH)
{
convertedSpeed = MathHelper.ConvertMilesPerHourToMetersPerSecond(changeWaypointSpeed.Value);
}
else
{
convertedSpeed = MathHelper.ConvertKilometersPerHourToMetersPerSecond(changeWaypointSpeed.Value);
}
return convertedSpeed;
var scrollerItems = new List<UIMenuScrollerItem> { EditWaypoint, ChangeWaypointSpeed, ChangeCollectorRadius, ChangeSpeedZoneRadius };
GameFiber.StartNew(() => UserInput.InitializeMenuMouseControl(menu, scrollerItems), "RNUI Mouse Input Fiber");
}
}
}

View file

@ -3,42 +3,51 @@ using RAGENativeUI.Elements;
using System.Collections.Generic;
using System.Drawing;
using SceneManager.Utils;
using Rage;
namespace SceneManager
namespace SceneManager.Menus
{
// The only reason this class should change is to modify the main menu
class MainMenu
{
internal static UIMenu mainMenu { get; private set; }
private static UIMenuItem navigateToPathMenu, navigateToBarrierMenu, navigateToSettingsMenu;
internal static UIMenu Menu { get; } = new UIMenu("Scene Manager", "~o~Main Menu");
internal static void InstantiateMenu()
internal static void Initialize()
{
mainMenu = new UIMenu("Scene Manager", "~o~Main Menu");
MenuManager.menuPool.Add(mainMenu);
MenuManager.AddToMenuPool(Menu);
Menu.OnMenuOpen += MainMenu_OnMenuOpen;
}
internal static void BuildMainMenu()
{
mainMenu.AddItem(navigateToPathMenu = new UIMenuItem("Path Menu"));
var navigateToPathMenu = new UIMenuItem("Path Menu");
Menu.AddItem(navigateToPathMenu);
navigateToPathMenu.ForeColor = Color.Gold;
mainMenu.BindMenuToItem(PathMainMenu.pathMainMenu, navigateToPathMenu);
Menu.BindMenuToItem(PathMainMenu.Menu, navigateToPathMenu);
mainMenu.AddItem(navigateToBarrierMenu = new UIMenuItem("Barrier Menu"));
var navigateToBarrierMenu = new UIMenuItem("Barrier Menu");
Menu.AddItem(navigateToBarrierMenu);
navigateToBarrierMenu.ForeColor = Color.Gold;
mainMenu.BindMenuToItem(BarrierMenu.barrierMenu, navigateToBarrierMenu);
Menu.BindMenuToItem(BarrierMenu.Menu, navigateToBarrierMenu);
mainMenu.AddItem(navigateToSettingsMenu = new UIMenuItem("Settings"));
var navigateToSettingsMenu = new UIMenuItem("Settings Menu");
Menu.AddItem(navigateToSettingsMenu);
navigateToSettingsMenu.ForeColor = Color.Gold;
mainMenu.BindMenuToItem(SettingsMenu.settingsMenu, navigateToSettingsMenu);
Menu.BindMenuToItem(SettingsMenu.Menu, navigateToSettingsMenu);
mainMenu.RefreshIndex();
mainMenu.OnMenuOpen += MainMenu_OnMenuOpen;
Menu.RefreshIndex();
}
private static void MainMenu_OnMenuOpen(UIMenu menu)
{
var scrollerItems = new List<UIMenuScrollerItem> { };
RNUIMouseInputHandler.Initialize(menu, scrollerItems);
GameFiber.StartNew(() => UserInput.InitializeMenuMouseControl(menu, scrollerItems), "RNUI Mouse Input Fiber");
}
internal static void DisplayMenu()
{
Menu.Visible = !Menu.Visible;
}
}
}

View file

@ -1,32 +1,36 @@
using RAGENativeUI;
using SceneManager.Menus;
using Rage;
using System.Linq;
using RAGENativeUI.Elements;
using System.Collections.Generic;
using System.Drawing;
namespace SceneManager
{
// The only reason this class should change is to modify how menus are are being handled
internal static class MenuManager
{
internal static MenuPool menuPool = new MenuPool();
internal static Dictionary<UIMenu, List<UIMenuItem>> menus = new Dictionary<UIMenu, List<UIMenuItem>>();
internal static MenuPool MenuPool { get; } = new MenuPool();
internal static void InstantiateMenus()
internal static void InitializeMenus()
{
MainMenu.InstantiateMenu();
SettingsMenu.InstantiateMenu();
PathMainMenu.InstantiateMenu();
PathCreationMenu.InstantiateMenu();
BarrierMenu.InstantiateMenu();
EditPathMenu.InstantiateMenu();
EditWaypointMenu.InstantiateMenu();
MainMenu.Initialize();
SettingsMenu.Initialize();
PathMainMenu.Initialize();
PathCreationMenu.Initialize();
ImportPathMenu.Initialize();
BarrierMenu.Initialize();
EditPathMenu.Initialize();
EditWaypointMenu.Initialize();
BuildMenus();
ColorMenuItems();
DefineMenuMouseSettings();
}
private static void DefineMenuMouseSettings()
{
foreach (UIMenu menu in menuPool)
foreach (UIMenu menu in MenuPool)
{
menu.MouseControlsEnabled = false;
menu.AllowCameraMovement = true;
@ -38,8 +42,57 @@ namespace SceneManager
MainMenu.BuildMainMenu();
SettingsMenu.BuildSettingsMenu();
PathMainMenu.BuildPathMenu();
ImportPathMenu.BuildImportMenu();
EditPathMenu.BuildEditPathMenu();
BarrierMenu.BuildBarrierMenu();
}
private static void ColorMenuItems()
{
foreach(UIMenuItem menuItem in MenuPool.SelectMany(x => x.MenuItems))
{
if (menuItem.Enabled && menuItem.ForeColor == Color.Gold)
{
menuItem.HighlightedBackColor = menuItem.ForeColor;
}
}
}
internal static bool AreMenusClosed()
{
if (!BarrierMenu.Menu.Visible && !PathMainMenu.Menu.Visible && !PathCreationMenu.Menu.Visible && !EditPathMenu.Menu.Visible && !EditWaypointMenu.Menu.Visible && !SettingsMenu.Menu.Visible)
{
return true;
}
else
{
return false;
}
}
internal static void Update()
{
while (AnyMenuVisible())
{
MenuPool.ProcessMenus();
GameFiber.Yield();
}
}
private static bool AnyMenuVisible()
{
if(MenuPool.Any(x => x.Visible))
{
return true;
}
return false;
}
internal static void AddToMenuPool(UIMenu menu)
{
MenuPool.Add(menu);
}
}
}

View file

@ -1,318 +1,148 @@
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Rage;
using RAGENativeUI;
using RAGENativeUI.Elements;
using SceneManager.Utils;
using SceneManager.Objects;
namespace SceneManager
namespace SceneManager.Menus
{
class PathCreationMenu
{
internal static UIMenu pathCreationMenu = new UIMenu("Scene Manager", "~o~Path Creation Menu");
private static UIMenuItem trafficAddWaypoint = new UIMenuItem("Add waypoint"), trafficRemoveWaypoint = new UIMenuItem("Remove last waypoint"), trafficEndPath = new UIMenuItem("End path creation");
internal static UIMenuNumericScrollerItem<int> waypointSpeed;
internal static UIMenuCheckboxItem stopWaypointType = new UIMenuCheckboxItem("Is this a Stop waypoint?", false, "If checked, vehicles will drive to this waypoint, then stop.");
internal static UIMenuCheckboxItem directWaypointBehavior = new UIMenuCheckboxItem("Drive directly to waypoint?", false, "If checked, vehicles will ignore traffic rules and drive directly to this waypoint.");
internal static UIMenuCheckboxItem collectorWaypoint = new UIMenuCheckboxItem("Collector", true, "If checked, this waypoint will collect vehicles to follow the path. Your path's first waypoint ~b~must~w~ be a collector.");
internal static UIMenuNumericScrollerItem<int> collectorRadius = new UIMenuNumericScrollerItem<int>("Collection Radius", "The distance from this waypoint (in meters) vehicles will be collected", 1, 50, 1);
internal static UIMenuNumericScrollerItem<int> speedZoneRadius = new UIMenuNumericScrollerItem<int>("Speed Zone Radius", "The distance from this collector waypoint (in meters) non-collected vehicles will drive at this waypoint's speed", 5, 200, 5);
private static List<UIMenuItem> menuItems = new List<UIMenuItem> {collectorWaypoint, collectorRadius, speedZoneRadius, stopWaypointType, directWaypointBehavior, waypointSpeed, trafficAddWaypoint, trafficRemoveWaypoint, trafficEndPath };
internal static UIMenu Menu { get; } = new UIMenu("Scene Manager", "~o~Path Creation Menu");
private static Path CurrentPath { get; set; }
private static UIMenuItem AddWaypoint { get; } = new UIMenuItem("Add waypoint");
internal static UIMenuItem RemoveLastWaypoint { get; } = new UIMenuItem("Remove last waypoint");
internal static UIMenuItem EndPathCreation { get; } = new UIMenuItem("End path creation");
internal static UIMenuNumericScrollerItem<int> WaypointSpeed { get; private set; }
internal static UIMenuCheckboxItem StopWaypoint { get; } = new UIMenuCheckboxItem("Is this a Stop waypoint?", false, "If checked, vehicles will drive to this waypoint, then stop.");
internal static UIMenuCheckboxItem DirectWaypoint { get; } = new UIMenuCheckboxItem("Drive directly to waypoint?", false, "If checked, vehicles will ignore traffic rules and drive directly to this waypoint.");
internal static UIMenuCheckboxItem CollectorWaypoint { get; } = new UIMenuCheckboxItem("Collector", true, "If checked, this waypoint will collect vehicles to follow the path. Your path's first waypoint ~b~must~w~ be a collector.");
internal static UIMenuNumericScrollerItem<int> CollectorRadius { get; } = new UIMenuNumericScrollerItem<int>("Collection Radius", "The distance from this waypoint (in meters) vehicles will be collected", 1, 50, 1);
internal static UIMenuNumericScrollerItem<int> SpeedZoneRadius { get; } = new UIMenuNumericScrollerItem<int>("Speed Zone Radius", "The distance from this collector waypoint (in meters) non-collected vehicles will drive at this waypoint's speed", 5, 200, 5);
internal static State PathCreationState { get; set; } = State.Uninitialized;
internal static void InstantiateMenu()
internal static void Initialize()
{
pathCreationMenu.ParentMenu = PathMainMenu.pathMainMenu;
MenuManager.menuPool.Add(pathCreationMenu);
pathCreationMenu.OnItemSelect += PathCreation_OnItemSelected;
pathCreationMenu.OnCheckboxChange += PathCreation_OnCheckboxChanged;
pathCreationMenu.OnScrollerChange += PathCreation_OnScrollerChanged;
pathCreationMenu.OnMenuOpen += PathCreation_OnMenuOpen;
Menu.ParentMenu = PathMainMenu.Menu;
MenuManager.MenuPool.Add(Menu);
Menu.OnItemSelect += PathCreation_OnItemSelected;
Menu.OnCheckboxChange += PathCreation_OnCheckboxChanged;
Menu.OnScrollerChange += PathCreation_OnScrollerChanged;
Menu.OnMenuOpen += PathCreation_OnMenuOpen;
}
internal static void BuildPathCreationMenu()
{
pathCreationMenu.AddItem(collectorWaypoint);
collectorWaypoint.Enabled = false;
collectorWaypoint.Checked = true;
Menu.MenuItems.Clear();
pathCreationMenu.AddItem(collectorRadius);
collectorRadius.Index = Settings.CollectorRadius - 1;
collectorRadius.Enabled = true;
Menu.AddItem(CollectorWaypoint);
CollectorWaypoint.Enabled = false;
CollectorWaypoint.Checked = true;
pathCreationMenu.AddItem(speedZoneRadius);
speedZoneRadius.Index = (Settings.SpeedZoneRadius / 5) - 1;
speedZoneRadius.Enabled = true;
Menu.AddItem(CollectorRadius);
CollectorRadius.Index = Settings.CollectorRadius - 1;
CollectorRadius.Enabled = true;
pathCreationMenu.AddItem(stopWaypointType);
stopWaypointType.Checked = Settings.StopWaypoint;
pathCreationMenu.AddItem(directWaypointBehavior);
directWaypointBehavior.Checked = Settings.DirectDrivingBehavior;
Menu.AddItem(SpeedZoneRadius);
SpeedZoneRadius.Index = (Settings.SpeedZoneRadius / 5) - 1;
SpeedZoneRadius.Enabled = true;
pathCreationMenu.AddItem(waypointSpeed = new UIMenuNumericScrollerItem<int>("Waypoint Speed", $"How fast the AI will drive to this waypoint in ~b~{SettingsMenu.speedUnits.SelectedItem}", 5, 100, 5));
waypointSpeed.Index = (Settings.WaypointSpeed / 5) - 1;
Menu.AddItem(StopWaypoint);
StopWaypoint.Checked = Settings.StopWaypoint;
Menu.AddItem(DirectWaypoint);
DirectWaypoint.Checked = Settings.DirectDrivingBehavior;
pathCreationMenu.AddItem(trafficAddWaypoint);
trafficAddWaypoint.ForeColor = Color.Gold;
Menu.AddItem(WaypointSpeed = new UIMenuNumericScrollerItem<int>("Waypoint Speed", $"How fast the AI will drive to this waypoint in ~b~{SettingsMenu.SpeedUnits.SelectedItem}", 5, 100, 5));
WaypointSpeed.Index = (Settings.WaypointSpeed / 5) - 1;
pathCreationMenu.AddItem(trafficRemoveWaypoint);
trafficRemoveWaypoint.ForeColor = Color.Gold;
trafficRemoveWaypoint.Enabled = false;
Menu.AddItem(AddWaypoint);
AddWaypoint.ForeColor = Color.Gold;
pathCreationMenu.AddItem(trafficEndPath);
trafficEndPath.ForeColor = Color.Gold;
trafficEndPath.Enabled = false;
Menu.AddItem(RemoveLastWaypoint);
RemoveLastWaypoint.ForeColor = Color.Gold;
RemoveLastWaypoint.Enabled = false;
pathCreationMenu.RefreshIndex();
Menu.AddItem(EndPathCreation);
EndPathCreation.ForeColor = Color.Gold;
EndPathCreation.Enabled = false;
Menu.RefreshIndex();
}
private static void UpdateCollectorMenuOptionsStatus()
private static void ValidateCollectorRadiusSettings()
{
if (collectorWaypoint.Checked)
if (CollectorRadius.Value > SpeedZoneRadius.Value)
{
collectorRadius.Enabled = true;
speedZoneRadius.Enabled = true;
}
else
{
collectorRadius.Enabled = false;
speedZoneRadius.Enabled = false;
}
}
private static void AddNewWaypoint()
{
var anyPathsExist = PathMainMenu.paths.Count > 0;
var waypointPosition = MousePositionInWorld.GetPosition;
if (!anyPathsExist)
{
AddNewPathToPathsCollection(PathMainMenu.paths, 0);
}
else if (anyPathsExist && !PathMainMenu.paths.Any(p => p != null && p.State == State.Creating))
{
AddNewPathToPathsCollection(PathMainMenu.paths, PathMainMenu.paths.IndexOf(PathMainMenu.paths.Where(p => p.State == State.Finished).Last()) + 1);
}
var firstNonNullPath = PathMainMenu.paths.Where(p => p != null && p.State == State.Creating).First();
var pathIndex = PathMainMenu.paths.IndexOf(firstNonNullPath);
var pathNumber = firstNonNullPath.Number;
var waypointNumber = PathMainMenu.paths[pathIndex].Waypoints.Count + 1;
DrivingFlagType drivingFlag = directWaypointBehavior.Checked ? DrivingFlagType.Direct : DrivingFlagType.Normal;
if (collectorWaypoint.Checked)
{
PathMainMenu.paths[pathIndex].Waypoints.Add(new Waypoint(firstNonNullPath, waypointNumber, waypointPosition, SetDriveSpeedForWaypoint(), drivingFlag, stopWaypointType.Checked, CreateWaypointBlip(), true, collectorRadius.Value, speedZoneRadius.Value));
}
else
{
PathMainMenu.paths[pathIndex].Waypoints.Add(new Waypoint(firstNonNullPath, waypointNumber, waypointPosition, SetDriveSpeedForWaypoint(), drivingFlag, stopWaypointType.Checked, CreateWaypointBlip()));
}
Game.LogTrivial($"Path {pathNumber} Waypoint {waypointNumber} added [Driving style: {drivingFlag} | Stop waypoint: {stopWaypointType.Checked} | Speed: {waypointSpeed.Value} | Collector: {collectorWaypoint.Checked}]");
ToggleTrafficEndPathMenuItem(pathIndex);
collectorWaypoint.Enabled = true;
collectorWaypoint.Checked = false;
if (collectorWaypoint.Checked)
{
collectorRadius.Enabled = true;
speedZoneRadius.Enabled = true;
}
else
{
collectorRadius.Enabled = false;
speedZoneRadius.Enabled = false;
}
trafficRemoveWaypoint.Enabled = true;
PathMainMenu.createNewPath.Text = $"Continue Creating Path {pathNumber}";
float SetDriveSpeedForWaypoint()
{
float convertedSpeed;
if (SettingsMenu.speedUnits.SelectedItem == SpeedUnits.MPH)
while (CollectorRadius.Value > SpeedZoneRadius.Value)
{
//Logger.Log($"Original speed: {waypointSpeeds[waypointSpeed.Index]}{SettingsMenu.speedUnits.SelectedItem}");
convertedSpeed = MathHelper.ConvertMilesPerHourToMetersPerSecond(waypointSpeed.Value);
//Logger.Log($"Converted speed: {convertedSpeed}m/s");
}
else
{
//Logger.Log($"Original speed: {waypointSpeeds[waypointSpeed.Index]}{SettingsMenu.speedUnits.SelectedItem}");
convertedSpeed = MathHelper.ConvertKilometersPerHourToMetersPerSecond(waypointSpeed.Value);
//Logger.Log($"Converted speed: {convertedSpeed}m/s");
}
return convertedSpeed;
}
Blip CreateWaypointBlip()
{
var spriteNumericalEnum = pathIndex + 17; // 17 because the numerical value of these sprites are always 17 more than the path index
var blip = new Blip(waypointPosition)
{
Scale = 0.5f,
Sprite = (BlipSprite)spriteNumericalEnum
};
if (collectorWaypoint.Checked)
{
blip.Color = Color.Blue;
}
else if (stopWaypointType.Checked)
{
blip.Color = Color.Red;
}
else
{
blip.Color = Color.Green;
}
if (!SettingsMenu.mapBlips.Checked)
{
blip.Alpha = 0f;
}
return blip;
}
}
private static void RemoveWaypoint()
{
for (int i = 0; i < PathMainMenu.paths.Count; i++)
{
if (PathMainMenu.paths.ElementAtOrDefault(i) != null && PathMainMenu.paths[i].State == State.Creating)
{
Game.LogTrivial($"[Path {i + 1}] {PathMainMenu.paths[i].Waypoints.Last().DrivingFlagType} waypoint removed");
PathMainMenu.paths[i].Waypoints.Last().Blip.Delete();
PathMainMenu.paths[i].Waypoints.Last().RemoveSpeedZone();
if (PathMainMenu.paths[i].Waypoints.Last().CollectorRadiusBlip)
{
PathMainMenu.paths[i].Waypoints.Last().CollectorRadiusBlip.Delete();
}
PathMainMenu.paths[i].Waypoints.RemoveAt(PathMainMenu.paths[i].Waypoints.IndexOf(PathMainMenu.paths[i].Waypoints.Last()));
ToggleTrafficEndPathMenuItem(i);
// If the path has no waypoints, disable the menu option to remove a waypoint
if (PathMainMenu.paths[i].Waypoints.Count == 0)
{
collectorWaypoint.Checked = true;
collectorWaypoint.Enabled = false;
speedZoneRadius.Enabled = true;
collectorRadius.Enabled = true;
trafficRemoveWaypoint.Enabled = false;
trafficEndPath.Enabled = false;
}
SpeedZoneRadius.ScrollToNextOption();
}
}
}
private static void EndPath()
private static void ValidateSpeedZoneRadiusSettings()
{
for (int i = 0; i < PathMainMenu.paths.Count; i++)
if (SpeedZoneRadius.Value < CollectorRadius.Value)
{
var currentPath = PathMainMenu.paths[i];
if (PathMainMenu.paths.ElementAtOrDefault(i) != null && currentPath.State == State.Creating)
{
Game.LogTrivial($"[Path Creation] Path {currentPath.Number} finished with {currentPath.Waypoints.Count} waypoints.");
Game.DisplayNotification($"~o~Scene Manager ~g~[Success]\n~w~Path {i + 1} complete.");
currentPath.State = State.Finished;
currentPath.IsEnabled = true;
currentPath.Number = i + 1;
currentPath.LoopForVehiclesToBeDismissed();
GameFiber.StartNew(() =>
{
currentPath.LoopWaypointCollection();
});
PathMainMenu.createNewPath.Text = "Create New Path";
PathMainMenu.BuildPathMenu();
PathMainMenu.pathMainMenu.RefreshIndex();
pathCreationMenu.Clear();
PathMainMenu.pathMainMenu.Visible = true;
break;
}
CollectorRadius.Value = SpeedZoneRadius.Value;
}
}
private static void ToggleTrafficEndPathMenuItem(int pathIndex)
{
if (PathMainMenu.paths[pathIndex].Waypoints.Count > 0)
{
trafficEndPath.Enabled = true;
}
else
{
trafficEndPath.Enabled = false;
}
}
private static void AddNewPathToPathsCollection(List<Path> paths, int pathIndex)
{
var pathNum = pathIndex + 1;
Game.LogTrivial($"Creating path {pathNum}");
Game.DisplayNotification($"~o~Scene Manager\n~y~[Creating]~w~ Path {pathNum} started.");
paths.Insert(pathIndex, new Path(pathNum, State.Creating));
trafficRemoveWaypoint.Enabled = false;
trafficEndPath.Enabled = false;
}
private static void PathCreation_OnCheckboxChanged(UIMenu sender, UIMenuCheckboxItem checkboxItem, bool @checked)
{
if(checkboxItem == collectorWaypoint)
if(checkboxItem == CollectorWaypoint)
{
collectorRadius.Enabled = collectorWaypoint.Checked ? true : false;
speedZoneRadius.Enabled = collectorWaypoint.Checked ? true : false;
CollectorRadius.Enabled = CollectorWaypoint.Checked ? true : false;
SpeedZoneRadius.Enabled = CollectorWaypoint.Checked ? true : false;
}
}
private static void PathCreation_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
{
if (selectedItem == trafficAddWaypoint)
if (selectedItem == AddWaypoint)
{
AddNewWaypoint();
if (PathCreationState != State.Creating)
{
CurrentPath = PathManager.InitializeNewPath();
}
PathManager.AddWaypoint(CurrentPath);
PathManager.TogglePathCreationMenuItems(CurrentPath);
}
if (selectedItem == trafficRemoveWaypoint)
if (selectedItem == RemoveLastWaypoint)
{
RemoveWaypoint();
PathManager.RemoveWaypoint(CurrentPath);
PathManager.TogglePathCreationMenuItems(CurrentPath);
}
if (selectedItem == trafficEndPath)
if (selectedItem == EndPathCreation)
{
EndPath();
PathCreationState = State.Finished;
PathManager.EndPath(CurrentPath);
}
}
private static void PathCreation_OnScrollerChanged(UIMenu sender, UIMenuScrollerItem scrollerItem, int first, int last)
{
if (scrollerItem == collectorRadius)
if (scrollerItem == CollectorRadius)
{
if (collectorRadius.Value > speedZoneRadius.Value)
{
while (collectorRadius.Value > speedZoneRadius.Value)
{
speedZoneRadius.ScrollToNextOption();
}
}
ValidateCollectorRadiusSettings();
}
if (scrollerItem == speedZoneRadius)
if (scrollerItem == SpeedZoneRadius)
{
if (speedZoneRadius.Value < collectorRadius.Value)
{
collectorRadius.Value = speedZoneRadius.Value;
}
ValidateSpeedZoneRadiusSettings();
}
}
private static void PathCreation_OnMenuOpen(UIMenu menu)
{
var scrollerItems = new List<UIMenuScrollerItem> { collectorRadius, speedZoneRadius, waypointSpeed };
RNUIMouseInputHandler.Initialize(menu, scrollerItems);
var scrollerItems = new List<UIMenuScrollerItem> { CollectorRadius, SpeedZoneRadius, WaypointSpeed };
GameFiber.StartNew(() => UserInput.InitializeMenuMouseControl(menu, scrollerItems), "RNUI Mouse Input Fiber");
}
}
}

View file

@ -7,414 +7,157 @@ using RAGENativeUI.Elements;
using SceneManager.Objects;
using SceneManager.Utils;
namespace SceneManager
namespace SceneManager.Menus
{
internal static class PathMainMenu
{
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" };
internal static UIMenu pathMainMenu = new UIMenu("Scene Manager", "~o~Path Manager Main Menu");
internal static UIMenuItem createNewPath;
internal static UIMenuListScrollerItem<string> importPath;
internal static UIMenuItem deleteAllPaths = new UIMenuItem("Delete All Paths");
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 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\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);
private static int MAX_PATH_LIMIT { get; } = 10;
internal static List<string> ImportedPaths { get; } = new List<string>();
private static string[] DismissOptions { get; } = new string[] { "From path", "From waypoint", "From world" };
internal static UIMenu Menu { get; } = new UIMenu("Scene Manager", "~o~Path Manager Main Menu");
internal static UIMenuItem CreateNewPath { get; } = new UIMenuItem("Create New Path");
internal static UIMenuListScrollerItem<string> ImportPath { get; } = new UIMenuListScrollerItem<string>("Import Path", "Import a saved path", ImportedPaths);
internal static UIMenuItem DeleteAllPaths { get; } = new UIMenuItem("Delete All Paths");
internal static UIMenuNumericScrollerItem<int> EditPath { get; private set; }
internal static UIMenuListScrollerItem<string> DirectOptions { get; } = new UIMenuListScrollerItem<string>("Direct driver to path's", "", new[] { "First waypoint", "Nearest waypoint" });
internal static UIMenuNumericScrollerItem<int> DirectDriver { get; private set; }
internal static UIMenuListScrollerItem<string> DismissDriver { get; } = 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 { get; } = new UIMenuCheckboxItem("Disable All Paths", false);
internal static void InstantiateMenu()
internal static void Initialize()
{
pathMainMenu.ParentMenu = MainMenu.mainMenu;
MenuManager.menuPool.Add(pathMainMenu);
pathMainMenu.OnItemSelect += PathMenu_OnItemSelected;
pathMainMenu.OnCheckboxChange += PathMenu_OnCheckboxChange;
pathMainMenu.OnMenuOpen += PathMenu_OnMenuOpen;
Menu.ParentMenu = MainMenu.Menu;
MenuManager.MenuPool.Add(Menu);
Menu.OnItemSelect += PathMenu_OnItemSelected;
Menu.OnCheckboxChange += PathMenu_OnCheckboxChange;
Menu.OnMenuOpen += PathMenu_OnMenuOpen;
}
internal static void BuildPathMenu()
{
MenuManager.menuPool.CloseAllMenus();
pathMainMenu.Clear();
MenuManager.MenuPool.CloseAllMenus();
Menu.Clear();
pathMainMenu.AddItem(createNewPath = new UIMenuItem("Create New Path"));
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));
editPath.ForeColor = Color.Gold;
pathMainMenu.AddItem(disableAllPaths);
disableAllPaths.Enabled = true;
pathMainMenu.AddItem(deleteAllPaths);
deleteAllPaths.Enabled = true;
deleteAllPaths.ForeColor = Color.Gold;
pathMainMenu.AddItem(directOptions);
pathMainMenu.AddItem(directDriver = new UIMenuNumericScrollerItem<int>("Direct nearest driver to path", "", 1, paths.Count, 1));
directDriver.ForeColor = Color.Gold;
directDriver.Enabled = true;
pathMainMenu.AddItem(dismissDriver);
dismissDriver.ForeColor = Color.Gold;
Menu.AddItem(CreateNewPath);
CreateNewPath.ForeColor = Color.Gold;
Menu.AddItem(ImportPath);
ImportPath.ForeColor = Color.Gold;
ImportPath.Enabled = true;
Menu.AddItem(EditPath = new UIMenuNumericScrollerItem<int>("Edit Path", "", 1, PathManager.Paths.Count, 1));
EditPath.ForeColor = Color.Gold;
Menu.AddItem(DisableAllPaths);
DisableAllPaths.Enabled = true;
Menu.AddItem(DeleteAllPaths);
DeleteAllPaths.Enabled = true;
DeleteAllPaths.ForeColor = Color.Gold;
Menu.AddItem(DirectOptions);
Menu.AddItem(DirectDriver = new UIMenuNumericScrollerItem<int>("Direct nearest driver to path", "", 1, PathManager.Paths.Count, 1)); // This must instantiate here because the Paths.Count value changes
DirectDriver.ForeColor = Color.Gold;
DirectDriver.Enabled = true;
Menu.AddItem(DismissDriver);
DismissDriver.ForeColor = Color.Gold;
if (paths.Count == 8)
if (PathManager.Paths.Count == MAX_PATH_LIMIT)
{
createNewPath.Enabled = false;
CreateNewPath.Enabled = false;
ImportPath.Enabled = false;
}
if (paths.Count == 0)
if (PathManager.Paths.Count == 0)
{
editPath.Enabled = false;
deleteAllPaths.Enabled = false;
disableAllPaths.Enabled = false;
directDriver.Enabled = false;
EditPath.Enabled = false;
DeleteAllPaths.Enabled = false;
DisableAllPaths.Enabled = false;
DirectDriver.Enabled = false;
}
if(Settings.ImportedPaths.Count == 0)
{
ImportPath.Enabled = false;
}
MenuManager.menuPool.RefreshIndex();
}
private static bool VehicleAndDriverValid(this Vehicle v)
{
if (v && v.HasDriver && v.Driver && v.Driver.IsAlive)
{
return true;
}
else
{
return false;
}
}
private static void GoToEditPathMenu()
{
pathMainMenu.Visible = false;
EditPathMenu.editPathMenu.Visible = true;
}
private static void GoToPathCreationMenu()
{
if (createNewPath.Text.Contains("Continue"))
{
pathMainMenu.Visible = false;
PathCreationMenu.pathCreationMenu.Visible = true;
}
else
{
PathCreationMenu.pathCreationMenu.Clear();
PathCreationMenu.BuildPathCreationMenu();
pathMainMenu.Visible = false;
PathCreationMenu.pathCreationMenu.Visible = true;
// For each element in paths, determine if the element exists but is not finished yet, or if it doesn't exist, create it.
for (int i = 0; i <= paths.Count; i++)
{
if (paths.ElementAtOrDefault(i) != null && paths[i].State == State.Creating)
{
Game.DisplayNotification($"~o~Scene Manager~y~[Creating]\n~w~Resuming path {paths[i].Number}");
break;
}
}
}
}
private static void DisableAllPaths()
{
if (disableAllPaths.Checked)
{
foreach (Path path in paths)
{
path.DisablePath();
}
Game.LogTrivial($"All paths disabled.");
}
else
{
foreach (Path path in paths)
{
path.EnablePath();
}
Game.LogTrivial($"All paths enabled.");
}
}
private static void DeleteAllPaths()
{
for (int i = 0; i < paths.Count; i++)
{
DeletePath(paths[i], Delete.All);
}
disableAllPaths.Checked = false;
paths.Clear();
BuildPathMenu();
pathMainMenu.Visible = true;
Game.LogTrivial($"All paths deleted");
Game.DisplayNotification($"~o~Scene Manager\n~w~All paths deleted.");
}
internal static void DeletePath(Path path, Delete pathsToDelete)
{
//Game.LogTrivial($"Preparing to delete path {path.Number}");
RemoveVehiclesFromPath();
RemoveBlipsAndYieldZones();
//Game.LogTrivial($"Clearing path waypoints");
path.Waypoints.Clear();
// Manipulating the menu to reflect specific paths being deleted
if (pathsToDelete == Delete.Single)
{
paths.Remove(path);
UpdatePathNumbers();
UpdatePathBlips();
BuildPathMenu();
pathMainMenu.Visible = true;
Game.LogTrivial($"Path {path.Number} deleted successfully.");
Game.DisplayNotification($"~o~Scene Manager\n~w~Path {path.Number} deleted.");
}
EditPathMenu.editPathMenu.Reset(true, true);
EditPathMenu.disablePath.Enabled = true;
void RemoveVehiclesFromPath()
{
//Game.LogTrivial($"Removing all vehicles on the path");
var pathVehicles = path.CollectedVehicles.Where(cv => cv.Path.Number == path.Number).ToList();
foreach (CollectedVehicle cv in pathVehicles.Where(cv => cv != null && cv.Vehicle && cv.Driver))
{
if (cv.StoppedAtWaypoint)
{
Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(cv.Vehicle, 1f, 1, true);
}
//cv.StoppedAtWaypoint = false;
if (cv.Driver.GetAttachedBlip())
{
cv.Driver.GetAttachedBlip().Delete();
}
cv.Driver.Dismiss();
cv.Vehicle.IsSirenOn = false;
cv.Vehicle.IsSirenSilent = true;
cv.Vehicle.Dismiss();
//Game.LogTrivial($"{cv.vehicle.Model.Name} cleared from path {cv.path}");
path.CollectedVehicles.Remove(cv);
}
path.CollectedVehicles.Clear();
}
void RemoveBlipsAndYieldZones()
{
//Game.LogTrivial($"Removing waypoint blips and yield zones.");
foreach (Waypoint waypoint in path.Waypoints)
{
if (waypoint.SpeedZone != 0)
{
waypoint.RemoveSpeedZone();
}
if (waypoint.Blip)
{
waypoint.Blip.Delete();
}
if (waypoint.CollectorRadiusBlip)
{
waypoint.CollectorRadiusBlip.Delete();
}
}
}
void UpdatePathBlips()
{
foreach (Path p in paths)
{
foreach (Waypoint waypoint in p.Waypoints)
{
var blipColor = waypoint.Blip.Color;
waypoint.Blip.Sprite = (BlipSprite)paths.IndexOf(p) + 17;
waypoint.Blip.Color = blipColor;
}
}
}
void UpdatePathNumbers()
{
for (int i = 0; i < paths.Count; i++)
{
paths[i].Number = i + 1;
}
}
}
private static void DirectDriver()
{
var nearbyVehicle = Game.LocalPlayer.Character.GetNearbyVehicles(16).Where(v => v != Game.LocalPlayer.Character.CurrentVehicle && v.VehicleAndDriverValid()).FirstOrDefault();
var path = paths[directDriver.Index];
var collectedVehicle = path.CollectedVehicles.Where(cv => cv.Vehicle == nearbyVehicle).FirstOrDefault();
var waypoints = path.Waypoints;
var firstWaypoint = waypoints.First();
var nearestWaypoint = waypoints.Where(wp => wp.Position.DistanceTo2D(nearbyVehicle.FrontPosition) < wp.Position.DistanceTo2D(nearbyVehicle.RearPosition)).OrderBy(wp => wp.Position.DistanceTo2D(nearbyVehicle)).FirstOrDefault();
if (nearbyVehicle)
{
var nearbyVehiclePath = paths.Where(p => p.CollectedVehicles.Any(v => v.Vehicle == nearbyVehicle)).FirstOrDefault();
if (nearbyVehiclePath != null)
{
var nearbyCollectedVehicle = nearbyVehiclePath.CollectedVehicles.Where(v => v.Vehicle == nearbyVehicle).FirstOrDefault();
if (nearbyCollectedVehicle != null)
{
nearbyCollectedVehicle.Dismiss(DismissOption.FromDirected, path);
if (directOptions.SelectedItem == "First waypoint")
{
GameFiber.StartNew(() =>
{
nearbyCollectedVehicle.AssignWaypointTasks(path, firstWaypoint);
//AITasking.AssignWaypointTasks(nearbyCollectedVehicle, path, firstWaypoint);
});
}
else
{
if (nearestWaypoint != null)
{
GameFiber.StartNew(() =>
{
nearbyCollectedVehicle.AssignWaypointTasks(path, nearestWaypoint);
//AITasking.AssignWaypointTasks(nearbyCollectedVehicle, path, nearestWaypoint);
});
}
}
return;
}
}
// The vehicle should only be added to the collection when it's not null AND if the selected item is First Waypoint OR if the selected item is nearestWaypoint AND nearestWaypoint is not null
if (collectedVehicle == null && directOptions.SelectedItem == "First waypoint" || (directOptions.SelectedItem == "Nearest waypoint" && nearestWaypoint != null))
{
Game.LogTrivial($"[Direct Driver] Adding {nearbyVehicle.Model.Name} to collection.");
path.CollectedVehicles.Add(new CollectedVehicle(nearbyVehicle, path));
collectedVehicle = path.CollectedVehicles.Where(cv => cv.Vehicle == nearbyVehicle).FirstOrDefault();
//Logger.Log($"Collected vehicle is {collectedVehicle.Vehicle.Model.Name}");
}
if (collectedVehicle == null)
{
return;
}
collectedVehicle.Directed = true;
collectedVehicle.Driver.Tasks.Clear();
//Logger.Log($"Collected vehicle properties: Dismissed [{collectedVehicle.Dismissed}], Directed [{collectedVehicle.Directed}], StopppedAtWaypoint [{collectedVehicle.StoppedAtWaypoint}]");
if (directOptions.SelectedItem == "First waypoint")
{
GameFiber.StartNew(() =>
{
collectedVehicle.AssignWaypointTasks(path, firstWaypoint);
//AITasking.AssignWaypointTasks(collectedVehicle, path, firstWaypoint);
});
}
else
{
if (nearestWaypoint != null)
{
GameFiber.StartNew(() =>
{
collectedVehicle.AssignWaypointTasks(path, nearestWaypoint);
//AITasking.AssignWaypointTasks(collectedVehicle, path, nearestWaypoint);
});
}
}
}
}
private static void DismissDriver()
{
var nearbyVehicle = Game.LocalPlayer.Character.GetNearbyVehicles(16).Where(v => v != Game.LocalPlayer.Character.CurrentVehicle && v.VehicleAndDriverValid()).FirstOrDefault();
if (nearbyVehicle)
{
if (!paths.Any() && dismissDriver.Index == (int)DismissOption.FromWorld)
{
Game.LogTrivial($"Dismissed {nearbyVehicle.Model.Name} from the world");
while (nearbyVehicle && nearbyVehicle.HasOccupants)
{
foreach (Ped occupant in nearbyVehicle.Occupants)
{
occupant.Delete();
}
GameFiber.Yield();
}
if (nearbyVehicle)
{
nearbyVehicle.Delete();
}
return;
}
foreach (Path path in paths)
{
var collectedVehicle = path.CollectedVehicles.Where(cv => cv.Vehicle == nearbyVehicle).FirstOrDefault();
if (collectedVehicle != null)
{
collectedVehicle.Dismiss((DismissOption)dismissDriver.Index);
break;
}
else if (dismissDriver.Index == (int)DismissOption.FromWorld)
{
Game.LogTrivial($"Dismissed {nearbyVehicle.Model.Name} from the world");
while (nearbyVehicle && nearbyVehicle.HasOccupants)
{
foreach (Ped occupant in nearbyVehicle.Occupants)
{
occupant.Delete();
}
GameFiber.Yield();
}
if (nearbyVehicle)
{
nearbyVehicle.Delete();
}
break;
}
}
}
MenuManager.MenuPool.RefreshIndex();
}
private static void PathMenu_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
{
if (selectedItem == createNewPath)
if (selectedItem == CreateNewPath)
{
GoToPathCreationMenu();
}
if (selectedItem == editPath)
if(selectedItem == ImportPath)
{
pathMainMenu.Visible = false;
EditPathMenu.editPathMenu.Visible = true;
GoToImportMenu();
}
if (selectedItem == deleteAllPaths)
if (selectedItem == EditPath)
{
DeleteAllPaths();
GoToEditPathMenu();
}
if (selectedItem == directDriver)
if (selectedItem == DeleteAllPaths)
{
DirectDriver();
Utils.DeleteAllPaths.Delete();
DisableAllPaths.Checked = false;
BuildPathMenu();
Menu.Visible = true;
}
if (selectedItem == dismissDriver)
if (selectedItem == DirectDriver)
{
DismissDriver();
if(Utils.DirectDriver.ValidateOptions(DirectOptions, PathManager.Paths[DirectDriver.Index], out Vehicle nearbyVehicle, out Waypoint targetWaypoint))
{
Utils.DirectDriver.Direct(nearbyVehicle, PathManager.Paths[DirectDriver.Index], targetWaypoint);
}
}
if (selectedItem == DismissDriver)
{
Utils.DismissDriver.Dismiss(DismissDriver.Index);
}
}
private static void PathMenu_OnCheckboxChange(UIMenu sender, UIMenuCheckboxItem checkboxItem, bool @checked)
{
if (checkboxItem == disableAllPaths)
if (checkboxItem == DisableAllPaths)
{
DisableAllPaths();
TogglePaths.Toggle(DisableAllPaths.Checked);
}
}
private static void PathMenu_OnMenuOpen(UIMenu menu)
{
var scrollerItems = new List<UIMenuScrollerItem> { directOptions, directDriver, dismissDriver, editPath };
RNUIMouseInputHandler.Initialize(menu, scrollerItems);
var scrollerItems = new List<UIMenuScrollerItem> { DirectOptions, DirectDriver, DismissDriver, EditPath };
GameFiber.StartNew(() => UserInput.InitializeMenuMouseControl(menu, scrollerItems), "RNUI Mouse Input Fiber");
}
private static void GoToPathCreationMenu()
{
if (PathCreationMenu.PathCreationState == State.Creating)
{
Menu.Visible = false;
PathCreationMenu.Menu.Visible = true;
Path currentPath = PathManager.Paths.FirstOrDefault(x => x.State == State.Creating);
Game.DisplayNotification($"~o~Scene Manager~y~[Creating]\n~w~Resuming path {currentPath.Number}");
}
else
{
PathCreationMenu.BuildPathCreationMenu();
Menu.Visible = false;
PathCreationMenu.Menu.Visible = true;
}
}
private static void GoToImportMenu()
{
Menu.Visible = false;
ImportPathMenu.Menu.Visible = true;
}
private static void GoToEditPathMenu()
{
Menu.Visible = false;
EditPathMenu.Menu.Visible = true;
}
}
}

View file

@ -3,113 +3,67 @@ using RAGENativeUI;
using RAGENativeUI.Elements;
using System;
using System.Collections.Generic;
using SceneManager.Objects;
using SceneManager.Utils;
namespace SceneManager
namespace SceneManager.Menus
{
class SettingsMenu
{
internal static UIMenu settingsMenu = new UIMenu("Scene Manager", "~o~Plugin Settings");
internal static UIMenuCheckboxItem threeDWaypoints = new UIMenuCheckboxItem("Enable 3D Waypoints", Settings.Enable3DWaypoints),
mapBlips = new UIMenuCheckboxItem("Enable Map Blips", Settings.EnableMapBlips),
hints = new UIMenuCheckboxItem("Enable Hints", Settings.EnableHints);
private static SpeedUnits[] speedArray = {SpeedUnits.MPH, SpeedUnits.KPH };
internal static UIMenuListScrollerItem<SpeedUnits> speedUnits = new UIMenuListScrollerItem<SpeedUnits>("Speed Unit of Measure", "", new[] { SpeedUnits.MPH, SpeedUnits.KPH });
internal static UIMenuItem saveSettings = new UIMenuItem("Save settings to .ini", "Updates the plugin's .ini file with the current settings so the next time the plugin is loaded, it will use these settings.");
internal static UIMenu Menu { get; set; } = new UIMenu("Scene Manager", "~o~Plugin Settings");
internal static UIMenuCheckboxItem ThreeDWaypoints { get; } = new UIMenuCheckboxItem("Enable 3D Waypoints", Settings.Enable3DWaypoints);
internal static UIMenuCheckboxItem MapBlips { get; } = new UIMenuCheckboxItem("Enable Map Blips", Settings.EnableMapBlips);
internal static UIMenuCheckboxItem Hints { get; } = new UIMenuCheckboxItem("Enable Hints", Settings.EnableHints);
private static SpeedUnits[] SpeedUnitsArray { get; } = { Utils.SpeedUnits.MPH, Utils.SpeedUnits.KPH };
internal static UIMenuListScrollerItem<SpeedUnits> SpeedUnits { get; } = new UIMenuListScrollerItem<SpeedUnits>("Speed Unit of Measure", "", new[] { Utils.SpeedUnits.MPH, Utils.SpeedUnits.KPH });
internal static UIMenuItem SaveSettings { get; } = new UIMenuItem("Save settings to .ini", "Updates the plugin's .ini file with the current settings so the next time the plugin is loaded, it will use these settings.");
internal static void InstantiateMenu()
internal static void Initialize()
{
settingsMenu.ParentMenu = MainMenu.mainMenu;
MenuManager.menuPool.Add(settingsMenu);
settingsMenu.OnCheckboxChange += SettingsMenu_OnCheckboxChange;
settingsMenu.OnScrollerChange += SettingsMenu_OnScrollerChange;
settingsMenu.OnItemSelect += SettingsMenu_OnItemSelected;
settingsMenu.OnMenuOpen += SettingsMenu_OnMenuOpen;
Menu.ParentMenu = MainMenu.Menu;
MenuManager.AddToMenuPool(Menu);
Menu.OnCheckboxChange += SettingsMenu_OnCheckboxChange;
Menu.OnItemSelect += SettingsMenu_OnItemSelected;
Menu.OnMenuOpen += SettingsMenu_OnMenuOpen;
}
internal static void BuildSettingsMenu()
{
settingsMenu.AddItem(threeDWaypoints);
settingsMenu.AddItem(mapBlips);
settingsMenu.AddItem(hints);
settingsMenu.AddItem(speedUnits);
speedUnits.Index = Array.IndexOf(speedArray, Settings.SpeedUnit);
settingsMenu.AddItem(saveSettings);
saveSettings.ForeColor = System.Drawing.Color.Gold;
}
private static void ToggleMapBlips()
{
if (mapBlips.Checked)
{
foreach (Path path in PathMainMenu.paths)
{
foreach (Waypoint wp in path.Waypoints)
{
wp.EnableBlip();
}
}
}
else
{
foreach (Path path in PathMainMenu.paths)
{
foreach (Waypoint wp in path.Waypoints)
{
wp.DisableBlip();
}
}
}
}
private static void ToggleHints()
{
Hints.Enabled = hints.Checked ? true : false;
}
private static void ToggleSettings()
{
Settings.UpdateSettings(threeDWaypoints.Checked, mapBlips.Checked, hints.Checked, speedUnits.SelectedItem);
Game.DisplayHelp($"Scene Manager settings saved");
Menu.AddItem(ThreeDWaypoints);
Menu.AddItem(MapBlips);
Menu.AddItem(Hints);
Menu.AddItem(SpeedUnits);
SpeedUnits.Index = Array.IndexOf(SpeedUnitsArray, Settings.SpeedUnit);
Menu.AddItem(SaveSettings);
SaveSettings.ForeColor = System.Drawing.Color.Gold;
}
private static void SettingsMenu_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
{
if(selectedItem == saveSettings)
if(selectedItem == SaveSettings)
{
Settings.UpdateSettings(threeDWaypoints.Checked, mapBlips.Checked, hints.Checked, speedUnits.SelectedItem);
Settings.UpdateSettings(ThreeDWaypoints.Checked, MapBlips.Checked, Hints.Checked, SpeedUnits.SelectedItem);
Game.DisplayHelp($"Scene Manager settings saved");
}
}
private static void SettingsMenu_OnCheckboxChange(UIMenu sender, UIMenuCheckboxItem checkboxItem, bool @checked)
{
if (checkboxItem == mapBlips)
if (checkboxItem == MapBlips)
{
ToggleMapBlips();
PathManager.ToggleBlips(MapBlips.Checked);
}
if (checkboxItem == hints)
if (checkboxItem == Hints)
{
Hints.Enabled = hints.Checked ? true : false;
}
}
private static void SettingsMenu_OnScrollerChange(UIMenu sender, UIMenuScrollerItem scrollerItem, int oldIndex, int newIndex)
{
if (scrollerItem == speedUnits)
{
// Clear the menu and rebuild it to reflect the menu item text change
PathCreationMenu.pathCreationMenu.Clear();
PathCreationMenu.BuildPathCreationMenu();
SceneManager.Hints.Enabled = Hints.Checked ? true : false;
}
}
private static void SettingsMenu_OnMenuOpen(UIMenu menu)
{
var scrollerItems = new List<UIMenuScrollerItem> { speedUnits };
RNUIMouseInputHandler.Initialize(menu, scrollerItems);
var scrollerItems = new List<UIMenuScrollerItem> { SpeedUnits };
GameFiber.StartNew(() => UserInput.InitializeMenuMouseControl(menu, scrollerItems), "RNUI Mouse Input Fiber");
}
}
}