mirror of
https://github.com/thegeneralist01/Scene-Manager-DevRepo
synced 2026-01-11 23:50:29 +01:00
Merge V2.1.1 release (#3)
* Mouse can now be used to fully navigate menus * Added check for driver's current vehicle when releasing from Stop waypoint in case the ped is not in a vehicle. * Lines are now only drawn between waypoint markers under the same conditions that waypoint markers are drawn * Updated marker position to be player's mouse position * Version update * Added logic to update waypoint position during driving task if the waypoint position was changed before the driver arrived. * Removed unused usings. Refactored debug statements to use Game.LogTrivial instead of Logger.Log * Removed class * Removed Logger class * Consolidated all custom enums to this class. Added default waypoint settings from .ini * Modified a hint message * Fixed collector options not being enabled/disabled when Collector box is checked * Refactored AITasking into CollectedVehicle. * Updated reference to vehicle tasking based on AITasking refactor. Fixed speed zone radius not updating correctly. * Version update * Refactored AITasking into CollectedVehicle * Added check for CollectorRadius being more than SpeedZoneRadius. Added debug messages when values are reset to default. * Added hint message if player tries to edit waypoints while 3D waypoints are disabled * Fixed a bug where a 3D waypoint marker would be drawn even if 3D waypoints were disabled * Removed unnecessary property setting when a vehicle is being removed from a path. * Added a check for if the driver loses their task and reassigns it. * Fixed a bug where the 3D line between waypoints was still being drawn even though 3D waypoints were disabled in the settings menu. * Updated version * Added console command to show info about collected vehicles. * Added ConsoleCommand class, removed AITasking class. * Removed class after refactoring into CollectedVehicle * Update README.md * Update README.md * Added ini setting for Advanced Barrier Options. Added enum for TrafficLight state. Added debug message for invalid barriers. * Updated version * Added MousePositionInWorld and RNUIMouseInputHandler classes * Fixed a crash when a collected ped is arrested. * Refactored to implement RNUIMouseInputHandler class. * Removed unused method. * Updated version * Disabled deletion/creation of shadow barrier and re-enabled updating position based on mouse position. * Added check for Driver's current vehicle in driving loop in case the Driver exited Vehicle at some point. Adjusted some guard clause logic and log messages. * Removed unused variable * Renamed some methods to improve clarity * Updated version.
This commit is contained in:
parent
d73ae601e7
commit
8bc4de3528
21 changed files with 1818 additions and 1083 deletions
|
|
@ -4,6 +4,9 @@
|
|||
Drag and drop the contents from within the downloaded GTA V folder into where your GTA V is installed.
|
||||

|
||||
|
||||
## GET SUPPORT AND REPORT PROBLEMS
|
||||
For the fastest support, [join my Discord](https://discord.gg/cUQaTNQ) and ask your question in the **correct category/channel**. For slower support, [use this thread on the LSPDFR forums](https://www.lcpdfr.com/forums/topic/107730-richs-plugin-support-thread/).
|
||||
|
||||
## HOW TO USE SCENE MANAGER
|
||||
### Using the Menus:
|
||||
Menu options with gold colored text are selectable, which means when you select these menu items, something will happen (opening a new menu, adding a waypoint, placing a barrier, etc). Menu options with white colored text are interactable (can be scrolled through, for example), but nothing will happen if you try to select them.
|
||||
|
|
|
|||
|
|
@ -1,232 +0,0 @@
|
|||
using Rage;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace SceneManager
|
||||
{
|
||||
// Driving styles https://gtaforums.com/topic/822314-guide-driving-styles/
|
||||
// also https://vespura.com/fivem/drivingstyle/
|
||||
|
||||
class AITasking
|
||||
{
|
||||
internal static void AssignWaypointTasks(CollectedVehicle collectedVehicle, Path path, Waypoint currentWaypoint)
|
||||
{
|
||||
if (!VehicleAndDriverAreValid(collectedVehicle))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
collectedVehicle.Path = path;
|
||||
if(currentWaypoint != null)
|
||||
{
|
||||
collectedVehicle.CurrentWaypoint = currentWaypoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
collectedVehicle.CurrentWaypoint = path.Waypoints[0];
|
||||
}
|
||||
|
||||
if (currentWaypoint != null && collectedVehicle.Directed)
|
||||
{
|
||||
collectedVehicle.Dismissed = false;
|
||||
float acceptedDistance = GetAcceptedStoppingDistance(path.Waypoints, path.Waypoints.IndexOf(currentWaypoint));
|
||||
while (!collectedVehicle.ReadyForDirectTasks)
|
||||
{
|
||||
GameFiber.Yield();
|
||||
}
|
||||
collectedVehicle.Driver.Tasks.Clear();
|
||||
AssignTasksForDirectedDriver(acceptedDistance);
|
||||
LoopWhileDrivingToDirectedWaypoint(acceptedDistance);
|
||||
if(collectedVehicle != null)
|
||||
{
|
||||
collectedVehicle.Directed = false;
|
||||
}
|
||||
if (collectedVehicle.Vehicle)
|
||||
{
|
||||
collectedVehicle.Driver.Tasks.PerformDrivingManeuver(collectedVehicle.Vehicle, VehicleManeuver.GoForwardWithCustomSteeringAngle, 3).WaitForCompletion();
|
||||
Logger.Log($"{collectedVehicle.Vehicle.Model.Name} directed task is complete, directed is now false");
|
||||
}
|
||||
}
|
||||
|
||||
if (currentWaypoint.IsStopWaypoint)
|
||||
{
|
||||
StopVehicleAtWaypoint(currentWaypoint, collectedVehicle);
|
||||
}
|
||||
if(path?.Waypoints?.Count > 0 && currentWaypoint != path?.Waypoints?.Last())
|
||||
{
|
||||
DriveVehicleToNextWaypoint(collectedVehicle, path, currentWaypoint);
|
||||
}
|
||||
|
||||
if (!VehicleAndDriverAreValid(collectedVehicle) || collectedVehicle.Directed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Logger.Log($"{collectedVehicle.Vehicle.Model.Name} all Path {path.Number} tasks complete.");
|
||||
if(!collectedVehicle.Dismissed)
|
||||
{
|
||||
collectedVehicle.Dismiss();
|
||||
}
|
||||
|
||||
void AssignTasksForDirectedDriver(float acceptedDistance)
|
||||
{
|
||||
//Logger.Log($"{collectedVehicle.Vehicle.Model.Name} distance to collection waypoint: {collectedVehicle.Vehicle.DistanceTo2D(currentWaypoint.Position)}");
|
||||
|
||||
Logger.Log($"{collectedVehicle.Vehicle.Model.Name} is driving to path {currentWaypoint.Path.Number} waypoint {currentWaypoint.Number} (directed)");
|
||||
//Logger.Log($"{collectedVehicle.Vehicle.Model.Name} Dismissed: {collectedVehicle.Dismissed}, Directed: {collectedVehicle.Directed}");
|
||||
collectedVehicle.Driver.Tasks.DriveToPosition(currentWaypoint.Position, currentWaypoint.Speed, (VehicleDrivingFlags)currentWaypoint.DrivingFlagType, acceptedDistance);
|
||||
}
|
||||
|
||||
void LoopWhileDrivingToDirectedWaypoint(float acceptedDistance)
|
||||
{
|
||||
while (VehicleAndDriverAreValid(collectedVehicle) && !collectedVehicle.Dismissed && !collectedVehicle.SkipWaypoint && collectedVehicle.Vehicle.FrontPosition.DistanceTo2D(currentWaypoint.Position) > acceptedDistance)
|
||||
{
|
||||
//Logger.Log($"Looping while {collectedVehicle.Vehicle.Model.Name} drives to path {path.Number} waypoint {currentWaypoint.Number}");
|
||||
GameFiber.Yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void DriveVehicleToNextWaypoint(CollectedVehicle collectedVehicle, Path path, Waypoint currentWaypoint)
|
||||
{
|
||||
if (!VehicleAndDriverAreValid(collectedVehicle) || currentWaypoint == null || currentWaypoint.Path == null)
|
||||
{
|
||||
Logger.Log($"Vehicle, driver, waypoint, or path is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
var vehicle = collectedVehicle.Vehicle;
|
||||
var driver = vehicle.Driver;
|
||||
|
||||
Logger.Log($"Preparing to run task loop for {collectedVehicle.Vehicle.Model.Name} on path {path.Number}");
|
||||
//Logger.Log($"Current path: {collectedVehicle.Path.Number}, Current waypoint: {collectedVehicle.CurrentWaypoint.Number}");
|
||||
for (int currentWaypointTask = currentWaypoint.Number; currentWaypointTask < path.Waypoints.Count; currentWaypointTask++)
|
||||
{
|
||||
//Logger.Log($"{collectedVehicle.Vehicle.Model.Name} in the task loop");
|
||||
//Logger.Log($"Dismissed: {collectedVehicle.Dismissed}, Directed: {collectedVehicle.Directed}, StoppedAtWaypoint: {collectedVehicle.StoppedAtWaypoint}");
|
||||
collectedVehicle.SkipWaypoint = false;
|
||||
|
||||
if (collectedVehicle == null || !collectedVehicle.Vehicle || collectedVehicle.Dismissed || collectedVehicle.Directed)
|
||||
{
|
||||
Logger.Log($"Vehicle dismissed, directed, or null, return");
|
||||
return;
|
||||
}
|
||||
if(collectedVehicle.Driver == null || !collectedVehicle.Driver || !collectedVehicle.Vehicle.HasDriver || !collectedVehicle.Driver.IsAlive || collectedVehicle.Vehicle.Driver == Game.LocalPlayer.Character)
|
||||
{
|
||||
Logger.Log($"{vehicle.Model.Name} does not have a driver/driver is null or driver is dead.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (path.Waypoints.ElementAtOrDefault(currentWaypointTask) != null && !collectedVehicle.StoppedAtWaypoint)
|
||||
{
|
||||
collectedVehicle.CurrentWaypoint = path.Waypoints[currentWaypointTask];
|
||||
//Logger.Log($"{collectedVehicle.Vehicle.Model.Name} current waypoint: {collectedVehicle.CurrentWaypoint.Number}");
|
||||
float acceptedDistance = GetAcceptedStoppingDistance(path.Waypoints, currentWaypointTask);
|
||||
|
||||
Logger.Log($"{vehicle.Model.Name} is driving to path {currentWaypoint.Path.Number} waypoint {path.Waypoints[currentWaypointTask].Number} (Stop: {currentWaypoint.IsStopWaypoint}, Driving flag: {currentWaypoint.DrivingFlagType})");
|
||||
//Logger.Log($"{vehicle.Model.Name} driver is persistent: {driver.IsPersistent}");
|
||||
driver.Tasks.DriveToPosition(path.Waypoints[currentWaypointTask].Position, path.Waypoints[currentWaypointTask].Speed, (VehicleDrivingFlags)path.Waypoints[currentWaypointTask].DrivingFlagType, acceptedDistance);
|
||||
LoopWhileDrivingToWaypoint(currentWaypointTask, acceptedDistance);
|
||||
|
||||
if (!VehicleAndDriverAreValid(collectedVehicle))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (collectedVehicle.SkipWaypoint)
|
||||
{
|
||||
collectedVehicle.SkipWaypoint = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!collectedVehicle.Dismissed && !collectedVehicle.Directed && path.Waypoints.ElementAtOrDefault(currentWaypointTask) != null && path.Waypoints[currentWaypointTask].IsStopWaypoint)
|
||||
{
|
||||
StopVehicleAtWaypoint(path.Waypoints[currentWaypointTask], collectedVehicle);
|
||||
}
|
||||
|
||||
if (!VehicleAndDriverAreValid(collectedVehicle) || collectedVehicle.Dismissed || collectedVehicle.Directed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
driver.Tasks.PerformDrivingManeuver(collectedVehicle.Vehicle, VehicleManeuver.GoForwardWithCustomSteeringAngle, 3).WaitForCompletion();
|
||||
// Do we need this?
|
||||
if (driver)
|
||||
{
|
||||
driver.Tasks.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoopWhileDrivingToWaypoint(int nextWaypoint, float acceptedDistance)
|
||||
{
|
||||
while (VehicleAndDriverAreValid(collectedVehicle) && !collectedVehicle.Dismissed && !collectedVehicle.SkipWaypoint && !collectedVehicle.Directed && path.Waypoints.ElementAtOrDefault(nextWaypoint) != null && collectedVehicle.Vehicle.FrontPosition.DistanceTo2D(path.Waypoints[nextWaypoint].Position) > acceptedDistance)
|
||||
{
|
||||
//Logger.Log($"Looping while {vehicle.Model.Name} drives to waypoint.");
|
||||
GameFiber.Sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static float GetAcceptedStoppingDistance(List<Waypoint> waypoints, int nextWaypoint)
|
||||
{
|
||||
float dist;
|
||||
if(Settings.SpeedUnit == SpeedUnits.MPH)
|
||||
{
|
||||
dist = (MathHelper.ConvertMilesPerHourToKilometersPerHour(waypoints[nextWaypoint].Speed) * MathHelper.ConvertMilesPerHourToKilometersPerHour(waypoints[nextWaypoint].Speed)) / (250 * 0.8f);
|
||||
}
|
||||
else
|
||||
{
|
||||
dist = (waypoints[nextWaypoint].Speed * waypoints[nextWaypoint].Speed) / (250 * 0.8f);
|
||||
}
|
||||
var acceptedDistance = MathHelper.Clamp(dist, 2, 10);
|
||||
//Logger.Log($"Accepted distance: {acceptedDistance}");
|
||||
return acceptedDistance;
|
||||
}
|
||||
|
||||
private static bool VehicleAndDriverAreValid(CollectedVehicle collectedVehicle)
|
||||
{
|
||||
if (collectedVehicle == null)
|
||||
{
|
||||
Logger.Log($"CollectedVehicle is null");
|
||||
return false;
|
||||
}
|
||||
if (!collectedVehicle.Vehicle && !collectedVehicle.Dismissed)
|
||||
{
|
||||
Logger.Log($"Vehicle is null");
|
||||
collectedVehicle.Dismiss();
|
||||
return false;
|
||||
}
|
||||
if (collectedVehicle.Driver == null || !collectedVehicle.Driver || !collectedVehicle.Driver.IsAlive && !collectedVehicle.Dismissed)
|
||||
{
|
||||
collectedVehicle.Dismiss();
|
||||
//Logger.Log($"{collectedVehicle.Vehicle.Model.Name} driver is null or dead");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void StopVehicleAtWaypoint(Waypoint currentWaypoint, CollectedVehicle collectedVehicle)
|
||||
{
|
||||
if (!VehicleAndDriverAreValid(collectedVehicle))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var stoppingDistance = GetAcceptedStoppingDistance(currentWaypoint.Path.Waypoints, currentWaypoint.Path.Waypoints.IndexOf(currentWaypoint));
|
||||
Logger.Log($"{collectedVehicle.Vehicle.Model.Name} stopping at path {currentWaypoint.Path.Number} waypoint.");
|
||||
Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(collectedVehicle.Vehicle, stoppingDistance, -1, true);
|
||||
collectedVehicle.StoppedAtWaypoint = true;
|
||||
|
||||
while (currentWaypoint != null && VehicleAndDriverAreValid(collectedVehicle) && collectedVehicle.StoppedAtWaypoint && !collectedVehicle.Directed)
|
||||
{
|
||||
GameFiber.Yield();
|
||||
}
|
||||
if(collectedVehicle.Vehicle && collectedVehicle.Driver)
|
||||
{
|
||||
Logger.Log($"{collectedVehicle.Vehicle.Model.Name} releasing from stop waypoint.");
|
||||
Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(collectedVehicle.Vehicle, 0f, 1, true);
|
||||
collectedVehicle.Driver.Tasks.CruiseWithVehicle(5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
34
SceneManager/ConsoleCommands.cs
Normal file
34
SceneManager/ConsoleCommands.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
using Rage;
|
||||
using Rage.Attributes;
|
||||
using Rage.ConsoleCommands.AutoCompleters;
|
||||
using System.Linq;
|
||||
|
||||
namespace SceneManager
|
||||
{
|
||||
internal static class ConsoleCommands
|
||||
{
|
||||
[ConsoleCommand]
|
||||
internal static void Command_ShowCollectedVehicleInfo([ConsoleCommandParameter(AutoCompleterType = typeof(ConsoleCommandAutoCompleterVehicle))] 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}]");
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
using System.ComponentModel.Design.Serialization;
|
||||
using System.Drawing.Text;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
|
@ -36,7 +34,7 @@ namespace SceneManager
|
|||
void GetAssemblyVersion()
|
||||
{
|
||||
string version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
||||
Logger.Log($"Scene Manager V{version} is ready.");
|
||||
Game.LogTrivial($"Scene Manager V{version} is ready.");
|
||||
}
|
||||
}
|
||||
private static bool CheckRNUIVersion()
|
||||
|
|
@ -45,7 +43,7 @@ namespace SceneManager
|
|||
var exists = File.Exists(directory + @"\RAGENativeUI.dll");
|
||||
if (!exists)
|
||||
{
|
||||
Logger.Log($"RNUI was not found in the user's GTA V directory.");
|
||||
Game.LogTrivial($"RNUI was not found in the user's GTA V directory.");
|
||||
Game.DisplayNotification($"~o~Scene Manager ~r~[Error]\n~w~RAGENativeUI.dll was not found in your GTA V directory. Please install RAGENativeUI and try again.");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -54,7 +52,7 @@ namespace SceneManager
|
|||
Version requiredMinimumVersion = new Version("1.7.0.0");
|
||||
if(userVersion >= requiredMinimumVersion)
|
||||
{
|
||||
Logger.Log($"User's RNUI version: {userVersion}");
|
||||
Game.LogTrivial($"User's RNUI version: {userVersion}");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
@ -83,7 +81,6 @@ namespace SceneManager
|
|||
Hints.Display($"~o~Scene Manager ~y~[Hint]\n~w~To open the menu, press the ~b~{Settings.ModifierKey} ~w~+ ~b~{Settings.ToggleKey} keys ~w~or ~b~{Settings.ModifierButton} ~w~+ ~b~{Settings.ToggleButton} buttons");
|
||||
}
|
||||
}
|
||||
|
||||
private static void MyTerminationHandler(object sender, EventArgs e)
|
||||
{
|
||||
// Clean up cones
|
||||
|
|
@ -102,11 +99,7 @@ namespace SceneManager
|
|||
PathMainMenu.DeletePath(PathMainMenu.paths[i], PathMainMenu.Delete.All);
|
||||
}
|
||||
|
||||
// Clear everything
|
||||
BarrierMenu.barriers.Clear();
|
||||
PathMainMenu.paths.Clear();
|
||||
|
||||
Logger.Log($"Plugin has shut down.");
|
||||
Game.LogTrivial($"Plugin has shut down.");
|
||||
Game.DisplayNotification($"~o~Scene Manager ~r~[Terminated]\n~w~The plugin has shut down.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
using Rage;
|
||||
|
||||
namespace SceneManager
|
||||
{
|
||||
class Logger
|
||||
{
|
||||
internal static void Log(string message)
|
||||
{
|
||||
#if DEBUG
|
||||
Game.LogTrivialDebug($"{message}");
|
||||
#else
|
||||
Game.LogTrivial($"{message}");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,93 +9,145 @@ namespace SceneManager
|
|||
{
|
||||
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.barrierKeys);
|
||||
private static UIMenuNumericScrollerItem<int> rotateBarrier = new UIMenuNumericScrollerItem<int>("Rotate Barrier", "", 0, 350, 10);
|
||||
private static UIMenuCheckboxItem invincible = new UIMenuCheckboxItem("Indestructible", false);
|
||||
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 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 Rage.Object shadowBarrier;
|
||||
internal static Object shadowBarrier;
|
||||
|
||||
internal static void InstantiateMenu()
|
||||
{
|
||||
barrierMenu.ParentMenu = MainMenu.mainMenu;
|
||||
MenuManager.menuPool.Add(barrierMenu);
|
||||
|
||||
barrierMenu.OnItemSelect += BarrierMenu_OnItemSelected;
|
||||
barrierMenu.OnScrollerChange += BarrierMenu_OnScrollerChanged;
|
||||
barrierMenu.OnCheckboxChange += BarrierMenu_OnCheckboxChanged;
|
||||
barrierMenu.OnMenuOpen += BarrierMenu_OnMenuOpen;
|
||||
}
|
||||
|
||||
internal static void BuildBarrierMenu()
|
||||
{
|
||||
barrierMenu.AddItem(resetBarriers);
|
||||
resetBarriers.ForeColor = Color.Gold;
|
||||
resetBarriers.Enabled = false;
|
||||
barrierMenu.AddItem(barrierList);
|
||||
barrierList.ForeColor = Color.Gold;
|
||||
|
||||
barrierMenu.AddItem(removeBarrierOptions, 0);
|
||||
barrierMenu.AddItem(rotateBarrier);
|
||||
|
||||
barrierMenu.AddItem(invincible);
|
||||
|
||||
if (Settings.EnableAdvancedBarricadeOptions)
|
||||
{
|
||||
barrierMenu.AddItem(barrierTexture);
|
||||
barrierTexture.Index = 0;
|
||||
|
||||
barrierMenu.AddItem(setBarrierLights);
|
||||
|
||||
barrierMenu.AddItem(setBarrierTrafficLight);
|
||||
setBarrierTrafficLight.Index = 3;
|
||||
}
|
||||
|
||||
barrierMenu.AddItem(removeBarrierOptions);
|
||||
removeBarrierOptions.ForeColor = Color.Gold;
|
||||
removeBarrierOptions.Enabled = false;
|
||||
|
||||
barrierMenu.AddItem(rotateBarrier, 0);
|
||||
|
||||
barrierMenu.AddItem(barrierList, 0);
|
||||
barrierList.ForeColor = Color.Gold;
|
||||
|
||||
barrierMenu.OnItemSelect += BarrierMenu_OnItemSelected;
|
||||
barrierMenu.OnScrollerChange += BarrierMenu_OnScrollerChange;
|
||||
barrierMenu.AddItem(resetBarriers);
|
||||
resetBarriers.ForeColor = Color.Gold;
|
||||
resetBarriers.Enabled = false;
|
||||
}
|
||||
|
||||
internal static void CreateShadowBarrier(UIMenu barrierMenu)
|
||||
internal static void CreateShadowBarrier()
|
||||
{
|
||||
Hints.Display($"~o~Scene Manager ~y~[Hint]\n~y~ ~w~The shadow cone will disappear if you aim too far away.");
|
||||
|
||||
if (shadowBarrier)
|
||||
{
|
||||
shadowBarrier.Delete();
|
||||
}
|
||||
|
||||
shadowBarrier = new Rage.Object(Settings.barrierValues[barrierList.Index], TracePlayerView(Settings.BarrierPlacementDistance, TraceFlags.IntersectWorld).HitPosition, rotateBarrier.Value);
|
||||
shadowBarrier = new Object(Settings.barrierValues[barrierList.Index], MousePositionInWorld.GetPosition, rotateBarrier.Value);
|
||||
if (!shadowBarrier)
|
||||
{
|
||||
barrierMenu.Close();
|
||||
Game.DisplayNotification($"~o~Scene Manager ~red~[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;
|
||||
}
|
||||
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;
|
||||
|
||||
GameFiber ShadowConeLoopFiber = new GameFiber(() => LoopToDisplayShadowBarrier());
|
||||
ShadowConeLoopFiber.Start();
|
||||
// Start with lights off for Parks's objects
|
||||
if (Settings.EnableAdvancedBarricadeOptions)
|
||||
{
|
||||
Rage.Native.NativeFunction.Natives.x971DA0055324D033(shadowBarrier, barrierTexture.Value);
|
||||
SetBarrierLights();
|
||||
}
|
||||
}
|
||||
|
||||
void LoopToDisplayShadowBarrier()
|
||||
private static void LoopToDisplayShadowBarrier()
|
||||
{
|
||||
while (barrierMenu.Visible && shadowBarrier)
|
||||
while (barrierMenu.Visible)
|
||||
{
|
||||
if (barrierList.Selected || rotateBarrier.Selected)
|
||||
if (barrierList.Selected || rotateBarrier.Selected || invincible.Selected || barrierTexture.Selected || setBarrierLights.Selected || setBarrierTrafficLight.Selected)
|
||||
{
|
||||
if (shadowBarrier)
|
||||
{
|
||||
shadowBarrier.IsVisible = true;
|
||||
UpdateShadowBarrierPosition();
|
||||
}
|
||||
else if(MousePositionInWorld.GetPositionForBarrier.DistanceTo2D(Game.LocalPlayer.Character.Position) <= Settings.BarrierPlacementDistance)
|
||||
{
|
||||
CreateShadowBarrier();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shadowBarrier.IsVisible = false;
|
||||
if (shadowBarrier)
|
||||
{
|
||||
shadowBarrier.Delete();
|
||||
}
|
||||
}
|
||||
GameFiber.Yield();
|
||||
}
|
||||
|
||||
if (shadowBarrier)
|
||||
{
|
||||
shadowBarrier.Delete();
|
||||
}
|
||||
|
||||
void UpdateShadowBarrierPosition()
|
||||
{
|
||||
DisableBarrierMenuOptionsIfShadowConeTooFar();
|
||||
shadowBarrier.SetPositionWithSnap(TracePlayerView(Settings.BarrierPlacementDistance, TraceFlags.IntersectWorld).HitPosition);
|
||||
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.Position.DistanceTo2D(Game.LocalPlayer.Character.Position) > Settings.BarrierPlacementDistance)
|
||||
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.Position.DistanceTo2D(Game.LocalPlayer.Character.Position) <= Settings.BarrierPlacementDistance && barrierList.SelectedItem == "Flare")
|
||||
else if (shadowBarrier && shadowBarrier.Position.DistanceTo2D(Game.LocalPlayer.Character.Position) <= Settings.BarrierPlacementDistance && barrierList.SelectedItem == "Flare")
|
||||
{
|
||||
barrierList.Enabled = true;
|
||||
rotateBarrier.Enabled = false;
|
||||
|
|
@ -109,114 +161,46 @@ namespace SceneManager
|
|||
}
|
||||
}
|
||||
|
||||
//------------ CREDIT PNWPARKS FOR THESE FUNCTIONS ------------\\
|
||||
// Implement Parks's 'Get Point Player is Looking At' script for better placement in 3rd person https://bitbucket.org/snippets/gtaparks/MeBKxX
|
||||
|
||||
HitResult TracePlayerView(float maxTraceDistance = 30f, 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)
|
||||
private static void SpawnBarrier()
|
||||
{
|
||||
Vector3 direction = GetPlayerLookingDirection(out start);
|
||||
end = start + (maxTraceDistance * direction);
|
||||
var barrierObjects = barriers.Where(b => b.Object).Select(b => b.Object).ToArray();
|
||||
return World.TraceLine(start, end, flags, barrierObjects);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
//------------ CREDIT PNWPARKS FOR THESE FUNCTIONS ------------\\
|
||||
}
|
||||
|
||||
private static void BarrierMenu_OnScrollerChange(UIMenu sender, UIMenuScrollerItem scrollerItem, int oldIndex, int newIndex)
|
||||
{
|
||||
if (scrollerItem == barrierList)
|
||||
{
|
||||
CreateShadowBarrier(barrierMenu);
|
||||
|
||||
if(barrierList.SelectedItem == "Flare")
|
||||
{
|
||||
rotateBarrier.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotateBarrier.Enabled = true;
|
||||
}
|
||||
|
||||
barrierMenu.Width = SetMenuWidth();
|
||||
}
|
||||
|
||||
if (scrollerItem == rotateBarrier)
|
||||
{
|
||||
shadowBarrier.Heading = rotateBarrier.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private static void BarrierMenu_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
|
||||
{
|
||||
if (selectedItem == barrierList as UIMenuItem)
|
||||
{
|
||||
// Attach some invisible object to the cone which the AI try to drive around
|
||||
// Barrier rotates with cone and becomes invisible similar to ASC when created
|
||||
if(barrierList.SelectedItem == "Flare")
|
||||
{
|
||||
SpawnFlare();
|
||||
}
|
||||
else
|
||||
{
|
||||
SpawnBarrier();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (selectedItem == removeBarrierOptions as UIMenuItem)
|
||||
{
|
||||
RemoveBarrier();
|
||||
}
|
||||
|
||||
if (selectedItem == resetBarriers)
|
||||
{
|
||||
var currentBarriers = barriers.Where(b => b.Model.Name != "0xa2c44e80").ToList(); // 0xa2c44e80 is the flare weapon hash
|
||||
foreach (Barrier barrier in currentBarriers)
|
||||
{
|
||||
var newBarrier = new Rage.Object(barrier.Model, barrier.Position, barrier.Rotation);
|
||||
newBarrier.SetPositionWithSnap(barrier.Position);
|
||||
Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(newBarrier, true);
|
||||
newBarrier.IsPositionFrozen = false;
|
||||
Rage.Native.NativeFunction.Natives.SET_DISABLE_FRAG_DAMAGE(newBarrier, true);
|
||||
barriers.Add(new Barrier(newBarrier, newBarrier.Position, newBarrier.Heading));
|
||||
|
||||
|
||||
if (barrier.Object)
|
||||
{
|
||||
barrier.Object.Delete();
|
||||
}
|
||||
barriers.Remove(barrier);
|
||||
}
|
||||
currentBarriers.Clear();
|
||||
}
|
||||
|
||||
void SpawnBarrier()
|
||||
{
|
||||
var barrier = new Rage.Object(shadowBarrier.Model, shadowBarrier.Position, rotateBarrier.Value);
|
||||
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);
|
||||
if(barrier.Model.Name != "prop_barrier_wat_03a")
|
||||
{
|
||||
Rage.Native.NativeFunction.Natives.SET_DISABLE_BREAKING(barrier, true);
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
barrier.IsPositionFrozen = false;
|
||||
}
|
||||
}
|
||||
barriers.Add(new Barrier(barrier, barrier.Position, barrier.Heading));
|
||||
removeBarrierOptions.Enabled = true;
|
||||
resetBarriers.Enabled = true;
|
||||
|
|
@ -225,8 +209,8 @@ namespace SceneManager
|
|||
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)
|
||||
|
|
@ -243,8 +227,16 @@ namespace SceneManager
|
|||
barriers.Add(new Barrier(flare, flare.Position, flare.Heading));
|
||||
removeBarrierOptions.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveBarrier()
|
||||
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)
|
||||
{
|
||||
|
|
@ -275,12 +267,137 @@ namespace SceneManager
|
|||
removeBarrierOptions.Enabled = barriers.Count == 0 ? false : true;
|
||||
resetBarriers.Enabled = barriers.Count == 0 ? false : true;
|
||||
}
|
||||
|
||||
private static void ResetBarriers()
|
||||
{
|
||||
var currentBarriers = barriers.Where(b => b.Model.Name != "0xa2c44e80").ToList(); // 0xa2c44e80 is the flare weapon hash
|
||||
foreach (Barrier barrier in currentBarriers)
|
||||
{
|
||||
var newBarrier = new Rage.Object(barrier.Model, barrier.Position, barrier.Rotation);
|
||||
newBarrier.SetPositionWithSnap(barrier.Position);
|
||||
Rage.Native.NativeFunction.Natives.SET_ENTITY_DYNAMIC(newBarrier, true);
|
||||
newBarrier.IsPositionFrozen = false;
|
||||
Rage.Native.NativeFunction.Natives.SET_DISABLE_FRAG_DAMAGE(newBarrier, true);
|
||||
Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(newBarrier, setBarrierTrafficLight.Index);
|
||||
newBarrier.IsPositionFrozen = true;
|
||||
GameFiber.Sleep(50);
|
||||
if (newBarrier)
|
||||
{
|
||||
newBarrier.IsPositionFrozen = false;
|
||||
}
|
||||
barriers.Add(new Barrier(newBarrier, newBarrier.Position, newBarrier.Heading));
|
||||
|
||||
|
||||
if (barrier.Object)
|
||||
{
|
||||
barrier.Object.Delete();
|
||||
}
|
||||
barriers.Remove(barrier);
|
||||
}
|
||||
currentBarriers.Clear();
|
||||
}
|
||||
|
||||
private static float SetMenuWidth()
|
||||
private static void SetBarrierLights()
|
||||
{
|
||||
if (setBarrierLights.Checked)
|
||||
{
|
||||
Rage.Native.NativeFunction.Natives.SET_ENTITY_LIGHTS(shadowBarrier, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rage.Native.NativeFunction.Natives.SET_ENTITY_LIGHTS(shadowBarrier, true);
|
||||
}
|
||||
|
||||
Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index);
|
||||
}
|
||||
|
||||
private static void BarrierMenu_OnCheckboxChanged(UIMenu sender, UIMenuCheckboxItem checkbox, bool @checked)
|
||||
{
|
||||
if(checkbox == setBarrierLights)
|
||||
{
|
||||
SetBarrierLights();
|
||||
}
|
||||
}
|
||||
|
||||
private static void BarrierMenu_OnScrollerChanged(UIMenu sender, UIMenuScrollerItem scrollerItem, int oldIndex, int newIndex)
|
||||
{
|
||||
if (scrollerItem == barrierList)
|
||||
{
|
||||
if (shadowBarrier)
|
||||
{
|
||||
shadowBarrier.Delete();
|
||||
}
|
||||
barrierTexture.Index = 0;
|
||||
|
||||
if(barrierList.SelectedItem == "Flare")
|
||||
{
|
||||
rotateBarrier.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotateBarrier.Enabled = true;
|
||||
}
|
||||
|
||||
barrierMenu.Width = SetMenuWidth();
|
||||
}
|
||||
|
||||
if (scrollerItem == barrierTexture)
|
||||
{
|
||||
Rage.Native.NativeFunction.Natives.x971DA0055324D033(shadowBarrier, barrierTexture.Value);
|
||||
}
|
||||
|
||||
if (scrollerItem == setBarrierTrafficLight)
|
||||
{
|
||||
Rage.Native.NativeFunction.Natives.SET_ENTITY_TRAFFICLIGHT_OVERRIDE(shadowBarrier, setBarrierTrafficLight.Index);
|
||||
}
|
||||
|
||||
if (scrollerItem == rotateBarrier)
|
||||
{
|
||||
RotateBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
private static void BarrierMenu_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
|
||||
{
|
||||
if (selectedItem == barrierList)
|
||||
{
|
||||
SpawnBarrier();
|
||||
}
|
||||
|
||||
if (selectedItem == removeBarrierOptions)
|
||||
{
|
||||
RemoveBarrier();
|
||||
}
|
||||
|
||||
if (selectedItem == resetBarriers)
|
||||
{
|
||||
ResetBarriers();
|
||||
}
|
||||
}
|
||||
|
||||
private static void BarrierMenu_OnMenuOpen(UIMenu menu)
|
||||
{
|
||||
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.");
|
||||
CreateShadowBarrier();
|
||||
|
||||
GameFiber ShadowConeLoopFiber = new GameFiber(() => LoopToDisplayShadowBarrier());
|
||||
ShadowConeLoopFiber.Start();
|
||||
|
||||
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems);
|
||||
}
|
||||
|
||||
internal static float SetMenuWidth()
|
||||
{
|
||||
float defaultWidth = UIMenu.DefaultWidth;
|
||||
float width = barrierMenu.Width;
|
||||
|
||||
barrierList.TextStyle.Apply();
|
||||
Rage.Native.NativeFunction.Natives.x54CE8AC98E120CAB("STRING"); // _BEGIN_TEXT_COMMAND_GET_WIDTH
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
using System.Drawing;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using Rage;
|
||||
using RAGENativeUI;
|
||||
using RAGENativeUI.Elements;
|
||||
|
|
@ -15,6 +18,9 @@ namespace SceneManager
|
|||
{
|
||||
editPathMenu.ParentMenu = PathMainMenu.pathMainMenu;
|
||||
MenuManager.menuPool.Add(editPathMenu);
|
||||
editPathMenu.OnItemSelect += EditPath_OnItemSelected;
|
||||
editPathMenu.OnCheckboxChange += EditPath_OnCheckboxChange;
|
||||
editPathMenu.OnMenuOpen += EditPath_OnMenuOpen;
|
||||
}
|
||||
|
||||
internal static void BuildEditPathMenu()
|
||||
|
|
@ -26,22 +32,48 @@ namespace SceneManager
|
|||
deletePath.ForeColor = Color.Gold;
|
||||
|
||||
editPathMenu.RefreshIndex();
|
||||
editPathMenu.OnItemSelect += EditPath_OnItemSelected;
|
||||
editPathMenu.OnCheckboxChange += EditPath_OnCheckboxChange;
|
||||
}
|
||||
|
||||
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, PathMainMenu.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 EditPath_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
|
||||
{
|
||||
var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index];
|
||||
|
||||
if (selectedItem == editPathWaypoints)
|
||||
{
|
||||
EditWaypointMenu.BuildEditWaypointMenu();
|
||||
EditPathWaypoints();
|
||||
}
|
||||
|
||||
if (selectedItem == deletePath)
|
||||
{
|
||||
PathMainMenu.DeletePath(currentPath, PathMainMenu.Delete.Single);
|
||||
DeletePath();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -49,18 +81,21 @@ namespace SceneManager
|
|||
{
|
||||
if (checkboxItem == disablePath)
|
||||
{
|
||||
var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index];
|
||||
if (disablePath.Checked)
|
||||
DisablePath();
|
||||
}
|
||||
}
|
||||
|
||||
private static void EditPath_OnMenuOpen(UIMenu menu)
|
||||
{
|
||||
currentPath.DisablePath();
|
||||
Logger.Log($"Path {currentPath.Number} disabled.");
|
||||
}
|
||||
else
|
||||
var scrollerItems = new List<UIMenuScrollerItem> { };
|
||||
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>() { { disablePath, DisablePath } };
|
||||
var selectItems = new Dictionary<UIMenuItem, RNUIMouseInputHandler.Function>()
|
||||
{
|
||||
currentPath.EnablePath();
|
||||
Logger.Log($"Path {currentPath.Number} enabled.");
|
||||
}
|
||||
}
|
||||
{ editPathWaypoints, EditPathWaypoints },
|
||||
{ deletePath, DeletePath }
|
||||
};
|
||||
|
||||
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using Rage;
|
||||
|
|
@ -9,35 +9,33 @@ namespace SceneManager
|
|||
{
|
||||
class EditWaypointMenu
|
||||
{
|
||||
private static VehicleDrivingFlags[] drivingFlags = new VehicleDrivingFlags[] { VehicleDrivingFlags.Normal, VehicleDrivingFlags.IgnorePathFinding, VehicleDrivingFlags.StopAtDestination };
|
||||
private static string[] waypointTypes = new string[] { "Drive To (Normal)", "Drive To (Direct)", "Stop" };
|
||||
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;
|
||||
internal static UIMenuListScrollerItem<string> changeWaypointType = new UIMenuListScrollerItem<string>("Waypoint Type", "", waypointTypes);
|
||||
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 current position. You should turn this on if you're planning on adding this waypoint as a new waypoint.");
|
||||
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 void InstantiateMenu()
|
||||
{
|
||||
editWaypointMenu.ParentMenu = EditPathMenu.editPathMenu;
|
||||
MenuManager.menuPool.Add(editWaypointMenu);
|
||||
|
||||
editWaypointMenu.OnScrollerChange += EditWaypoint_OnScrollerChanged;
|
||||
editWaypointMenu.OnCheckboxChange += EditWaypoint_OnCheckboxChanged;
|
||||
editWaypointMenu.OnItemSelect += EditWaypoint_OnItemSelected;
|
||||
editWaypointMenu.OnMenuOpen += EditWaypoint_OnMenuOpen;
|
||||
}
|
||||
|
||||
internal static void BuildEditWaypointMenu()
|
||||
{
|
||||
// Need to unsubscribe from these or else there will be duplicate firings if the user left the menu, then re-entered
|
||||
ResetEventHandlerSubscriptions();
|
||||
|
||||
var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Value-1];
|
||||
//Logger.Log($"Current path: {currentPath.Number}");
|
||||
|
||||
editWaypoint = new UIMenuNumericScrollerItem<int>("Edit Waypoint", "", currentPath.Waypoints.First().Number, currentPath.Waypoints.Last().Number, 1);
|
||||
editWaypointMenu.Clear();
|
||||
|
|
@ -45,7 +43,6 @@ namespace SceneManager
|
|||
editWaypoint.Index = 0;
|
||||
|
||||
var currentWaypoint = currentPath.Waypoints.Where(wp => wp.Number == editWaypoint.Value).FirstOrDefault();
|
||||
//Logger.Log($"Current waypoint: {currentWaypoint.Number}, Driving flag: {currentWaypoint.DrivingFlag.ToString()}");
|
||||
if(currentWaypoint != null)
|
||||
{
|
||||
editWaypointMenu.AddItem(collectorWaypoint = new UIMenuCheckboxItem("Collector", currentWaypoint.IsCollector, "If this waypoint will collect vehicles to follow the path"));
|
||||
|
|
@ -85,17 +82,140 @@ namespace SceneManager
|
|||
editWaypointMenu.RefreshIndex();
|
||||
editWaypointMenu.Visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ResetEventHandlerSubscriptions()
|
||||
private static void UpdateCollectorMenuOptionsStatus()
|
||||
{
|
||||
editWaypointMenu.OnItemSelect -= EditWaypoint_OnItemSelected;
|
||||
editWaypointMenu.OnCheckboxChange -= EditWaypoint_OnCheckboxChanged;
|
||||
editWaypointMenu.OnScrollerChange -= EditWaypoint_OnScrollerChanged;
|
||||
if (collectorWaypoint.Checked)
|
||||
{
|
||||
changeCollectorRadius.Enabled = true;
|
||||
changeSpeedZoneRadius.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
changeCollectorRadius.Enabled = false;
|
||||
changeSpeedZoneRadius.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
editWaypointMenu.OnScrollerChange += EditWaypoint_OnScrollerChanged;
|
||||
editWaypointMenu.OnCheckboxChange += EditWaypoint_OnCheckboxChanged;
|
||||
editWaypointMenu.OnItemSelect += EditWaypoint_OnItemSelected;
|
||||
private static void UpdateWaypoint()
|
||||
{
|
||||
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)
|
||||
{
|
||||
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, PathMainMenu.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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddAsNewWaypoint()
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,8 +226,6 @@ namespace SceneManager
|
|||
|
||||
if (scrollerItem == editWaypoint)
|
||||
{
|
||||
//changeWaypointType.Index = Array.IndexOf(drivingFlags, currentWaypoint.DrivingFlag);
|
||||
|
||||
changeWaypointSpeed.Value = (int)MathHelper.ConvertMetersPerSecondToMilesPerHour(currentWaypoint.Speed);
|
||||
stopWaypointType.Checked = currentWaypoint.IsStopWaypoint;
|
||||
directWaypointBehavior.Checked = currentWaypoint.DrivingFlagType == DrivingFlagType.Direct ? true : false;
|
||||
|
|
@ -156,117 +274,38 @@ namespace SceneManager
|
|||
|
||||
if (selectedItem == updateWaypoint)
|
||||
{
|
||||
if(currentPath.Waypoints.Count == 1)
|
||||
{
|
||||
currentWaypoint.UpdateWaypoint(currentWaypoint, drivingFlag, stopWaypointType.Checked, SetDriveSpeedForWaypoint(), true, changeCollectorRadius.Value, changeSpeedZoneRadius.Value, updateWaypointPosition.Checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentWaypoint.UpdateWaypoint(currentWaypoint, drivingFlag, stopWaypointType.Checked, SetDriveSpeedForWaypoint(), collectorWaypoint.Checked, changeCollectorRadius.Value, changeSpeedZoneRadius.Value, updateWaypointPosition.Checked);
|
||||
}
|
||||
|
||||
Logger.Log($"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\n~g~[Success]~w~ Waypoint {currentWaypoint.Number} updated.");
|
||||
|
||||
// Why am I rebuilding the menu??
|
||||
//BuildEditWaypointMenu();
|
||||
UpdateWaypoint();
|
||||
}
|
||||
|
||||
if (selectedItem == addAsNewWaypoint)
|
||||
{
|
||||
var pathIndex = PathMainMenu.paths.IndexOf(currentPath);
|
||||
var newWaypointBlip = CreateNewWaypointBlip();
|
||||
if (!currentPath.IsEnabled)
|
||||
{
|
||||
newWaypointBlip.Alpha = 0.5f;
|
||||
}
|
||||
|
||||
if (collectorWaypoint.Checked)
|
||||
{
|
||||
currentPath.Waypoints.Add(new Waypoint(currentPath, currentPath.Waypoints.Last().Number + 1, Game.LocalPlayer.Character.Position, SetDriveSpeedForWaypoint(), drivingFlag, stopWaypointType.Checked, newWaypointBlip, true, changeCollectorRadius.Value, changeSpeedZoneRadius.Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPath.Waypoints.Add(new Waypoint(currentPath, currentPath.Waypoints.Last().Number + 1, Game.LocalPlayer.Character.Position, 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;
|
||||
Logger.Log($"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(Game.LocalPlayer.Character.Position)
|
||||
{
|
||||
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;
|
||||
}
|
||||
AddAsNewWaypoint();
|
||||
}
|
||||
|
||||
if (selectedItem == removeWaypoint)
|
||||
{
|
||||
if (currentPath.Waypoints.Count == 1)
|
||||
{
|
||||
Logger.Log($"Deleting the last waypoint from the path.");
|
||||
PathMainMenu.DeletePath(currentPath, PathMainMenu.Delete.Single);
|
||||
|
||||
editWaypointMenu.Visible = false;
|
||||
PathMainMenu.pathMainMenu.Visible = true;
|
||||
RemoveWaypoint();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentWaypoint.Remove();
|
||||
currentPath.Waypoints.Remove(currentWaypoint);
|
||||
Logger.Log($"[Path {currentPath.Number}] Waypoint {currentWaypoint.Number} ({currentWaypoint.DrivingFlagType}) removed");
|
||||
|
||||
foreach (Waypoint wp in currentPath.Waypoints)
|
||||
{
|
||||
wp.Number = currentPath.Waypoints.IndexOf(wp) + 1;
|
||||
//Logger.Log($"Waypoint at index {currentPath.Waypoints.IndexOf(wp)} is now waypoint #{wp.Number}");
|
||||
}
|
||||
|
||||
editWaypointMenu.Clear();
|
||||
BuildEditWaypointMenu();
|
||||
|
||||
if (currentPath.Waypoints.Count == 1)
|
||||
private static void EditWaypoint_OnMenuOpen(UIMenu menu)
|
||||
{
|
||||
Hints.Display($"~o~Scene Manager\n~y~[Hint]~w~ Your path's first waypoint ~b~must~w~ be a collector. If it's not, it will automatically be made into one.");
|
||||
Logger.Log($"The path only has 1 waypoint left, this waypoint must be a collector.");
|
||||
currentPath.Waypoints[0].UpdateWaypoint(currentWaypoint, drivingFlag, stopWaypointType.Checked, SetDriveSpeedForWaypoint(), true, changeCollectorRadius.Value, changeSpeedZoneRadius.Value, updateWaypointPosition.Checked);
|
||||
collectorWaypoint.Checked = true;
|
||||
changeCollectorRadius.Enabled = true;
|
||||
changeSpeedZoneRadius.Enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
var scrollerItems = new List<UIMenuScrollerItem> { editWaypoint, changeWaypointSpeed, changeCollectorRadius, changeSpeedZoneRadius };
|
||||
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>()
|
||||
{
|
||||
{ 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()
|
||||
|
|
@ -274,15 +313,11 @@ namespace SceneManager
|
|||
float convertedSpeed;
|
||||
if (SettingsMenu.speedUnits.SelectedItem == SpeedUnits.MPH)
|
||||
{
|
||||
//Logger.Log($"Original speed: {waypointSpeeds[waypointSpeed.Index]}{SettingsMenu.speedUnits.SelectedItem}");
|
||||
convertedSpeed = MathHelper.ConvertMilesPerHourToMetersPerSecond(changeWaypointSpeed.Value);
|
||||
//Logger.Log($"Converted speed: {convertedSpeed}m/s");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Logger.Log($"Original speed: {waypointSpeeds[waypointSpeed.Index]}{SettingsMenu.speedUnits.SelectedItem}");
|
||||
convertedSpeed = MathHelper.ConvertKilometersPerHourToMetersPerSecond(changeWaypointSpeed.Value);
|
||||
//Logger.Log($"Converted speed: {convertedSpeed}m/s");
|
||||
}
|
||||
|
||||
return convertedSpeed;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
using RAGENativeUI;
|
||||
using Rage;
|
||||
using RAGENativeUI;
|
||||
using RAGENativeUI.Elements;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SceneManager
|
||||
{
|
||||
|
|
@ -15,7 +19,7 @@ namespace SceneManager
|
|||
MenuManager.menuPool.Add(mainMenu);
|
||||
}
|
||||
|
||||
public static void BuildMainMenu()
|
||||
internal static void BuildMainMenu()
|
||||
{
|
||||
mainMenu.AddItem(navigateToPathMenu = new UIMenuItem("Path Menu"));
|
||||
navigateToPathMenu.ForeColor = Color.Gold;
|
||||
|
|
@ -28,15 +32,36 @@ namespace SceneManager
|
|||
mainMenu.BindMenuToItem(SettingsMenu.settingsMenu, navigateToSettingsMenu);
|
||||
|
||||
mainMenu.RefreshIndex();
|
||||
mainMenu.OnItemSelect += MainMenu_OnItemSelected;
|
||||
mainMenu.OnMenuOpen += MainMenu_OnMenuOpen;
|
||||
}
|
||||
|
||||
private static void MainMenu_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
|
||||
private static void ShowPathMainMenu()
|
||||
{
|
||||
if (selectedItem == navigateToBarrierMenu)
|
||||
PathMainMenu.pathMainMenu.Visible = true;
|
||||
}
|
||||
|
||||
private static void ShowBarrierMenu()
|
||||
{
|
||||
BarrierMenu.CreateShadowBarrier(BarrierMenu.barrierMenu);
|
||||
}
|
||||
BarrierMenu.barrierMenu.Visible = true;
|
||||
}
|
||||
|
||||
private static void ShowSettingsMenu()
|
||||
{
|
||||
SettingsMenu.settingsMenu.Visible = true;
|
||||
}
|
||||
|
||||
private static void MainMenu_OnMenuOpen(UIMenu menu)
|
||||
{
|
||||
var scrollerItems = new List<UIMenuScrollerItem> { };
|
||||
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>() { };
|
||||
var selectItems = new Dictionary<UIMenuItem, RNUIMouseInputHandler.Function>()
|
||||
{
|
||||
{ navigateToPathMenu, ShowPathMainMenu },
|
||||
{ navigateToBarrierMenu, ShowBarrierMenu },
|
||||
{ navigateToSettingsMenu, ShowSettingsMenu }
|
||||
};
|
||||
|
||||
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,20 +34,8 @@ namespace SceneManager
|
|||
MainMenu.BuildMainMenu();
|
||||
SettingsMenu.BuildSettingsMenu();
|
||||
PathMainMenu.BuildPathMenu();
|
||||
PathCreationMenu.BuildPathCreationMenu();
|
||||
EditPathMenu.BuildEditPathMenu();
|
||||
BarrierMenu.BuildBarrierMenu();
|
||||
}
|
||||
|
||||
private static void AddMenusToMenuPool()
|
||||
{
|
||||
menuPool.Add(MainMenu.mainMenu);
|
||||
menuPool.Add(SettingsMenu.settingsMenu);
|
||||
menuPool.Add(PathMainMenu.pathMainMenu);
|
||||
menuPool.Add(BarrierMenu.barrierMenu);
|
||||
menuPool.Add(PathCreationMenu.pathCreationMenu);
|
||||
menuPool.Add(EditPathMenu.editPathMenu);
|
||||
menuPool.Add(EditWaypointMenu.editWaypointMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Net.Configuration;
|
||||
using System.Windows.Forms;
|
||||
using Rage;
|
||||
using RAGENativeUI;
|
||||
using RAGENativeUI.Elements;
|
||||
|
|
@ -10,22 +12,24 @@ namespace SceneManager
|
|||
{
|
||||
class PathCreationMenu
|
||||
{
|
||||
private static VehicleDrivingFlags[] drivingFlags = new VehicleDrivingFlags[] { VehicleDrivingFlags.Normal, VehicleDrivingFlags.IgnorePathFinding, VehicleDrivingFlags.StopAtDestination }; // Implement custom driving flag for normal
|
||||
private static string[] waypointTypes = new string[] { "Drive To (Normal)", "Drive To (Direct)", "Stop" };
|
||||
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 UIMenuListScrollerItem<string> waypointType = new UIMenuListScrollerItem<string>("Waypoint Type", $"~b~Drive To (Normal): ~w~AI obeys traffic as much as possible{Environment.NewLine}~b~Drive To (Direct): ~w~AI ignores pathfinding rules{Environment.NewLine}~b~Stop: ~w~AI stops at the waypoint until dismissed", waypointTypes);
|
||||
private static UIMenuNumericScrollerItem<int> waypointSpeed;
|
||||
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 void InstantiateMenu()
|
||||
{
|
||||
pathCreationMenu.ParentMenu = PathMainMenu.pathMainMenu;
|
||||
MenuManager.menuPool.Add(pathCreationMenu);
|
||||
pathCreationMenu.OnItemSelect += PathCreation_OnItemSelected;
|
||||
pathCreationMenu.OnCheckboxChange += PathCreation_OnCheckboxChanged;
|
||||
pathCreationMenu.OnScrollerChange += PathCreation_OnScrollerChanged;
|
||||
pathCreationMenu.OnMenuOpen += PathCreation_OnMenuOpen;
|
||||
}
|
||||
|
||||
internal static void BuildPathCreationMenu()
|
||||
|
|
@ -35,18 +39,20 @@ namespace SceneManager
|
|||
collectorWaypoint.Checked = true;
|
||||
|
||||
pathCreationMenu.AddItem(collectorRadius);
|
||||
collectorRadius.Index = 0;
|
||||
collectorRadius.Index = Settings.CollectorRadius - 1;
|
||||
collectorRadius.Enabled = true;
|
||||
|
||||
pathCreationMenu.AddItem(speedZoneRadius);
|
||||
speedZoneRadius.Index = 0;
|
||||
speedZoneRadius.Index = (Settings.SpeedZoneRadius / 5) - 1;
|
||||
speedZoneRadius.Enabled = true;
|
||||
|
||||
pathCreationMenu.AddItem(stopWaypointType);
|
||||
stopWaypointType.Checked = Settings.StopWaypoint;
|
||||
pathCreationMenu.AddItem(directWaypointBehavior);
|
||||
directWaypointBehavior.Checked = Settings.DirectDrivingBehavior;
|
||||
|
||||
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 = 0;
|
||||
waypointSpeed.Index = (Settings.WaypointSpeed / 5) - 1;
|
||||
|
||||
pathCreationMenu.AddItem(trafficAddWaypoint);
|
||||
trafficAddWaypoint.ForeColor = Color.Gold;
|
||||
|
|
@ -60,25 +66,26 @@ namespace SceneManager
|
|||
trafficEndPath.Enabled = false;
|
||||
|
||||
pathCreationMenu.RefreshIndex();
|
||||
pathCreationMenu.OnItemSelect += PathCreation_OnItemSelected;
|
||||
pathCreationMenu.OnCheckboxChange += PathCreation_OnCheckboxChanged;
|
||||
pathCreationMenu.OnScrollerChange += PathCreation_OnScrollerChanged;
|
||||
}
|
||||
|
||||
private static void PathCreation_OnCheckboxChanged(UIMenu sender, UIMenuCheckboxItem checkboxItem, bool @checked)
|
||||
private static void UpdateCollectorMenuOptionsStatus()
|
||||
{
|
||||
if(checkboxItem == collectorWaypoint)
|
||||
if (collectorWaypoint.Checked)
|
||||
{
|
||||
collectorRadius.Enabled = collectorWaypoint.Checked ? true : false;
|
||||
speedZoneRadius.Enabled = collectorWaypoint.Checked ? true : false;
|
||||
collectorRadius.Enabled = true;
|
||||
speedZoneRadius.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
collectorRadius.Enabled = false;
|
||||
speedZoneRadius.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void PathCreation_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
|
||||
{
|
||||
if (selectedItem == trafficAddWaypoint)
|
||||
private static void AddNewWaypoint()
|
||||
{
|
||||
var anyPathsExist = PathMainMenu.paths.Count > 0;
|
||||
var waypointPosition = MousePositionInWorld.GetPosition;
|
||||
|
||||
if (!anyPathsExist)
|
||||
{
|
||||
|
|
@ -97,17 +104,27 @@ namespace SceneManager
|
|||
|
||||
if (collectorWaypoint.Checked)
|
||||
{
|
||||
PathMainMenu.paths[pathIndex].Waypoints.Add(new Waypoint(firstNonNullPath, waypointNumber, Game.LocalPlayer.Character.Position, SetDriveSpeedForWaypoint(), drivingFlag, stopWaypointType.Checked, CreateWaypointBlip(), true, collectorRadius.Value, speedZoneRadius.Value));
|
||||
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, Game.LocalPlayer.Character.Position, SetDriveSpeedForWaypoint(), drivingFlag, stopWaypointType.Checked, CreateWaypointBlip()));
|
||||
PathMainMenu.paths[pathIndex].Waypoints.Add(new Waypoint(firstNonNullPath, waypointNumber, waypointPosition, SetDriveSpeedForWaypoint(), drivingFlag, stopWaypointType.Checked, CreateWaypointBlip()));
|
||||
}
|
||||
Logger.Log($"Path {pathNumber} Waypoint {waypointNumber} added [Driving style: {drivingFlag} | Stop waypoint: {stopWaypointType.Checked} | Speed: {waypointSpeed.Value} | Collector: {collectorWaypoint.Checked}]");
|
||||
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}";
|
||||
|
||||
|
|
@ -133,7 +150,7 @@ namespace SceneManager
|
|||
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(Game.LocalPlayer.Character.Position)
|
||||
var blip = new Blip(waypointPosition)
|
||||
{
|
||||
Scale = 0.5f,
|
||||
Sprite = (BlipSprite)spriteNumericalEnum
|
||||
|
|
@ -161,14 +178,13 @@ namespace SceneManager
|
|||
}
|
||||
}
|
||||
|
||||
if (selectedItem == trafficRemoveWaypoint)
|
||||
private static void RemoveWaypoint()
|
||||
{
|
||||
// Loop through each path and find the first one which isn't finished, then delete the path's last waypoint and corresponding blip
|
||||
for (int i = 0; i < PathMainMenu.paths.Count; i++)
|
||||
{
|
||||
if (PathMainMenu.paths.ElementAtOrDefault(i) != null && PathMainMenu.paths[i].State == State.Creating)
|
||||
{
|
||||
Logger.Log($"[Path {i + 1}] {PathMainMenu.paths[i].Waypoints.Last().DrivingFlagType} waypoint removed");
|
||||
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();
|
||||
|
||||
|
|
@ -194,16 +210,15 @@ namespace SceneManager
|
|||
}
|
||||
}
|
||||
|
||||
if (selectedItem == trafficEndPath)
|
||||
private static void EndPath()
|
||||
{
|
||||
// Loop through each path and find the first one which isn't finished
|
||||
for (int i = 0; i < PathMainMenu.paths.Count; i++)
|
||||
{
|
||||
var currentPath = PathMainMenu.paths[i];
|
||||
if (PathMainMenu.paths.ElementAtOrDefault(i) != null && currentPath.State == State.Creating)
|
||||
{
|
||||
Logger.Log($"[Path Creation] Path {currentPath.Number} finished with {currentPath.Waypoints.Count} waypoints.");
|
||||
Game.DisplayNotification($"~o~Scene Manager\n~g~[Success]~w~ Path {i + 1} complete.");
|
||||
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;
|
||||
|
|
@ -212,34 +227,65 @@ namespace SceneManager
|
|||
GameFiber.StartNew(() =>
|
||||
{
|
||||
currentPath.LoopWaypointCollection();
|
||||
//foreach(Waypoint waypoint in PathMainMenu.paths[i].Waypoints)
|
||||
//{
|
||||
// GameFiber WaypointVehicleCollectorFiber = new GameFiber(() => waypoint.CollectVehicles(PathMainMenu.paths));
|
||||
// WaypointVehicleCollectorFiber.Start();
|
||||
// GameFiber.Sleep(1000);
|
||||
//}
|
||||
});
|
||||
|
||||
PathMainMenu.createNewPath.Text = "Create New Path";
|
||||
PathMainMenu.BuildPathMenu();
|
||||
PathMainMenu.pathMainMenu.RefreshIndex();
|
||||
pathCreationMenu.RefreshIndex();
|
||||
waypointSpeed.Index = 0;
|
||||
collectorWaypoint.Enabled = false;
|
||||
collectorWaypoint.Checked = true;
|
||||
speedZoneRadius.Enabled = true;
|
||||
speedZoneRadius.Index = 0;
|
||||
collectorRadius.Enabled = true;
|
||||
collectorRadius.Index = 0;
|
||||
stopWaypointType.Checked = false;
|
||||
directWaypointBehavior.Checked = false;
|
||||
trafficEndPath.Enabled = false;
|
||||
pathCreationMenu.Clear();
|
||||
PathMainMenu.pathMainMenu.Visible = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
AddNewWaypoint();
|
||||
}
|
||||
|
||||
if (selectedItem == trafficRemoveWaypoint)
|
||||
{
|
||||
RemoveWaypoint();
|
||||
}
|
||||
|
||||
if (selectedItem == trafficEndPath)
|
||||
{
|
||||
EndPath();
|
||||
}
|
||||
}
|
||||
|
||||
private static void PathCreation_OnScrollerChanged(UIMenu sender, UIMenuScrollerItem scrollerItem, int first, int last)
|
||||
|
|
@ -264,26 +310,23 @@ namespace SceneManager
|
|||
}
|
||||
}
|
||||
|
||||
private static void ToggleTrafficEndPathMenuItem(int pathIndex)
|
||||
private static void PathCreation_OnMenuOpen(UIMenu menu)
|
||||
{
|
||||
if (PathMainMenu.paths[pathIndex].Waypoints.Count > 0)
|
||||
var scrollerItems = new List<UIMenuScrollerItem> { collectorRadius, speedZoneRadius, waypointSpeed };
|
||||
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>()
|
||||
{
|
||||
trafficEndPath.Enabled = true;
|
||||
}
|
||||
else
|
||||
{ collectorWaypoint, UpdateCollectorMenuOptionsStatus},
|
||||
{ stopWaypointType, null},
|
||||
{ directWaypointBehavior, null}
|
||||
};
|
||||
var selectItems = new Dictionary<UIMenuItem, RNUIMouseInputHandler.Function>()
|
||||
{
|
||||
trafficEndPath.Enabled = false;
|
||||
}
|
||||
}
|
||||
{ trafficAddWaypoint, AddNewWaypoint },
|
||||
{ trafficRemoveWaypoint, RemoveWaypoint },
|
||||
{ trafficEndPath, EndPath }
|
||||
};
|
||||
|
||||
internal static void AddNewPathToPathsCollection(List<Path> paths, int pathIndex)
|
||||
{
|
||||
var pathNum = pathIndex + 1;
|
||||
Logger.Log($"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;
|
||||
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,25 +2,20 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using Rage;
|
||||
using RAGENativeUI;
|
||||
using RAGENativeUI.Elements;
|
||||
|
||||
namespace SceneManager
|
||||
{
|
||||
public enum DismissOption
|
||||
{
|
||||
FromPath = 0,
|
||||
FromWaypoint = 1,
|
||||
FromWorld = 2,
|
||||
FromPlayer = 3,
|
||||
FromDirected = 4
|
||||
}
|
||||
|
||||
|
||||
static class PathMainMenu
|
||||
{
|
||||
internal static List<Path> paths = new List<Path>() { };
|
||||
private static List<string> dismissOptions = new List<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 UIMenuItem createNewPath;
|
||||
|
|
@ -41,13 +36,13 @@ namespace SceneManager
|
|||
{
|
||||
pathMainMenu.ParentMenu = MainMenu.mainMenu;
|
||||
MenuManager.menuPool.Add(pathMainMenu);
|
||||
pathMainMenu.OnItemSelect += PathMenu_OnItemSelected;
|
||||
pathMainMenu.OnCheckboxChange += PathMenu_OnCheckboxChange;
|
||||
pathMainMenu.OnMenuOpen += PathMenu_OnMenuOpen;
|
||||
}
|
||||
|
||||
internal static void BuildPathMenu()
|
||||
{
|
||||
// Need to unsubscribe from events, else there will be duplicate firings if the user left the menu and re-entered
|
||||
ResetEventHandlerSubscriptions();
|
||||
|
||||
MenuManager.menuPool.CloseAllMenus();
|
||||
pathMainMenu.Clear();
|
||||
|
||||
|
|
@ -81,14 +76,6 @@ namespace SceneManager
|
|||
}
|
||||
|
||||
MenuManager.menuPool.RefreshIndex();
|
||||
|
||||
void ResetEventHandlerSubscriptions()
|
||||
{
|
||||
pathMainMenu.OnItemSelect -= PathMenu_OnItemSelected;
|
||||
pathMainMenu.OnCheckboxChange -= PathMenu_OnCheckboxChange;
|
||||
pathMainMenu.OnItemSelect += PathMenu_OnItemSelected;
|
||||
pathMainMenu.OnCheckboxChange += PathMenu_OnCheckboxChange;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool VehicleAndDriverValid(this Vehicle v)
|
||||
|
|
@ -103,6 +90,72 @@ namespace SceneManager
|
|||
}
|
||||
}
|
||||
|
||||
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}");
|
||||
|
|
@ -138,7 +191,7 @@ namespace SceneManager
|
|||
{
|
||||
Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(cv.Vehicle, 1f, 1, true);
|
||||
}
|
||||
cv.StoppedAtWaypoint = false;
|
||||
//cv.StoppedAtWaypoint = false;
|
||||
if (cv.Driver.GetAttachedBlip())
|
||||
{
|
||||
cv.Driver.GetAttachedBlip().Delete();
|
||||
|
|
@ -196,48 +249,7 @@ namespace SceneManager
|
|||
}
|
||||
}
|
||||
|
||||
private static void PathMenu_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
|
||||
{
|
||||
if (selectedItem == createNewPath)
|
||||
{
|
||||
pathMainMenu.Visible = false;
|
||||
PathCreationMenu.pathCreationMenu.Visible = true;
|
||||
Draw3DWaypointOnPlayer();
|
||||
|
||||
// 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.LogTrivial($"Resuming path {paths[i].Number}");
|
||||
Game.DisplayNotification($"~o~Scene Manager\n~y~[Creating]~w~ Resuming path {paths[i].Number}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedItem == editPath)
|
||||
{
|
||||
pathMainMenu.Visible = false;
|
||||
EditPathMenu.editPathMenu.Visible = true;
|
||||
}
|
||||
|
||||
if (selectedItem == deleteAllPaths)
|
||||
{
|
||||
// Iterate through each item in paths and delete it
|
||||
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.");
|
||||
}
|
||||
|
||||
if (selectedItem == directDriver)
|
||||
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];
|
||||
|
|
@ -259,7 +271,8 @@ namespace SceneManager
|
|||
{
|
||||
GameFiber.StartNew(() =>
|
||||
{
|
||||
AITasking.AssignWaypointTasks(nearbyCollectedVehicle, path, firstWaypoint);
|
||||
nearbyCollectedVehicle.AssignWaypointTasks(path, firstWaypoint);
|
||||
//AITasking.AssignWaypointTasks(nearbyCollectedVehicle, path, firstWaypoint);
|
||||
});
|
||||
}
|
||||
else
|
||||
|
|
@ -268,7 +281,8 @@ namespace SceneManager
|
|||
{
|
||||
GameFiber.StartNew(() =>
|
||||
{
|
||||
AITasking.AssignWaypointTasks(nearbyCollectedVehicle, path, nearestWaypoint);
|
||||
nearbyCollectedVehicle.AssignWaypointTasks(path, nearestWaypoint);
|
||||
//AITasking.AssignWaypointTasks(nearbyCollectedVehicle, path, nearestWaypoint);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -297,7 +311,8 @@ namespace SceneManager
|
|||
{
|
||||
GameFiber.StartNew(() =>
|
||||
{
|
||||
AITasking.AssignWaypointTasks(collectedVehicle, path, firstWaypoint);
|
||||
collectedVehicle.AssignWaypointTasks(path, firstWaypoint);
|
||||
//AITasking.AssignWaypointTasks(collectedVehicle, path, firstWaypoint);
|
||||
});
|
||||
}
|
||||
else
|
||||
|
|
@ -306,14 +321,15 @@ namespace SceneManager
|
|||
{
|
||||
GameFiber.StartNew(() =>
|
||||
{
|
||||
AITasking.AssignWaypointTasks(collectedVehicle, path, nearestWaypoint);
|
||||
collectedVehicle.AssignWaypointTasks(path, nearestWaypoint);
|
||||
//AITasking.AssignWaypointTasks(collectedVehicle, path, nearestWaypoint);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedItem == dismissDriver)
|
||||
private static void DismissDriver()
|
||||
{
|
||||
var nearbyVehicle = Game.LocalPlayer.Character.GetNearbyVehicles(16).Where(v => v != Game.LocalPlayer.Character.CurrentVehicle && v.VehicleAndDriverValid()).FirstOrDefault();
|
||||
if (nearbyVehicle)
|
||||
|
|
@ -364,60 +380,62 @@ namespace SceneManager
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void PathMenu_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
|
||||
{
|
||||
if (selectedItem == createNewPath)
|
||||
{
|
||||
GoToPathCreationMenu();
|
||||
}
|
||||
|
||||
if (selectedItem == editPath)
|
||||
{
|
||||
pathMainMenu.Visible = false;
|
||||
EditPathMenu.editPathMenu.Visible = true;
|
||||
}
|
||||
|
||||
if (selectedItem == deleteAllPaths)
|
||||
{
|
||||
DeleteAllPaths();
|
||||
}
|
||||
|
||||
if (selectedItem == directDriver)
|
||||
{
|
||||
DirectDriver();
|
||||
}
|
||||
|
||||
if (selectedItem == dismissDriver)
|
||||
{
|
||||
DismissDriver();
|
||||
}
|
||||
}
|
||||
|
||||
private static void PathMenu_OnCheckboxChange(UIMenu sender, UIMenuCheckboxItem checkboxItem, bool @checked)
|
||||
{
|
||||
if (checkboxItem == 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.");
|
||||
}
|
||||
DisableAllPaths();
|
||||
}
|
||||
}
|
||||
|
||||
private static void Draw3DWaypointOnPlayer()
|
||||
private static void PathMenu_OnMenuOpen(UIMenu menu)
|
||||
{
|
||||
GameFiber.StartNew(() =>
|
||||
var scrollerItems = new List<UIMenuScrollerItem> { directOptions, directDriver, dismissDriver, editPath };
|
||||
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>()
|
||||
{
|
||||
while (SettingsMenu.threeDWaypoints.Checked)
|
||||
{ disableAllPaths, DisableAllPaths }
|
||||
};
|
||||
|
||||
var selectItems = new Dictionary<UIMenuItem, RNUIMouseInputHandler.Function>()
|
||||
{
|
||||
if (PathCreationMenu.pathCreationMenu.Visible)
|
||||
{
|
||||
if (PathCreationMenu.collectorWaypoint.Checked)
|
||||
{
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Game.LocalPlayer.Character.Position.X, Game.LocalPlayer.Character.Position.Y, Game.LocalPlayer.Character.Position.Z - 1, 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, Game.LocalPlayer.Character.Position.X, Game.LocalPlayer.Character.Position.Y, Game.LocalPlayer.Character.Position.Z - 1, 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, Game.LocalPlayer.Character.Position.X, Game.LocalPlayer.Character.Position.Y, Game.LocalPlayer.Character.Position.Z - 1, 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, Game.LocalPlayer.Character.Position.X, Game.LocalPlayer.Character.Position.Y, Game.LocalPlayer.Character.Position.Z - 1, 0, 0, 0, 0, 0, 0, 1f, 1f, 1f, 65, 255, 65, 80, false, false, 2, false, 0, 0, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
GameFiber.Yield();
|
||||
}
|
||||
});
|
||||
{ createNewPath, GoToPathCreationMenu },
|
||||
{ editPath, GoToEditPathMenu },
|
||||
{ deleteAllPaths, DeleteAllPaths },
|
||||
{ directDriver, DirectDriver },
|
||||
{ dismissDriver, DismissDriver }
|
||||
};
|
||||
|
||||
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
using RAGENativeUI;
|
||||
using RAGENativeUI.Elements;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SceneManager
|
||||
{
|
||||
|
|
@ -19,6 +22,10 @@ namespace SceneManager
|
|||
{
|
||||
settingsMenu.ParentMenu = MainMenu.mainMenu;
|
||||
MenuManager.menuPool.Add(settingsMenu);
|
||||
settingsMenu.OnCheckboxChange += SettingsMenu_OnCheckboxChange;
|
||||
settingsMenu.OnScrollerChange += SettingsMenu_OnScrollerChange;
|
||||
settingsMenu.OnItemSelect += SettingsMenu_OnItemSelected;
|
||||
settingsMenu.OnMenuOpen += SettingsMenu_OnMenuOpen;
|
||||
}
|
||||
|
||||
internal static void BuildSettingsMenu()
|
||||
|
|
@ -30,24 +37,9 @@ namespace SceneManager
|
|||
speedUnits.Index = Array.IndexOf(speedArray, Settings.SpeedUnit);
|
||||
settingsMenu.AddItem(saveSettings);
|
||||
saveSettings.ForeColor = System.Drawing.Color.Gold;
|
||||
|
||||
settingsMenu.OnCheckboxChange += SettingsMenu_OnCheckboxChange;
|
||||
settingsMenu.OnScrollerChange += SettingsMenu_OnScrollerChange;
|
||||
settingsMenu.OnItemSelect += SettingsMenu_OnItemSelected;
|
||||
}
|
||||
|
||||
private static void SettingsMenu_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
|
||||
{
|
||||
if(selectedItem == saveSettings)
|
||||
{
|
||||
Settings.UpdateSettings(threeDWaypoints.Checked, mapBlips.Checked, hints.Checked, speedUnits.SelectedItem);
|
||||
Game.DisplayHelp($"Settings saved");
|
||||
}
|
||||
}
|
||||
|
||||
private static void SettingsMenu_OnCheckboxChange(UIMenu sender, UIMenuCheckboxItem checkboxItem, bool @checked)
|
||||
{
|
||||
if (checkboxItem == mapBlips)
|
||||
private static void ToggleMapBlips()
|
||||
{
|
||||
if (mapBlips.Checked)
|
||||
{
|
||||
|
|
@ -71,6 +63,33 @@ namespace SceneManager
|
|||
}
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
private static void SettingsMenu_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
|
||||
{
|
||||
if(selectedItem == saveSettings)
|
||||
{
|
||||
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)
|
||||
{
|
||||
ToggleMapBlips();
|
||||
}
|
||||
|
||||
if (checkboxItem == hints)
|
||||
{
|
||||
Hints.Enabled = hints.Checked ? true : false;
|
||||
|
|
@ -86,5 +105,22 @@ namespace SceneManager
|
|||
PathCreationMenu.BuildPathCreationMenu();
|
||||
}
|
||||
}
|
||||
|
||||
private static void SettingsMenu_OnMenuOpen(UIMenu menu)
|
||||
{
|
||||
var scrollerItems = new List<UIMenuScrollerItem> { speedUnits };
|
||||
var checkboxItems = new Dictionary<UIMenuCheckboxItem, RNUIMouseInputHandler.Function>()
|
||||
{
|
||||
{ threeDWaypoints, null},
|
||||
{ mapBlips, ToggleMapBlips},
|
||||
{ hints, ToggleHints}
|
||||
};
|
||||
var selectItems = new Dictionary<UIMenuItem, RNUIMouseInputHandler.Function>()
|
||||
{
|
||||
{ saveSettings, ToggleSettings }
|
||||
};
|
||||
|
||||
RNUIMouseInputHandler.Initialize(menu, scrollerItems, checkboxItems, selectItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
42
SceneManager/MousePositionInWorld.cs
Normal file
42
SceneManager/MousePositionInWorld.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
using Rage;
|
||||
using RAGENativeUI.Elements;
|
||||
|
||||
namespace SceneManager
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +1,21 @@
|
|||
using Rage;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace SceneManager
|
||||
{
|
||||
internal class CollectedVehicle
|
||||
{
|
||||
internal Ped Driver { get; set; }
|
||||
internal Vehicle Vehicle { get; set; }
|
||||
internal Path Path { get; set; }
|
||||
internal Waypoint CurrentWaypoint { get; set; }
|
||||
internal Ped Driver { get; private set; }
|
||||
internal Vehicle Vehicle { get; private set; }
|
||||
internal Path Path { get; private set; }
|
||||
internal Waypoint CurrentWaypoint { get; private set; }
|
||||
internal Waypoint NextWaypoint { get; private set; }
|
||||
internal bool StoppedAtWaypoint { get; set; } = false;
|
||||
internal bool Dismissed { get; set; } = false;
|
||||
internal bool StoppedAtWaypoint { get; private set; } = false;
|
||||
internal bool Dismissed { get; private set; } = false;
|
||||
internal bool Directed { get; set; } = false;
|
||||
internal bool SkipWaypoint { get; set; } = false;
|
||||
internal bool ReadyForDirectTasks { get; set; } = true;
|
||||
internal bool SkipWaypoint { get; private set; } = false;
|
||||
internal bool ReadyForDirectTasks { get; private set; } = true;
|
||||
|
||||
internal CollectedVehicle(Vehicle vehicle, Path path, Waypoint currentWaypoint)
|
||||
{
|
||||
|
|
@ -33,12 +34,264 @@ namespace SceneManager
|
|||
SetPersistence();
|
||||
}
|
||||
|
||||
internal void SetPersistence()
|
||||
private void SetPersistence()
|
||||
{
|
||||
Vehicle.IsPersistent = true;
|
||||
Driver.IsPersistent = true;
|
||||
Driver.BlockPermanentEvents = true;
|
||||
//Logger.Log($"{Vehicle.Model.Name} and driver are now persistent.");
|
||||
}
|
||||
|
||||
internal void AssignWaypointTasks(Path path, Waypoint currentWaypoint)
|
||||
{
|
||||
// Driving styles https://gtaforums.com/topic/822314-guide-driving-styles/
|
||||
// also https://vespura.com/fivem/drivingstyle/
|
||||
|
||||
if (!VehicleAndDriverAreValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AssignPathAndCurrentWaypoint();
|
||||
|
||||
AssignDirectedTask();
|
||||
|
||||
if (currentWaypoint.IsStopWaypoint)
|
||||
{
|
||||
StopAtWaypoint();
|
||||
}
|
||||
if (path?.Waypoints?.Count > 0 && currentWaypoint != path?.Waypoints?.Last())
|
||||
{
|
||||
DriveToNextWaypoint();
|
||||
}
|
||||
|
||||
if (!VehicleAndDriverAreValid() || Directed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Game.LogTrivial($"{Vehicle.Model.Name} [{Vehicle.Handle}] all Path {path.Number} tasks complete.");
|
||||
if (!Dismissed)
|
||||
{
|
||||
Dismiss();
|
||||
}
|
||||
|
||||
void AssignPathAndCurrentWaypoint()
|
||||
{
|
||||
Path = path;
|
||||
if (currentWaypoint != null)
|
||||
{
|
||||
CurrentWaypoint = currentWaypoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentWaypoint = path.Waypoints[0];
|
||||
}
|
||||
}
|
||||
|
||||
void AssignDirectedTask()
|
||||
{
|
||||
if (currentWaypoint != null && Directed)
|
||||
{
|
||||
Dismissed = false;
|
||||
|
||||
while (!ReadyForDirectTasks)
|
||||
{
|
||||
GameFiber.Yield();
|
||||
}
|
||||
if (!VehicleAndDriverAreValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Driver.Tasks.Clear();
|
||||
DriveToDirectedWaypoint();
|
||||
}
|
||||
}
|
||||
|
||||
void DriveToDirectedWaypoint()
|
||||
{
|
||||
Dismissed = false;
|
||||
|
||||
while (!ReadyForDirectTasks)
|
||||
{
|
||||
GameFiber.Yield();
|
||||
}
|
||||
Driver.Tasks.Clear();
|
||||
AssignTasksForDirectedDriver();
|
||||
|
||||
void AssignTasksForDirectedDriver()
|
||||
{
|
||||
float acceptedDistance = GetAcceptedStoppingDistance(Path.Waypoints, Path.Waypoints.IndexOf(currentWaypoint));
|
||||
Vector3 oldPosition = currentWaypoint.Position;
|
||||
Game.LogTrivial($"{Vehicle.Model.Name} [{Vehicle.Handle}] is driving to path {currentWaypoint.Path.Number} waypoint {currentWaypoint.Number} (directed)");
|
||||
Driver.Tasks.DriveToPosition(currentWaypoint.Position, currentWaypoint.Speed, (VehicleDrivingFlags)currentWaypoint.DrivingFlagType, acceptedDistance);
|
||||
LoopWhileDrivingToDirectedWaypoint();
|
||||
|
||||
void LoopWhileDrivingToDirectedWaypoint()
|
||||
{
|
||||
while (VehicleAndDriverAreValid() && !Dismissed && !SkipWaypoint && Vehicle.FrontPosition.DistanceTo2D(oldPosition) > acceptedDistance)
|
||||
{
|
||||
if (oldPosition != currentWaypoint.Position)
|
||||
{
|
||||
oldPosition = currentWaypoint.Position;
|
||||
}
|
||||
GameFiber.Yield();
|
||||
}
|
||||
if (Vehicle)
|
||||
{
|
||||
Driver.Tasks.PerformDrivingManeuver(Vehicle, VehicleManeuver.GoForwardWithCustomSteeringAngle, 3).WaitForCompletion();
|
||||
Game.LogTrivial($"{Vehicle.Model.Name} [{Vehicle.Handle}] directed task is complete, directed is now false");
|
||||
}
|
||||
Directed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DriveToNextWaypoint()
|
||||
{
|
||||
if (!VehicleAndDriverAreValid() || CurrentWaypoint == null || Path == null)
|
||||
{
|
||||
Game.LogTrivial($"Vehicle, driver, waypoint, or path is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
Game.LogTrivial($"Preparing to run task loop for {Vehicle.Model.Name} [{Vehicle.Handle}] on path {Path.Number}");
|
||||
for (int currentWaypointTask = CurrentWaypoint.Number; currentWaypointTask < Path.Waypoints.Count; currentWaypointTask++)
|
||||
{
|
||||
var oldPosition = Path.Waypoints[currentWaypointTask].Position;
|
||||
SkipWaypoint = false;
|
||||
|
||||
if (this == null || !Vehicle || Dismissed || Directed)
|
||||
{
|
||||
Game.LogTrivial($"Vehicle dismissed, directed, or null, return");
|
||||
return;
|
||||
}
|
||||
if (Driver == null || !Driver || !Vehicle.HasDriver || !Driver.IsAlive || Vehicle.Driver == Game.LocalPlayer.Character)
|
||||
{
|
||||
Game.LogTrivial($"{Vehicle.Model.Name} [{Vehicle.Handle}] does not have a driver/driver is null or driver is dead.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Path.Waypoints.ElementAtOrDefault(currentWaypointTask) != null && !StoppedAtWaypoint)
|
||||
{
|
||||
CurrentWaypoint = Path.Waypoints[currentWaypointTask];
|
||||
float acceptedDistance = GetAcceptedStoppingDistance(Path.Waypoints, currentWaypointTask);
|
||||
|
||||
Game.LogTrivial($"{Vehicle.Model.Name} [{Vehicle.Handle}] is driving to path {Path.Number} waypoint {Path.Waypoints[currentWaypointTask].Number} (Stop: {CurrentWaypoint.IsStopWaypoint}, Driving flag: {CurrentWaypoint.DrivingFlagType})");
|
||||
Driver.Tasks.DriveToPosition(Path.Waypoints[currentWaypointTask].Position, Path.Waypoints[currentWaypointTask].Speed, (VehicleDrivingFlags)Path.Waypoints[currentWaypointTask].DrivingFlagType, acceptedDistance);
|
||||
LoopWhileDrivingToWaypoint(currentWaypointTask, acceptedDistance, oldPosition);
|
||||
|
||||
if (!VehicleAndDriverAreValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SkipWaypoint)
|
||||
{
|
||||
SkipWaypoint = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Dismissed && !Directed && Path.Waypoints.ElementAtOrDefault(currentWaypointTask) != null && Path.Waypoints[currentWaypointTask].IsStopWaypoint)
|
||||
{
|
||||
StopAtWaypoint();
|
||||
}
|
||||
|
||||
if (!VehicleAndDriverAreValid() || Dismissed || Directed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Driver.Tasks.PerformDrivingManeuver(Vehicle, VehicleManeuver.GoForwardWithCustomSteeringAngle, 3).WaitForCompletion();
|
||||
}
|
||||
}
|
||||
|
||||
void LoopWhileDrivingToWaypoint(int currentWaypointTask, float acceptedDistance, Vector3 oldPosition)
|
||||
{
|
||||
while (VehicleAndDriverAreValid() && !Dismissed && !SkipWaypoint && !Directed && Path.Waypoints.ElementAtOrDefault(currentWaypointTask) != null && Vehicle.FrontPosition.DistanceTo2D(Path.Waypoints[currentWaypointTask].Position) > acceptedDistance)
|
||||
{
|
||||
if (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);
|
||||
}
|
||||
if(Driver.Tasks.CurrentTaskStatus == TaskStatus.NoTask)
|
||||
{
|
||||
//Game.DisplayNotification($"~o~Scene Manager ~r~[Error]\n{Vehicle.Model.Name} [{Vehicle.Handle}] driver [{Driver.Handle}] has no task. Reassiging current waypoint task.");
|
||||
Game.LogTrivial($"{Vehicle.Model.Name} [{Vehicle.Handle}] driver [{Driver.Handle}] has no task. Reassiging current waypoint task.");
|
||||
if (Driver.CurrentVehicle)
|
||||
{
|
||||
Driver.Tasks.DriveToPosition(Path.Waypoints[currentWaypointTask].Position, Path.Waypoints[currentWaypointTask].Speed, (VehicleDrivingFlags)Path.Waypoints[currentWaypointTask].DrivingFlagType, acceptedDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
Game.LogTrivial($"{Vehicle.Model.Name} [{Vehicle.Handle}] driver [{Driver.Handle}] is not in a vehicle. Exiting loop.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
GameFiber.Sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float GetAcceptedStoppingDistance(List<Waypoint> waypoints, int nextWaypoint)
|
||||
{
|
||||
float dist;
|
||||
if (Settings.SpeedUnit == SpeedUnits.MPH)
|
||||
{
|
||||
dist = (MathHelper.ConvertMilesPerHourToKilometersPerHour(waypoints[nextWaypoint].Speed) * MathHelper.ConvertMilesPerHourToKilometersPerHour(waypoints[nextWaypoint].Speed)) / (250 * 0.8f);
|
||||
}
|
||||
else
|
||||
{
|
||||
dist = (waypoints[nextWaypoint].Speed * waypoints[nextWaypoint].Speed) / (250 * 0.8f);
|
||||
}
|
||||
var acceptedDistance = MathHelper.Clamp(dist, 2, 10);
|
||||
return acceptedDistance;
|
||||
}
|
||||
|
||||
void StopAtWaypoint()
|
||||
{
|
||||
if (!VehicleAndDriverAreValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var stoppingDistance = GetAcceptedStoppingDistance(currentWaypoint.Path.Waypoints, currentWaypoint.Path.Waypoints.IndexOf(currentWaypoint));
|
||||
Game.LogTrivial($"{Vehicle.Model.Name} stopping at path {currentWaypoint.Path.Number} waypoint.");
|
||||
Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Vehicle, stoppingDistance, -1, true);
|
||||
StoppedAtWaypoint = true;
|
||||
|
||||
while (currentWaypoint != null && VehicleAndDriverAreValid() && StoppedAtWaypoint && !Directed)
|
||||
{
|
||||
GameFiber.Yield();
|
||||
}
|
||||
if (Driver && Driver.CurrentVehicle)
|
||||
{
|
||||
Game.LogTrivial($"{Vehicle.Model.Name} releasing from stop waypoint.");
|
||||
Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Vehicle, 0f, 1, true);
|
||||
Driver.Tasks.CruiseWithVehicle(5f);
|
||||
}
|
||||
}
|
||||
|
||||
bool VehicleAndDriverAreValid()
|
||||
{
|
||||
if (this == null)
|
||||
{
|
||||
Game.LogTrivial($"CollectedVehicle is null");
|
||||
return false;
|
||||
}
|
||||
if (!Vehicle && !Dismissed)
|
||||
{
|
||||
Game.LogTrivial($"Vehicle is null");
|
||||
Dismiss();
|
||||
return false;
|
||||
}
|
||||
if (!Driver || !Driver.IsAlive)
|
||||
{
|
||||
Dismiss();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal void Dismiss(DismissOption dismissOption = DismissOption.FromPath, Path newPath = null)
|
||||
|
|
@ -64,19 +317,21 @@ namespace SceneManager
|
|||
if (Vehicle)
|
||||
{
|
||||
Vehicle.Dismiss();
|
||||
}
|
||||
Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Vehicle, 0f, 1, true);
|
||||
}
|
||||
Path.CollectedVehicles.Remove(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if(StoppedAtWaypoint)
|
||||
if(Vehicle && StoppedAtWaypoint)
|
||||
{
|
||||
//Logger.Log($"Unstucking {Vehicle.Model.Name}");
|
||||
StoppedAtWaypoint = false;
|
||||
Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Vehicle, 0f, 1, true);
|
||||
Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(Driver.CurrentVehicle, 0f, 1, true);
|
||||
if (Driver?.CurrentVehicle)
|
||||
{
|
||||
Driver.Tasks.CruiseWithVehicle(5f);
|
||||
}
|
||||
}
|
||||
Driver.Tasks.Clear();
|
||||
|
||||
if (dismissOption == DismissOption.FromWaypoint)
|
||||
|
|
@ -96,7 +351,7 @@ namespace SceneManager
|
|||
|
||||
void DismissFromWorld()
|
||||
{
|
||||
Game.LogTrivial($"Dismissed {Vehicle.Model.Name} from the world");
|
||||
Game.LogTrivial($"Dismissed {Vehicle.Model.Name} [{Vehicle.Handle}] from the world");
|
||||
while (Vehicle.HasOccupants)
|
||||
{
|
||||
foreach (Ped occupant in Vehicle.Occupants)
|
||||
|
|
@ -113,11 +368,13 @@ namespace SceneManager
|
|||
{
|
||||
if (CurrentWaypoint == null || Path == null)
|
||||
{
|
||||
Logger.Log($"CurrentWaypoint or Path are null");
|
||||
Game.LogTrivial($"CurrentWaypoint or Path is null");
|
||||
return;
|
||||
}
|
||||
else if (CurrentWaypoint?.Number != Path?.Waypoints.Count)
|
||||
|
||||
if (CurrentWaypoint?.Number != Path?.Waypoints.Count)
|
||||
{
|
||||
Logger.Log($"Dismissed from waypoint.");
|
||||
Game.LogTrivial($"{Vehicle?.Model.Name} [{Vehicle?.Handle}] dismissed from waypoint.");
|
||||
SkipWaypoint = true;
|
||||
}
|
||||
else if (CurrentWaypoint?.Number == Path?.Waypoints.Count)
|
||||
|
|
@ -128,36 +385,35 @@ namespace SceneManager
|
|||
|
||||
void DismissFromPath()
|
||||
{
|
||||
Logger.Log($"Dismissing from path");
|
||||
Game.LogTrivial($"Dismissing {Vehicle?.Model.Name} [{Vehicle?.Handle}] from path");
|
||||
Dismissed = true;
|
||||
|
||||
// Check if the vehicle is near any of the path's collector waypoints
|
||||
GameFiber.StartNew(() =>
|
||||
{
|
||||
var nearestCollectorWaypoint = Path.Waypoints.Where(wp => wp.IsCollector).OrderBy(wp => Vehicle.DistanceTo2D(wp.Position)).FirstOrDefault();
|
||||
if (nearestCollectorWaypoint != null)
|
||||
if(nearestCollectorWaypoint == null)
|
||||
{
|
||||
// Enabling this will keep the menu, but the dismissed vehicle is immediately re - collected
|
||||
while (nearestCollectorWaypoint != null && Vehicle && Vehicle.HasDriver && Driver && Driver.IsAlive && Vehicle.FrontPosition.DistanceTo2D(nearestCollectorWaypoint.Position) <= nearestCollectorWaypoint.CollectorRadius)
|
||||
{
|
||||
//Game.LogTrivial($"{Vehicle.Model.Name} is within 2x collector radius, cannot be fully dismissed yet.");
|
||||
GameFiber.Yield();
|
||||
}
|
||||
Game.LogTrivial($"Nearest collector is null");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Log($"Nearest collector is null");
|
||||
while (nearestCollectorWaypoint != null && Vehicle && Vehicle.HasDriver && Driver && Driver.IsAlive && Vehicle.FrontPosition.DistanceTo2D(nearestCollectorWaypoint.Position) <= nearestCollectorWaypoint.CollectorRadius)
|
||||
{
|
||||
GameFiber.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
if (!Vehicle || !Driver)
|
||||
{
|
||||
Game.LogTrivial($"Vehicle or driver is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Directed)
|
||||
{
|
||||
Path.CollectedVehicles.Remove(this);
|
||||
Logger.Log($"{Vehicle.Model.Name} dismissed successfully.");
|
||||
Game.LogTrivial($"{Vehicle.Model.Name} [{Vehicle.Handle}] dismissed successfully.");
|
||||
if (Driver)
|
||||
{
|
||||
if (Driver.GetAttachedBlip())
|
||||
|
|
@ -169,12 +425,12 @@ namespace SceneManager
|
|||
}
|
||||
if (Vehicle)
|
||||
{
|
||||
Vehicle.Dismiss();
|
||||
Vehicle.IsSirenOn = false;
|
||||
Vehicle.IsSirenSilent = true;
|
||||
Vehicle.Dismiss();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, "DismissFromPath Fiber");
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,9 +81,9 @@ namespace SceneManager
|
|||
{
|
||||
GameFiber.StartNew(() =>
|
||||
{
|
||||
while (SettingsMenu.threeDWaypoints.Checked)
|
||||
while(true)
|
||||
{
|
||||
if (MenuManager.menuPool.IsAnyMenuOpen())
|
||||
if (SettingsMenu.threeDWaypoints.Checked && (State == State.Finished && MenuManager.menuPool.IsAnyMenuOpen()) || (State == State.Creating && PathCreationMenu.pathCreationMenu.Visible))
|
||||
{
|
||||
for (int i = 0; i < Waypoints.Count; i++)
|
||||
{
|
||||
|
|
@ -133,7 +133,6 @@ namespace SceneManager
|
|||
internal void LoopWaypointCollection()
|
||||
{
|
||||
uint lastProcessTime = Game.GameTime; // Store the last time the full loop finished; this is a value in ms
|
||||
int timeBetweenChecks = 1000; // How many ms to wait between outer loops
|
||||
int yieldAfterChecks = 50; // How many calculations to do before yielding
|
||||
while (PathMainMenu.paths.Contains(this))
|
||||
{
|
||||
|
|
@ -148,10 +147,11 @@ namespace SceneManager
|
|||
{
|
||||
foreach (Vehicle v in World.GetAllVehicles())
|
||||
{
|
||||
if (IsNearWaypoint(v, waypoint) && IsValidForCollection(v))
|
||||
if (VehicleIsNearWaypoint(v, waypoint) && VehicleIsValidForCollection(v))
|
||||
{
|
||||
CollectedVehicle newCollectedVehicle = AddVehicleToCollection(v);
|
||||
GameFiber AssignTasksFiber = new GameFiber(() => AITasking.AssignWaypointTasks(newCollectedVehicle, this, waypoint));
|
||||
GameFiber AssignTasksFiber = new GameFiber(() => newCollectedVehicle.AssignWaypointTasks(this, waypoint));
|
||||
//GameFiber AssignTasksFiber = new GameFiber(() => AITasking.AssignWaypointTasks(newCollectedVehicle, this, waypoint));
|
||||
AssignTasksFiber.Start();
|
||||
}
|
||||
|
||||
|
|
@ -177,18 +177,18 @@ namespace SceneManager
|
|||
{
|
||||
var collectedVehicle = new CollectedVehicle(vehicle, this);
|
||||
CollectedVehicles.Add(collectedVehicle);
|
||||
Logger.Log($"Added {vehicle.Model.Name} to collection from path {Number} waypoint {1}.");
|
||||
Game.LogTrivial($"Added {vehicle.Model.Name} to collection from path {Number} waypoint {1}.");
|
||||
return collectedVehicle;
|
||||
}
|
||||
|
||||
bool IsNearWaypoint(Vehicle v, Waypoint wp)
|
||||
bool VehicleIsNearWaypoint(Vehicle v, Waypoint wp)
|
||||
{
|
||||
return v.FrontPosition.DistanceTo2D(wp.Position) <= wp.CollectorRadius && Math.Abs(wp.Position.Z - v.Position.Z) < 3;
|
||||
}
|
||||
|
||||
bool IsValidForCollection(Vehicle v)
|
||||
bool VehicleIsValidForCollection(Vehicle v)
|
||||
{
|
||||
if (v && v != Game.LocalPlayer.Character.CurrentVehicle && 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))
|
||||
{
|
||||
var vehicleCollectedOnAnotherPath = PathMainMenu.paths.Any(p => p.Number != Number && p.CollectedVehicles.Any(cv => cv.Vehicle == v));
|
||||
if (vehicleCollectedOnAnotherPath)
|
||||
|
|
|
|||
|
|
@ -6,12 +6,6 @@ using System.Linq;
|
|||
|
||||
namespace SceneManager
|
||||
{
|
||||
public enum DrivingFlagType
|
||||
{
|
||||
Normal = 263075,
|
||||
Direct = 17040259
|
||||
}
|
||||
|
||||
public class Waypoint
|
||||
{
|
||||
internal Path Path { get; set; }
|
||||
|
|
@ -60,7 +54,7 @@ namespace SceneManager
|
|||
DrawWaypointMarker();
|
||||
}
|
||||
|
||||
internal void UpdateWaypoint(Waypoint currentWaypoint, DrivingFlagType drivingFlag, bool stopWaypoint, float speed, bool collectorWaypointChecked, float collectorRadius, float speedZoneRadius, bool updateWaypointPositionChecked)
|
||||
internal void UpdateWaypoint(Waypoint currentWaypoint, Vector3 newWaypointPosition, DrivingFlagType drivingFlag, bool stopWaypoint, float speed, bool collectorWaypointChecked, float collectorRadius, float speedZoneRadius, bool updateWaypointPositionChecked)
|
||||
{
|
||||
if(IsStopWaypoint != stopWaypoint)
|
||||
{
|
||||
|
|
@ -71,7 +65,7 @@ namespace SceneManager
|
|||
UpdateCollectorOptions();
|
||||
if (updateWaypointPositionChecked)
|
||||
{
|
||||
UpdateWaypointPosition(Game.LocalPlayer.Character.Position);
|
||||
UpdateWaypointPosition();
|
||||
}
|
||||
|
||||
void UpdateIfStopWaypoint()
|
||||
|
|
@ -103,7 +97,7 @@ namespace SceneManager
|
|||
{
|
||||
IsCollector = true;
|
||||
RemoveSpeedZone();
|
||||
SpeedZone = World.AddSpeedZone(currentWaypoint.Position, SpeedZoneRadius, speed);
|
||||
SpeedZone = World.AddSpeedZone(currentWaypoint.Position, speedZoneRadius, speed);
|
||||
Blip.Color = Color.Blue;
|
||||
if (CollectorRadiusBlip)
|
||||
{
|
||||
|
|
@ -140,7 +134,7 @@ namespace SceneManager
|
|||
}
|
||||
}
|
||||
|
||||
void UpdateWaypointPosition(Vector3 newWaypointPosition)
|
||||
void UpdateWaypointPosition()
|
||||
{
|
||||
Position = newWaypointPosition;
|
||||
RemoveSpeedZone();
|
||||
|
|
@ -199,27 +193,27 @@ namespace SceneManager
|
|||
{
|
||||
if (EditWaypointMenu.updateWaypointPosition.Checked)
|
||||
{
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Game.LocalPlayer.Character.Position.X, Game.LocalPlayer.Character.Position.Y, Game.LocalPlayer.Character.Position.Z - 1, 0, 0, 0, 0, 0, 0, (float)EditWaypointMenu.changeCollectorRadius.Value * 2, (float)EditWaypointMenu.changeCollectorRadius.Value * 2, 1f, 80, 130, 255, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Game.LocalPlayer.Character.Position.X, Game.LocalPlayer.Character.Position.Y, Game.LocalPlayer.Character.Position.Z - 1, 0, 0, 0, 0, 0, 0, (float)EditWaypointMenu.changeSpeedZoneRadius.Value * 2, (float)EditWaypointMenu.changeSpeedZoneRadius.Value * 2, 1f, 255, 185, 80, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, GetMousePositionInWorld(), 0, 0, 0, 0, 0, 0, (float)EditWaypointMenu.changeCollectorRadius.Value * 2, (float)EditWaypointMenu.changeCollectorRadius.Value * 2, 1f, 80, 130, 255, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, GetMousePositionInWorld(), 0, 0, 0, 0, 0, 0, (float)EditWaypointMenu.changeSpeedZoneRadius.Value * 2, (float)EditWaypointMenu.changeSpeedZoneRadius.Value * 2, 1f, 255, 185, 80, 100, false, false, 2, false, 0, 0, false);
|
||||
}
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position.X, Position.Y, Position.Z - 1, 0, 0, 0, 0, 0, 0, (float)EditWaypointMenu.changeCollectorRadius.Value * 2, (float)EditWaypointMenu.changeCollectorRadius.Value * 2, 2f, 80, 130, 255, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position.X, Position.Y, Position.Z - 1, 0, 0, 0, 0, 0, 0, (float)EditWaypointMenu.changeSpeedZoneRadius.Value * 2, (float)EditWaypointMenu.changeSpeedZoneRadius.Value * 2, 2f, 255, 185, 80, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position, 0, 0, 0, 0, 0, 0, (float)EditWaypointMenu.changeCollectorRadius.Value * 2, (float)EditWaypointMenu.changeCollectorRadius.Value * 2, 2f, 80, 130, 255, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position, 0, 0, 0, 0, 0, 0, (float)EditWaypointMenu.changeSpeedZoneRadius.Value * 2, (float)EditWaypointMenu.changeSpeedZoneRadius.Value * 2, 2f, 255, 185, 80, 100, false, false, 2, false, 0, 0, false);
|
||||
}
|
||||
else if (EditWaypointMenu.stopWaypointType.Checked)
|
||||
{
|
||||
if (EditWaypointMenu.updateWaypointPosition.Checked)
|
||||
{
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Game.LocalPlayer.Character.Position.X, Game.LocalPlayer.Character.Position.Y, Game.LocalPlayer.Character.Position.Z - 1, 0, 0, 0, 0, 0, 0, 1f, 1f, 1f, 255, 65, 65, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, GetMousePositionInWorld(), 0, 0, 0, 0, 0, 0, 1f, 1f, 1f, 255, 65, 65, 100, false, false, 2, false, 0, 0, false);
|
||||
}
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position.X, Position.Y, Position.Z - 1, 0, 0, 0, 0, 0, 0, 1f, 1f, 2f, 255, 65, 65, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position, 0, 0, 0, 0, 0, 0, 1f, 1f, 2f, 255, 65, 65, 100, false, false, 2, false, 0, 0, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (EditWaypointMenu.updateWaypointPosition.Checked)
|
||||
{
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Game.LocalPlayer.Character.Position.X, Game.LocalPlayer.Character.Position.Y, Game.LocalPlayer.Character.Position.Z - 1, 0, 0, 0, 0, 0, 0, 1f, 1f, 1f, 65, 255, 65, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, GetMousePositionInWorld(), 0, 0, 0, 0, 0, 0, 1f, 1f, 1f, 65, 255, 65, 100, false, false, 2, false, 0, 0, false);
|
||||
}
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position.X, Position.Y, Position.Z - 1, 0, 0, 0, 0, 0, 0, 1f, 1f, 2f, 65, 255, 65, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position, 0, 0, 0, 0, 0, 0, 1f, 1f, 2f, 65, 255, 65, 100, false, false, 2, false, 0, 0, false);
|
||||
}
|
||||
}
|
||||
else if ((Path.State == State.Finished && MenuManager.menuPool.IsAnyMenuOpen()) || (Path.State == State.Creating && PathCreationMenu.pathCreationMenu.Visible))
|
||||
|
|
@ -231,16 +225,16 @@ namespace SceneManager
|
|||
}
|
||||
if (IsCollector)
|
||||
{
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position.X, Position.Y, Position.Z - 1, 0, 0, 0, 0, 0, 0, CollectorRadius * 2, CollectorRadius * 2, markerHeight, 80, 130, 255, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position.X, Position.Y, Position.Z - 1, 0, 0, 0, 0, 0, 0, SpeedZoneRadius * 2, SpeedZoneRadius * 2, markerHeight, 255, 185, 80, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position, 0, 0, 0, 0, 0, 0, CollectorRadius * 2, CollectorRadius * 2, markerHeight, 80, 130, 255, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position, 0, 0, 0, 0, 0, 0, SpeedZoneRadius * 2, SpeedZoneRadius * 2, markerHeight, 255, 185, 80, 100, false, false, 2, false, 0, 0, false);
|
||||
}
|
||||
else if (IsStopWaypoint)
|
||||
{
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position.X, Position.Y, Position.Z - 1, 0, 0, 0, 0, 0, 0, 1f, 1f, markerHeight, 255, 65, 65, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position, 0, 0, 0, 0, 0, 0, 1f, 1f, markerHeight, 255, 65, 65, 100, false, false, 2, false, 0, 0, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position.X, Position.Y, Position.Z - 1, 0, 0, 0, 0, 0, 0, 1f, 1f, markerHeight, 65, 255, 65, 100, false, false, 2, false, 0, 0, false);
|
||||
Rage.Native.NativeFunction.Natives.DRAW_MARKER(1, Position, 0, 0, 0, 0, 0, 0, 1f, 1f, markerHeight, 65, 255, 65, 100, false, false, 2, false, 0, 0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -292,7 +286,7 @@ namespace SceneManager
|
|||
internal void CollectVehicles(List<Path> paths)
|
||||
{
|
||||
var sleepInterval = 1000;
|
||||
Logger.Log($"Starting collection loop on waypoint {Number}");
|
||||
Game.LogTrivial($"Starting collection loop on waypoint {Number}");
|
||||
while (paths.Contains(Path) && Path.Waypoints.Contains(this))
|
||||
{
|
||||
if (Path.IsEnabled && IsCollector)
|
||||
|
|
@ -309,7 +303,7 @@ namespace SceneManager
|
|||
if (collectedVehiclePlayerIsIn != null)
|
||||
{
|
||||
collectedVehiclePlayerIsIn.Dismiss(DismissOption.FromPlayer);
|
||||
Logger.Log($"Dismissed a collected vehicle the player was in.");
|
||||
Game.LogTrivial($"Dismissed a collected vehicle the player was in.");
|
||||
}
|
||||
GameFiber.Sleep(sleepInterval);
|
||||
}
|
||||
|
|
@ -327,8 +321,8 @@ namespace SceneManager
|
|||
if (collectedVehicle == null)
|
||||
{
|
||||
CollectedVehicle newCollectedVehicle = AddVehicleToCollection(vehicle);
|
||||
//Logger.Log($"Vehicle's front position distance to waypoint: {vehicle.FrontPosition.DistanceTo2D(waypoint.Position)}, collector radius: {waypoint.CollectorRadius}");
|
||||
GameFiber AssignTasksFiber = new GameFiber(() => AITasking.AssignWaypointTasks(newCollectedVehicle, Path, this));
|
||||
GameFiber AssignTasksFiber = new GameFiber(() => newCollectedVehicle.AssignWaypointTasks(Path, this));
|
||||
//GameFiber AssignTasksFiber = new GameFiber(() => AITasking.AssignWaypointTasks(newCollectedVehicle, Path, this));
|
||||
AssignTasksFiber.Start();
|
||||
}
|
||||
}
|
||||
|
|
@ -343,7 +337,7 @@ namespace SceneManager
|
|||
{
|
||||
var collectedVehicle = new CollectedVehicle(vehicle, Path, this);
|
||||
Path.CollectedVehicles.Add(collectedVehicle);
|
||||
Logger.Log($"Added {vehicle.Model.Name} to collection from path {Path.Number} waypoint {this.Number}.");
|
||||
Game.LogTrivial($"Added {vehicle.Model.Name} to collection from path {Path.Number} waypoint {this.Number}.");
|
||||
return collectedVehicle;
|
||||
}
|
||||
|
||||
|
|
@ -385,5 +379,36 @@ namespace SceneManager
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Vector3 GetMousePositionInWorld()
|
||||
{
|
||||
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(100f, TraceFlags.IntersectWorld).HitPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
|
|
@ -32,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("2.0.1.0")]
|
||||
[assembly: AssemblyFileVersion("2.0.1.0")]
|
||||
[assembly: AssemblyVersion("2.1.1.0")]
|
||||
[assembly: AssemblyFileVersion("2.1.1.0")]
|
||||
|
|
|
|||
253
SceneManager/RNUIMouseInputHandler.cs
Normal file
253
SceneManager/RNUIMouseInputHandler.cs
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
using Rage;
|
||||
using RAGENativeUI;
|
||||
using RAGENativeUI.Elements;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SceneManager
|
||||
{
|
||||
internal class RNUIMouseInputHandler
|
||||
{
|
||||
internal delegate void Function();
|
||||
|
||||
internal static void Initialize(UIMenu menu, List<UIMenuScrollerItem> scrollerItems, Dictionary<UIMenuCheckboxItem, Function> checkboxItems, Dictionary<UIMenuItem, Function> selectItems)
|
||||
{
|
||||
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))
|
||||
{
|
||||
var selectedItem = menu.MenuItems.Where(x => x.Enabled && x.Selected).FirstOrDefault();
|
||||
if (selectedItem != null)
|
||||
{
|
||||
//Game.LogTrivial($"selectedItem: {selectedItem.Text}");
|
||||
//Game.LogTrivial($"scrollerItems contains: {scrollerItems.Contains(selectedItem)}");
|
||||
if (selectItems.ContainsKey(selectedItem))
|
||||
{
|
||||
OnMenuItemClicked(selectItems);
|
||||
}
|
||||
else if (!scrollerItems.Contains(selectedItem) && checkboxItems.ContainsKey((UIMenuCheckboxItem)selectedItem))
|
||||
{
|
||||
OnCheckboxItemClicked(checkboxItems);
|
||||
}
|
||||
}
|
||||
|
||||
if(menu.SubtitleText == "~o~Main Menu")
|
||||
{
|
||||
menu.Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (menu.SubtitleText.Contains("Path Creation Menu"))
|
||||
{
|
||||
DrawWaypointMarker();
|
||||
}
|
||||
GameFiber.Yield();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
internal static void OnCheckboxItemClicked(Dictionary<UIMenuCheckboxItem, Function> checkboxItems)
|
||||
{
|
||||
var checkedItem = checkboxItems.Keys.Where(x => x.Selected && x.Enabled).FirstOrDefault();
|
||||
if(checkedItem != null)
|
||||
{
|
||||
checkedItem.Checked = !checkedItem.Checked;
|
||||
if(checkboxItems.TryGetValue(checkedItem, out Function func))
|
||||
{
|
||||
func?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void OnMenuItemClicked(Dictionary<UIMenuItem, Function> selectItems)
|
||||
{
|
||||
var selectedItem = selectItems.Keys.Where(x => x.Selected && x.Enabled).FirstOrDefault();
|
||||
//Game.LogTrivial($"selectedItem: {selectedItem?.Text}");
|
||||
if (selectedItem != null)
|
||||
{
|
||||
if (selectItems.TryGetValue(selectedItem, out Function func))
|
||||
{
|
||||
func?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
//Game.LogTrivial($"Selected scroller: {selectedScroller.Text}");
|
||||
if (Game.GetMouseWheelDelta() > 0)
|
||||
{
|
||||
foreach (var item in scrollerItems)
|
||||
{
|
||||
if (item == selectedScroller)
|
||||
{
|
||||
//Game.LogTrivial($"item text: {item.Text}");
|
||||
item.ScrollToNextOption();
|
||||
if (menu.SubtitleText.ToLower().Contains("barrier"))
|
||||
{
|
||||
HandleBarrierMenuItems(item);
|
||||
}
|
||||
if(item.Text == "Edit Waypoint")
|
||||
{
|
||||
UpdateEditWaypointMenuItems();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Game.GetMouseWheelDelta() < 0)
|
||||
{
|
||||
foreach (var item in scrollerItems)
|
||||
{
|
||||
if (item == selectedScroller)
|
||||
{
|
||||
item.ScrollToPreviousOption();
|
||||
if (menu.SubtitleText.ToLower().Contains("barrier"))
|
||||
{
|
||||
HandleBarrierMenuItems(item);
|
||||
}
|
||||
if (item.Text == "Edit Waypoint")
|
||||
{
|
||||
UpdateEditWaypointMenuItems();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleBarrierMenuItems(UIMenuItem item)
|
||||
{
|
||||
if (item.Text == "Spawn Barrier")
|
||||
{
|
||||
if (BarrierMenu.shadowBarrier)
|
||||
{
|
||||
BarrierMenu.shadowBarrier.Delete();
|
||||
}
|
||||
var changeTextureItem = scrollerItems.Where(x => x.Text == "Change Texture").FirstOrDefault().Index = 0;
|
||||
var listScrollerItem = (UIMenuListScrollerItem<string>)item;
|
||||
if (listScrollerItem.SelectedItem == "Flare")
|
||||
{
|
||||
scrollerItems.Where(x => x.Text == "Rotate Barrier").FirstOrDefault().Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
scrollerItems.Where(x => x.Text == "Rotate Barrier").FirstOrDefault().Enabled = true;
|
||||
}
|
||||
menu.Width = BarrierMenu.SetMenuWidth();
|
||||
}
|
||||
else if (item.Text == "Rotate Barrier")
|
||||
{
|
||||
BarrierMenu.RotateBarrier();
|
||||
}
|
||||
else if(item.Text == "Change Texture")
|
||||
{
|
||||
var numericScrollerItem = (UIMenuNumericScrollerItem<int>)item;
|
||||
Rage.Native.NativeFunction.Natives.x971DA0055324D033(BarrierMenu.shadowBarrier, numericScrollerItem.Value);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateEditWaypointMenuItems()
|
||||
{
|
||||
var currentPath = PathMainMenu.paths[PathMainMenu.editPath.Index];
|
||||
var editWaypoint = (UIMenuNumericScrollerItem<int>)menu.MenuItems.Where(x => x.Text == "Edit Waypoint").FirstOrDefault();
|
||||
var collectorWaypoint = (UIMenuCheckboxItem)menu.MenuItems.Where(x => x.Text == "Collector").FirstOrDefault();
|
||||
var changeCollectorRadius = (UIMenuNumericScrollerItem<int>)menu.MenuItems.Where(x => x.Text == "Collection Radius").FirstOrDefault();
|
||||
var changeSpeedZoneRadius = (UIMenuNumericScrollerItem<int>)menu.MenuItems.Where(x => x.Text == "Speed Zone Radius").FirstOrDefault();
|
||||
var stopWaypointType = (UIMenuCheckboxItem)menu.MenuItems.Where(x => x.Text == "Is this a Stop waypoint?").FirstOrDefault();
|
||||
var directWaypointBehavior = (UIMenuCheckboxItem)menu.MenuItems.Where(x => x.Text == "Drive directly to waypoint?").FirstOrDefault();
|
||||
var changeWaypointSpeed = (UIMenuNumericScrollerItem<int>)menu.MenuItems.Where(x => x.Text == "Waypoint Speed").FirstOrDefault();
|
||||
var updateWaypointPosition = (UIMenuCheckboxItem)menu.MenuItems.Where(x => x.Text == "Update Waypoint Position").FirstOrDefault();
|
||||
var currentWaypoint = currentPath.Waypoints[editWaypoint.Value - 1];
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -50,9 +50,9 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AITasking.cs" />
|
||||
<Compile Include="ConsoleCommands.cs" />
|
||||
<Compile Include="MousePositionInWorld.cs" />
|
||||
<Compile Include="Object Classes\CollectedVehicle.cs" />
|
||||
<Compile Include="Logger.cs" />
|
||||
<Compile Include="Object Classes\Barrier.cs" />
|
||||
<Compile Include="Hints.cs" />
|
||||
<Compile Include="Menus\BarrierMenu.cs" />
|
||||
|
|
@ -67,6 +67,7 @@
|
|||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Menus\PathMainMenu.cs" />
|
||||
<Compile Include="Menus\SettingsMenu.cs" />
|
||||
<Compile Include="RNUIMouseInputHandler.cs" />
|
||||
<Compile Include="Settings.cs" />
|
||||
<Compile Include="Object Classes\Waypoint.cs" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -17,19 +17,55 @@ namespace SceneManager
|
|||
KPH
|
||||
}
|
||||
|
||||
internal enum DrivingFlagType
|
||||
{
|
||||
Normal = 263075,
|
||||
Direct = 17040259
|
||||
}
|
||||
|
||||
internal enum DismissOption
|
||||
{
|
||||
FromPath = 0,
|
||||
FromWaypoint = 1,
|
||||
FromWorld = 2,
|
||||
FromPlayer = 3,
|
||||
FromDirected = 4
|
||||
}
|
||||
|
||||
internal enum TrafficLight
|
||||
{
|
||||
Green = 0,
|
||||
Red = 1,
|
||||
Yellow = 2,
|
||||
None = 3
|
||||
}
|
||||
|
||||
internal static class Settings
|
||||
{
|
||||
internal static readonly InitializationFile ini = new InitializationFile("Plugins/SceneManager.ini");
|
||||
|
||||
// Keybindings
|
||||
internal static Keys ToggleKey = Keys.T;
|
||||
internal static Keys ModifierKey = Keys.LShiftKey;
|
||||
internal static ControllerButtons ToggleButton = ControllerButtons.Y;
|
||||
internal static ControllerButtons ModifierButton = ControllerButtons.A;
|
||||
|
||||
// Plugin Settings
|
||||
internal static bool Enable3DWaypoints = true;
|
||||
internal static bool EnableMapBlips = true;
|
||||
internal static bool EnableHints = true;
|
||||
internal static SpeedUnits SpeedUnit = SpeedUnits.MPH;
|
||||
internal static float BarrierPlacementDistance = 30f;
|
||||
internal static bool EnableAdvancedBarricadeOptions = false;
|
||||
|
||||
// Default Waypoint Settings
|
||||
internal static int CollectorRadius = 1;
|
||||
internal static int SpeedZoneRadius = 5;
|
||||
internal static bool StopWaypoint = false;
|
||||
internal static bool DirectDrivingBehavior = false;
|
||||
internal static int WaypointSpeed = 5;
|
||||
|
||||
// Barriers
|
||||
internal static List<string> barrierKeys = new List<string>();
|
||||
internal static List<string> barrierValues = new List<string>();
|
||||
|
||||
|
|
@ -38,23 +74,67 @@ namespace SceneManager
|
|||
Game.LogTrivial("Loading SceneManager.ini settings");
|
||||
ini.Create();
|
||||
|
||||
// Keybindings
|
||||
ToggleKey = ini.ReadEnum("Keybindings", "ToggleKey", Keys.T);
|
||||
ModifierKey = ini.ReadEnum("Keybindings", "ModifierKey", Keys.LShiftKey);
|
||||
ToggleButton = ini.ReadEnum("Keybindings", "ToggleButton", ControllerButtons.A);
|
||||
ModifierButton = ini.ReadEnum("Keybindings", "ModifierButton", ControllerButtons.DPadDown);
|
||||
Enable3DWaypoints = ini.ReadBoolean("Other Settings", "Enable3DWaypoints", true);
|
||||
EnableMapBlips = ini.ReadBoolean("Other Settings", "EnableMapBlips", true);
|
||||
EnableHints = ini.ReadBoolean("Other Settings", "EnableHints", true);
|
||||
SpeedUnit = ini.ReadEnum("Other Settings", "SpeedUnits", SpeedUnits.MPH);
|
||||
BarrierPlacementDistance = ini.ReadInt32("Other Settings", "BarrierPlacementDistance", 30);
|
||||
|
||||
// Plugin Settings
|
||||
Enable3DWaypoints = ini.ReadBoolean("Plugin Settings", "Enable3DWaypoints", true);
|
||||
EnableMapBlips = ini.ReadBoolean("Plugin Settings", "EnableMapBlips", true);
|
||||
EnableHints = ini.ReadBoolean("Plugin Settings", "EnableHints", true);
|
||||
SpeedUnit = ini.ReadEnum("Plugin Settings", "SpeedUnits", SpeedUnits.MPH);
|
||||
BarrierPlacementDistance = ini.ReadInt32("Plugin Settings", "BarrierPlacementDistance", 30);
|
||||
EnableAdvancedBarricadeOptions = ini.ReadBoolean("Plugin Settings", "EnableAdvancedBarricadeOptions", false);
|
||||
|
||||
// Default Waypoint Settings
|
||||
CollectorRadius = ini.ReadInt32("Default Waypoint Settings", "CollectorRadius", 1);
|
||||
SpeedZoneRadius = ini.ReadInt32("Default Waypoint Settings", "SpeedZoneRadius", 5);
|
||||
StopWaypoint = ini.ReadBoolean("Default Waypoint Settings", "StopWaypoint", false);
|
||||
DirectDrivingBehavior = ini.ReadBoolean("Default Waypoint Settings", "DirectDrivingBehavior", false);
|
||||
WaypointSpeed = ini.ReadInt32("Default Waypoint Settings", "WaypointSpeed", 5);
|
||||
CheckForValidWaypointSettings();
|
||||
|
||||
// Barriers
|
||||
foreach(string key in ini.GetKeyNames("Barriers"))
|
||||
{
|
||||
barrierKeys.Add(key.Trim());
|
||||
var m = new Model(ini.ReadString("Barriers", key));
|
||||
if (m.IsValid)
|
||||
{
|
||||
barrierValues.Add(m.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
Game.LogTrivial($"{m.Name} is not valid.");
|
||||
}
|
||||
}
|
||||
|
||||
void CheckForValidWaypointSettings()
|
||||
{
|
||||
if(CollectorRadius > 50 || CollectorRadius < 1)
|
||||
{
|
||||
CollectorRadius = 1;
|
||||
Game.LogTrivial($"Invalid value for CollectorRadius in user settings, resetting to default.");
|
||||
}
|
||||
if(SpeedZoneRadius > 200 || SpeedZoneRadius < 5)
|
||||
{
|
||||
SpeedZoneRadius = 5;
|
||||
Game.LogTrivial($"Invalid value for SpeedZoneRadius in user settings, resetting to default.");
|
||||
}
|
||||
if (CollectorRadius > SpeedZoneRadius)
|
||||
{
|
||||
CollectorRadius = 1;
|
||||
SpeedZoneRadius = 5;
|
||||
Game.LogTrivial($"CollectorRadius is greater than SpeedZoneRadius in user settings, resetting to defaults.");
|
||||
}
|
||||
if (WaypointSpeed > 100 || WaypointSpeed < 5)
|
||||
{
|
||||
WaypointSpeed = 5;
|
||||
Game.LogTrivial($"Invalid value for WaypointSpeed in user settings, resetting to default.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void UpdateSettings(bool threeDWaypointsEnabled, bool mapBlipsEnabled, bool hintsEnabled, SpeedUnits unit)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue