1
Fork 0
mirror of https://github.com/thegeneralist01/Scene-Manager-DevRepo synced 2026-01-09 14:50:29 +01:00

Add project files.

This commit is contained in:
Rich Dunne 2020-06-08 12:24:59 -06:00
parent ac4873133a
commit 826e45f40b
10 changed files with 1290 additions and 0 deletions

25
SceneManager.sln Normal file
View file

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.902
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SceneManager", "SceneManager\SceneManager.csproj", "{F5800D69-4FC5-4BCE-B10B-CDFEFB6958A2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F5800D69-4FC5-4BCE-B10B-CDFEFB6958A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F5800D69-4FC5-4BCE-B10B-CDFEFB6958A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F5800D69-4FC5-4BCE-B10B-CDFEFB6958A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F5800D69-4FC5-4BCE-B10B-CDFEFB6958A2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CEBAC70B-3D1F-4D38-80C6-E64C184A356C}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,27 @@
using Rage;
namespace SceneManager
{
public class ControlledVehicle
{
public Vehicle Vehicle;
public int Path;
public int TotalWaypoints;
public int CurrentWaypoint;
public bool TasksAssigned;
public bool DismissNow;
public bool StoppedAtWaypoint;
public bool Redirected;
public ControlledVehicle(Vehicle vehicle, int path, int totalWaypoints, int currentWaypoint, bool tasksAssigned, bool dismissNow, bool redirected)
{
Vehicle = vehicle;
Path = path;
TotalWaypoints = totalWaypoints;
CurrentWaypoint = currentWaypoint;
TasksAssigned = tasksAssigned;
DismissNow = dismissNow;
Redirected = redirected;
}
}
}

View file

@ -0,0 +1,86 @@
using System.Windows.Forms;
using Rage;
[assembly: Rage.Attributes.Plugin("Scene Manager V1.7", Author = "Rich", Description = "Manage your scenes with custom AI traffic pathing and cone placement.")]
namespace SceneManager
{
public class EntryPoint
{
internal static class Settings
{
internal static Keys ToggleKey = Keys.T;
internal static Keys ModifierKey = Keys.LShiftKey;
internal static ControllerButtons ToggleButton = ControllerButtons.Y;
internal static ControllerButtons ModifierButton = ControllerButtons.A;
internal static bool EnableHints = true;
internal static string id = Verification.passThrough(Verification.GetID());
internal static string PatronKey = null; // This cannot reference VerifyUser because the file can just be shared and it will always work. Must be manually set to each user's ID
internal static void LoadSettings()
{
Game.LogTrivial("Loading SceneManager.ini settings");
InitializationFile ini = new InitializationFile("Plugins/SceneManager.ini");
ini.Create();
PatronKey = ini.ReadString("Patreon","PatronKey", null);
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);
EnableHints = ini.ReadBoolean("Other Settings", "EnableHints", true);
}
}
public static void Main()
{
Settings.LoadSettings();
Game.LogTrivial($"Scene Manager is ready.");
// id is hardware ID and needs to match PatronKey, which is also hardware ID
if (Settings.id == Settings.PatronKey)
{
Game.LogTrivial($"Patron status verified.");
Game.DisplayNotification($"~o~Scene Manager\n~g~[Patreon]~w~ Thanks for the support, enjoy your session!");
}
else
{
Game.LogTrivial($"Patron status not verified.");
Game.DisplayNotification($"~o~Scene Manager\n~y~[Patreon]~w~ Thanks for using my plugin! If you would like to gain access to benefits such as ~g~new features for this plugin~w~, ~g~early access to new plugins~w~, and ~g~custom plugins made just for you~w~, please consider supporting me on ~b~Patreon~w~. ~y~https://www.patreon.com/richdevs");
}
if (Settings.EnableHints)
{
if (Settings.ModifierKey == Keys.None && Settings.ModifierButton == ControllerButtons.None)
{
Game.DisplayNotification($"~o~Scene Manager\n~y~[Hint]~w~ To open the menu, press the ~b~{Settings.ToggleKey} key ~w~or ~b~{Settings.ToggleButton} button ~w~while on foot");
}
else if (Settings.ModifierKey == Keys.None)
{
Game.DisplayNotification($"~o~Scene Manager\n~y~[Hint]~w~ To open the menu, press the ~b~{Settings.ToggleKey} key ~w~or ~b~{Settings.ModifierButton} ~w~+ ~b~{Settings.ToggleButton} buttons ~w~while on foot");
}
else if (Settings.ModifierButton == ControllerButtons.None)
{
Game.DisplayNotification($"~o~Scene Manager\n~y~[Hint]~w~ To open the menu, press ~b~{Settings.ModifierKey} ~w~+ ~b~{Settings.ToggleKey} ~w~or the ~b~{Settings.ToggleButton} button ~w~while on foot");
}
else
{
Game.DisplayNotification($"~o~Scene Manager\n~y~[Hint]~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 ~w~while on foot");
}
}
GameFiber TrafficMenuFiber = new GameFiber(() => TrafficMenu.CheckUserInput());
TrafficMenuFiber.Start();
}
}
}
/*
* GameFiber.StartNew(delegate{
*
* });
*
* public static Vehicle[] GetNearbyVehicles2(Vector3 OriginPosition, int amount)
* {
* return (Vehicle[])(from x in World.GetAllVehicles() orderby x.DistanceTo(OriginPosition) select x).Take(amount).ToArray();
* }
*/

24
SceneManager/PathData.cs Normal file
View file

@ -0,0 +1,24 @@
using System.Collections.Generic;
namespace SceneManager
{
public class PathData
{
public int PathNum;
public bool PathFinished;
public List<WaypointData> WaypointData = new List<WaypointData>() { };
public PathData(int pathNum, bool pathFinished, List<WaypointData> waypointData)
{
PathNum = pathNum;
PathFinished = pathFinished;
WaypointData = waypointData;
}
public PathData(int pathNum, bool pathFinished)
{
PathNum = pathNum;
PathFinished = pathFinished;
}
}
}

View file

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SceneManager")]
[assembly: AssemblyDescription("Manage your scenes with custom AI traffic pathing and cone placement.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SceneManager")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f5800d69-4fc5-4bce-b10b-cdfefb6958a2")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// 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("1.7.0.0")]
[assembly: AssemblyFileVersion("1.7.0.0")]

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{F5800D69-4FC5-4BCE-B10B-CDFEFB6958A2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SceneManager</RootNamespace>
<AssemblyName>SceneManager</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="RAGENativeUI">
<HintPath>D:\Program Files\Rockstar Games\Grand Theft Auto V\RAGENativeUI.dll</HintPath>
</Reference>
<Reference Include="RagePluginHookSDK">
<HintPath>D:\Program Files\Rockstar Games\Grand Theft Auto V\plugins\LSPDFR\RagePluginHookSDK.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ControlledVehicle.cs" />
<Compile Include="EntryPoint.cs" />
<Compile Include="PathData.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TrafficMenu.cs" />
<Compile Include="TrafficPathing.cs" />
<Compile Include="Verification.cs" />
<Compile Include="WaypointData.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

645
SceneManager/TrafficMenu.cs Normal file
View file

@ -0,0 +1,645 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using Rage;
using RAGENativeUI;
using RAGENativeUI.Elements;
namespace SceneManager
{
public static class TrafficMenu
{
private static MenuPool _menuPool;
private static UIMenu mainMenu, trafficMenu, coneMenu, pathCreationMenu;
private static UIMenuItem navigateToTrafficMenu, navigateToConeMenu, createNewPath, trafficAddWaypoint, trafficRemoveWaypoint, trafficEndPath, deleteAllPaths, addCone, removeLastCone, removeNearestCone, removeAllCones, dismissDriver;
private static UIMenuListItem deleteSinglePath, selectCone, waypointType, waypointSpeed, directDriver;
private static List<dynamic> pathsNum = new List<dynamic>() { };
private static List<PathData> paths = new List<PathData>() { };
private static List<Rage.Object> cones = new List<Rage.Object>() { };
private static List<dynamic> waypointSpeeds = new List<dynamic>() { 5, 10, 15, 20, 30, 40, 50, 60, 70 };
private static List<dynamic> waypointTypes = new List<dynamic>() { "Drive To", "Stop" };
private static VehicleDrivingFlags[] drivingFlags = new VehicleDrivingFlags[] { VehicleDrivingFlags.Normal, VehicleDrivingFlags.StopAtDestination };
private static List<dynamic> coneList = new List<dynamic>() { "Large Striped Cone", "Large Cone", "Medium Striped Cone", "Medium Cone", "Roadpole A", "Roadpole B" };
private static string[] coneObjectNames = new string[] { "prop_mp_cone_01", "prop_roadcone01c", "prop_mp_cone_02", "prop_mp_cone_03", "prop_roadpole_01a", "prop_roadpole_01b" };
private static Rage.Object shadowCone;
public static void CheckUserInput()
{
#pragma warning disable CS0618 // Type or member is obsolete, clear NUI squiggles in BuildMenu
AppDomain.CurrentDomain.DomainUnload += MyTerminationHandler;
BuildMenu();
while (true)
{
// Keyboard
if (EntryPoint.Settings.ModifierKey == System.Windows.Forms.Keys.None)
{
if (Game.LocalPlayer.Character.IsOnFoot && Game.IsKeyDown(EntryPoint.Settings.ToggleKey) && !trafficMenu.Visible && !pathCreationMenu.Visible)
{
mainMenu.Visible = !mainMenu.Visible;
}
}
else if (Game.LocalPlayer.Character.IsOnFoot && Game.IsKeyDownRightNow(EntryPoint.Settings.ModifierKey) && Game.IsKeyDown(EntryPoint.Settings.ToggleKey) && !trafficMenu.Visible && !pathCreationMenu.Visible)
{
mainMenu.Visible = !mainMenu.Visible;
}
// Controller
if (EntryPoint.Settings.ModifierButton == ControllerButtons.None)
{
if (Game.LocalPlayer.Character.IsOnFoot && Game.IsControllerButtonDown(EntryPoint.Settings.ToggleButton) && !trafficMenu.Visible && !pathCreationMenu.Visible)
{
mainMenu.Visible = !mainMenu.Visible;
}
}
else if (Game.LocalPlayer.Character.IsOnFoot && Game.IsControllerButtonDownRightNow(EntryPoint.Settings.ModifierButton) && Game.IsControllerButtonDown(EntryPoint.Settings.ToggleButton) && !trafficMenu.Visible && !pathCreationMenu.Visible)
{
mainMenu.Visible = !mainMenu.Visible;
}
_menuPool.ProcessMenus();
GameFiber.Yield();
}
}
private static void BuildMenu()
{
_menuPool = new MenuPool();
// Instantiate menus
mainMenu = new UIMenu("Scene Manager", "");
trafficMenu = new UIMenu("Scene Manager", "~o~Traffic Menu");
trafficMenu.ParentMenu = mainMenu;
pathCreationMenu = new UIMenu("Scene Manager", "~o~Path Creation");
pathCreationMenu.ParentMenu = trafficMenu;
coneMenu = new UIMenu("Scene Manager", "~o~Cone Menu");
coneMenu.ParentMenu = mainMenu;
// Add menus to the pool
_menuPool.Add(mainMenu);
_menuPool.Add(trafficMenu);
_menuPool.Add(coneMenu);
_menuPool.Add(pathCreationMenu);
// Add menu items to main menu and navigate each item to a submenu
mainMenu.AddItem(navigateToTrafficMenu = new UIMenuItem("~o~Traffic Menu"));
mainMenu.BindMenuToItem(trafficMenu, navigateToTrafficMenu);
mainMenu.AddItem(navigateToConeMenu = new UIMenuItem("~o~Cone Menu"));
mainMenu.BindMenuToItem(coneMenu, navigateToConeMenu);
// Add menu items to trafficMenu
trafficMenu.AddItem(createNewPath = new UIMenuItem("Create New Path"));
trafficMenu.AddItem(deleteSinglePath = new UIMenuListItem("Delete Path", pathsNum, 0));
deleteSinglePath.Enabled = false;
trafficMenu.AddItem(deleteAllPaths = new UIMenuItem("Delete All Paths"));
deleteAllPaths.Enabled = false;
trafficMenu.AddItem(directDriver = new UIMenuListItem("Direct nearest driver to path", pathsNum, 0));
directDriver.Enabled = false;
trafficMenu.AddItem(dismissDriver = new UIMenuItem("Dismiss nearest driver"));
// Add menu items to pathCreationMenu
pathCreationMenu.AddItem(waypointType = new UIMenuListItem("Waypoint Type", waypointTypes, 0));
pathCreationMenu.AddItem(waypointSpeed = new UIMenuListItem("Waypoint Speed", waypointSpeeds, 0));
pathCreationMenu.AddItem(trafficAddWaypoint = new UIMenuItem("Add waypoint"));
pathCreationMenu.AddItem(trafficRemoveWaypoint = new UIMenuItem("Remove last waypoint"));
trafficRemoveWaypoint.Enabled = false;
pathCreationMenu.AddItem(trafficEndPath = new UIMenuItem("End path creation"));
// Add menu items to coneMenu
coneMenu.AddItem(selectCone = new UIMenuListItem("Select Cone", coneList, 0));
coneMenu.AddItem(addCone = new UIMenuItem("Add Cone"));
coneMenu.AddItem(removeLastCone = new UIMenuItem("Remove Last Cone"));
removeLastCone.Enabled = false;
coneMenu.AddItem(removeNearestCone = new UIMenuItem("Remove Nearest Cone"));
removeNearestCone.Enabled = false;
coneMenu.AddItem(removeAllCones = new UIMenuItem("Remove All Cones"));
removeAllCones.Enabled = false;
mainMenu.RefreshIndex();
trafficMenu.RefreshIndex();
pathCreationMenu.RefreshIndex();
coneMenu.RefreshIndex();
// Event handlers for when a menu item is selected
mainMenu.OnItemSelect += MainMenu_OnItemSelected;
trafficMenu.OnItemSelect += TrafficMenu_OnItemSelected;
pathCreationMenu.OnItemSelect += PathCreation_OnItemSelected;
coneMenu.OnListChange += ConeMenu_OnListChange;
coneMenu.OnItemSelect += ConeMenu_OnItemSelected;
// Disable mouse control for the menus
mainMenu.MouseControlsEnabled = false;
mainMenu.AllowCameraMovement = true;
trafficMenu.MouseControlsEnabled = false;
trafficMenu.AllowCameraMovement = true;
pathCreationMenu.MouseControlsEnabled = false;
pathCreationMenu.AllowCameraMovement = true;
coneMenu.MouseControlsEnabled = false;
coneMenu.AllowCameraMovement = true;
}
private static void RebuildTrafficMenu()
{
// The traffic menu has to be "refreshed" in some instances to show changes, so we do that here
_menuPool.CloseAllMenus();
trafficMenu.Clear();
trafficMenu.AddItem(createNewPath = new UIMenuItem("Create New Path"));
trafficMenu.AddItem(deleteSinglePath = new UIMenuListItem("Delete Path", pathsNum, 0));
trafficMenu.AddItem(deleteAllPaths = new UIMenuItem("Delete All Paths"));
trafficMenu.AddItem(directDriver = new UIMenuListItem("Direct nearest driver to path", pathsNum, 0));
trafficMenu.AddItem(dismissDriver = new UIMenuItem("Dismiss nearest driver"));
if (paths.Count == 8)
{
createNewPath.Enabled = false;
}
if (paths.Count == 0)
{
deleteSinglePath.Enabled = false;
deleteAllPaths.Enabled = false;
directDriver.Enabled = false;
}
_menuPool.RefreshIndex();
trafficMenu.Visible = true;
}
private static void DeletePath(PathData path, int index, UIMenuItem selectedItem)
{
// Before deleting a path, we need to dismiss any vehicles controlled by that path and remove the vehicles from ControlledVehicles
//Game.LogTrivial($"Deleting path {index+1}");
Game.LogTrivial($"Deleting path {path.WaypointData[0].Path}");
var matchingVehicle = TrafficPathing.ControlledVehicles.Where(cv => cv.Path == path.WaypointData[0].Path).ToList();
Game.LogTrivial($"Running foreach loop");
foreach (ControlledVehicle cv in matchingVehicle)
{
if (cv.Vehicle.Exists() && cv.Vehicle.IsValid() && cv.Vehicle.Driver.Exists() && cv.Vehicle.Driver.IsValid())
{
cv.DismissNow = true;
cv.Vehicle.Driver.Tasks.Clear();
cv.Vehicle.Driver.Dismiss();
//Game.LogTrivial($"{cv.vehicle.Model.Name} cleared from path {cv.path}");
}
}
Game.LogTrivial($"Remove all vehicles in the path");
TrafficPathing.ControlledVehicles.RemoveAll(cv => cv.Path == path.WaypointData[0].Path);
// Remove the speed zone so cars don't continue to be affected after the path is deleted
foreach (WaypointData wd in path.WaypointData)
{
if (wd == path.WaypointData[0])
{
World.RemoveSpeedZone(wd.YieldZone);
}
wd.WaypointBlip.Delete();
}
path.WaypointData.Clear();
// Manipulating the menu to reflect specific paths being deleted
if (selectedItem == deleteSinglePath)
{
Game.LogTrivial($"Path {path.PathNum} deleted.");
Game.DisplayNotification($"~o~Scene Manager\n~w~Path {path.PathNum} deleted.");
paths.RemoveAt(index);
//Game.LogTrivial("pathsNum count: " + pathsNum.Count);
//Game.LogTrivial("index: " + index);
pathsNum.RemoveAt(index);
RebuildTrafficMenu();
}
}
private static void TrafficMenu_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
{
if (selectedItem == createNewPath)
{
trafficMenu.Visible = false;
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].PathFinished == false)
{
//Game.LogTrivial($"pathFinished: {paths[i].PathFinished}");
Game.LogTrivial($"Resuming path {i+1}");
Game.DisplayNotification($"~o~Scene Manager\n~y~[Creating]~w~ Resuming path {i+1}");
break;
}
else if (paths.ElementAtOrDefault(i) == null)
{
Game.LogTrivial($"Creating path {i+1}");
Game.DisplayNotification($"~o~Scene Manager\n~y~[Creating]~w~ Path {i+1} started.");
paths.Insert(i, new PathData(i+1,false));// { pathNum = i+1, pathFinished = false });
trafficRemoveWaypoint.Enabled = false;
break;
}
}
}
if (selectedItem == deleteSinglePath)
{
//Game.LogTrivial("pathsNum has " + pathsNum.Count + " items before deleting a path.");
//Game.LogTrivial("deletePath index is " + deletePath.Index);
//Game.LogTrivial("deletePath selectedPath is " + deletePath.IndexToItem(deletePath.Index));
DeletePath(paths[deleteSinglePath.Index], deleteSinglePath.Index, deleteSinglePath);
}
if (selectedItem == deleteAllPaths)
{
// Iterate through each item in paths and delete it
for(int i = 0; i < paths.Count; i++)
{
DeletePath(paths[i], i, deleteAllPaths);
}
pathsNum.Clear();
paths.Clear();
RebuildTrafficMenu();
Game.LogTrivial($"All paths deleted");
Game.DisplayNotification($"~o~Scene Manager\n~w~All paths deleted.");
}
if (selectedItem == directDriver)
{
// Sometimes GetNearbyVehicles will cause a crash for some reason, so keeping it in a try/catch will prevent that.
try
{
foreach (Vehicle v in Game.LocalPlayer.Character.GetNearbyVehicles(5))
{
if (v.Exists() && v.IsValid() && v.HasDriver && v.Driver.IsAlive)
{
// Check if there's a matching vehicle in ControlledVehicles. If so, check if it has tasks and proceed, else add it to the collection and assign tasks
var matchingVehicle = TrafficPathing.ControlledVehicles.Where(cv => cv.Vehicle == v).ToList();
if (matchingVehicle.ElementAtOrDefault(0) != null && matchingVehicle[0].TasksAssigned)
{
Game.LogTrivial($"[Direct Driver] {v.Model.Name} already in collection with tasks. Clearing tasks.");
v.Driver.Tasks.Clear();
matchingVehicle[0].Path = paths[directDriver.Index].WaypointData[0].Path;
matchingVehicle[0].TotalWaypoints = paths[directDriver.Index].WaypointData.Count;
matchingVehicle[0].CurrentWaypoint = 1;
matchingVehicle[0].DismissNow = true;
matchingVehicle[0].StoppedAtWaypoint = false;
matchingVehicle[0].Redirected = true;
GameFiber DirectTaskFiber = new GameFiber(() => TrafficPathing.DirectTask(matchingVehicle[0], paths[directDriver.Index].WaypointData));
DirectTaskFiber.Start();
}
else if(matchingVehicle.ElementAtOrDefault(0) != null && !matchingVehicle[0].TasksAssigned)
{
Game.LogTrivial($"[Direct Driver] {v.Model.Name} already in collection, but with no tasks.");
v.Driver.Tasks.Clear();
matchingVehicle[0].Path = paths[directDriver.Index].WaypointData[0].Path;
matchingVehicle[0].TotalWaypoints = paths[directDriver.Index].WaypointData.Count;
matchingVehicle[0].CurrentWaypoint = 1;
matchingVehicle[0].DismissNow = true;
matchingVehicle[0].StoppedAtWaypoint = false;
matchingVehicle[0].Redirected = true;
GameFiber DirectTaskFiber = new GameFiber(() => TrafficPathing.DirectTask(matchingVehicle[0], paths[directDriver.Index].WaypointData));
DirectTaskFiber.Start();
}
else
{
TrafficPathing.ControlledVehicles.Add(new ControlledVehicle(v, paths[directDriver.Index].WaypointData[0].Path, paths[directDriver.Index].WaypointData.Count, 1, false, false, true));
Game.LogTrivial($"[Direct Driver] {v.Model.Name} not in collection, adding to collection for path {paths[directDriver.Index].WaypointData[0].Path} with {paths[directDriver.Index].WaypointData.Count} waypoints");
GameFiber DirectTaskFiber = new GameFiber(() => TrafficPathing.DirectTask(TrafficPathing.ControlledVehicles.Last(), paths[directDriver.Index].WaypointData));
DirectTaskFiber.Start();
}
Game.LogTrivial($"Directed driver of {v.Model.Name} to path {paths[directDriver.Index].WaypointData[0].Path}.");
break;
}
}
}
catch
{
Game.LogTrivial($"No vehicles nearby");
}
}
if (selectedItem == dismissDriver)
{
// Check for nearby vehicles, and if the vehicle is being controlled, release it
GameFiber.StartNew(delegate {
foreach (Vehicle v in Game.LocalPlayer.Character.GetNearbyVehicles(5))
{
try
{
if (v.Exists() && v.IsValid() && v.HasDriver && v.Driver.IsAlive)
{
var matchingVehicle = TrafficPathing.ControlledVehicles.Where(cv => cv.Vehicle == v).ToList();
if (matchingVehicle.ElementAtOrDefault(0) != null && matchingVehicle[0].CurrentWaypoint < matchingVehicle[0].TotalWaypoints && !matchingVehicle[0].StoppedAtWaypoint)
{
matchingVehicle[0].DismissNow = true;
v.Driver.Tasks.Clear();
v.Driver.Dismiss();
Game.LogTrivial($"Dismissed driver of {v.Model.Name} from the path");
}
else if (matchingVehicle.ElementAtOrDefault(0) != null && matchingVehicle[0].CurrentWaypoint < matchingVehicle[0].TotalWaypoints)
{
matchingVehicle[0].StoppedAtWaypoint = false;
Game.LogTrivial($"Dismissed driver of {v.Model.Name} from waypoint {matchingVehicle[0].CurrentWaypoint}");
}
else if (matchingVehicle.ElementAtOrDefault(0) != null && matchingVehicle[0].CurrentWaypoint == matchingVehicle[0].TotalWaypoints)
{
matchingVehicle[0].StoppedAtWaypoint = false;
matchingVehicle[0].DismissNow = true;
v.Driver.Tasks.Clear();
v.Driver.Dismiss();
Game.LogTrivial($"Dismissed driver of {v.Model.Name} from final waypoint and ultimately the path");
}
else if (matchingVehicle.ElementAtOrDefault(0) != null)
{
matchingVehicle[0].DismissNow = true;
v.Driver.Tasks.Clear();
v.Driver.Dismiss();
Game.LogTrivial($"Dismissed driver of {v.Model.Name} from path {matchingVehicle[0].Path}");
}
else
{
v.Driver.Tasks.Clear();
v.Driver.Dismiss();
Game.LogTrivial($"Dismissed driver of {v.Model.Name} (was not in collection)");
}
break;
}
}
catch
{
Game.LogTrivial($"Something went wrong getting nearby vehicles to dismiss");
}
}
});
}
}
private static void PathCreation_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
{
if (selectedItem == trafficAddWaypoint)
{
// Loop through each path and find the first one which isn't finished
for (int i = 0; i < paths.Count; i++)
{
if (paths.ElementAtOrDefault(i) != null && !paths.ElementAtOrDefault(i).PathFinished)
{
// Create a waypoint blip and set the sprite based on the current path number
Blip blip = new Blip(Game.LocalPlayer.Character.Position);
blip.Scale = 0.5f;
switch (i)
{
case 0:
blip.Sprite = BlipSprite.Numbered1;
break;
case 1:
blip.Sprite = BlipSprite.Numbered2;
break;
case 2:
blip.Sprite = BlipSprite.Numbered3;
break;
case 3:
blip.Sprite = BlipSprite.Numbered4;
break;
case 4:
blip.Sprite = BlipSprite.Numbered5;
break;
case 5:
blip.Sprite = BlipSprite.Numbered6;
break;
case 6:
blip.Sprite = BlipSprite.Numbered7;
break;
case 7:
blip.Sprite = BlipSprite.Numbered8;
break;
}
// If it's the first waypoint, make the blip orange, else make it yellow
if (paths[i].WaypointData.Count == 0)
{
blip.Color = Color.Orange;
}
else
{
blip.Color = Color.Yellow;
}
// Add the waypoint data to the path
paths[i].WaypointData.Add(new WaypointData(i+1, Game.LocalPlayer.Character.Position, waypointSpeeds[waypointSpeed.Index], drivingFlags[waypointType.Index], blip));
Game.LogTrivial($"[Path {i+1}] {drivingFlags[waypointType.Index].ToString()} waypoint added");
}
}
// Refresh the trafficMenu after a waypoint is added in order to show Continue Creating Current Path instead of Create New Path
trafficRemoveWaypoint.Enabled = true;
trafficMenu.Clear();
trafficMenu.AddItem(createNewPath = new UIMenuItem("Continue Creating Current Path"));
trafficMenu.AddItem(deleteSinglePath = new UIMenuListItem("Delete Path", pathsNum, 0));
trafficMenu.AddItem(deleteAllPaths = new UIMenuItem("Delete All Paths"));
trafficMenu.AddItem(directDriver = new UIMenuListItem("Direct nearest driver to path", pathsNum, 0));
trafficMenu.AddItem(dismissDriver = new UIMenuItem("Dismiss nearest driver"));
if (pathsNum.Count == 8)
{
createNewPath.Enabled = false;
}
if (pathsNum.Count == 0)
{
deleteSinglePath.Enabled = false;
deleteAllPaths.Enabled = false;
directDriver.Enabled = false;
}
_menuPool.RefreshIndex();
}
if (selectedItem == trafficRemoveWaypoint)
{
// 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 < paths.Count; i++)
{
if (paths.ElementAtOrDefault(i) != null && !paths[i].PathFinished)
{
Game.LogTrivial($"[Path {i+1}] {paths[i].WaypointData.Last().DrivingFlag.ToString()} waypoint removed");
paths[i].WaypointData.Last().WaypointBlip.Delete();
paths[i].WaypointData.RemoveAt(paths[i].WaypointData.IndexOf(paths[i].WaypointData.Last()));
// If the path has no waypoints, disable the menu option to remove a waypoint
if (paths[0].WaypointData.Count == 0)
{
trafficRemoveWaypoint.Enabled = false;
}
}
}
}
if (selectedItem == trafficEndPath)
{
// Loop through each path and find the first one which isn't finished
for (int i = 0; i < paths.Count; i++)
{
if (paths.ElementAtOrDefault(i) != null && !paths[i].PathFinished)
{
// If the path has one stop waypoint or at least two waypoints, finish the path and start the vehicle collector loop, else show user the error and delete any waypoints they made and clear the invalid path
if (paths[i].WaypointData.Count >= 2 || (paths[i].WaypointData.Count == 1 && paths[i].WaypointData[0].DrivingFlag == VehicleDrivingFlags.StopAtDestination))
{
Game.LogTrivial($"[Path Creation] Path {i+1} finished with {paths[i].WaypointData.Count} waypoints.");
Game.DisplayNotification($"~o~Scene Manager\n~g~[Success]~w~ Path {i+1} complete.");
paths[i].WaypointData.Last().WaypointBlip.Color = Color.OrangeRed;
paths[i].PathFinished = true;
paths[i].PathNum = i + 1;
pathsNum.Insert(i, paths[i].PathNum);
GameFiber InitialWaypointVehicleCollectorFiber = new GameFiber(() => TrafficPathing.InitialWaypointVehicleCollector(paths[i].WaypointData));
InitialWaypointVehicleCollectorFiber.Start();
break;
}
else
{
Game.LogTrivial($"[Path Error] A minimum of 2 waypoints is required.");
Game.DisplayNotification($"~o~Scene Manager\n~r~[Error]~w~ A minimum of 2 waypoints is required.");
foreach (WaypointData wd in paths[i].WaypointData)
{
wd.WaypointBlip.Delete();
}
paths[i].WaypointData.Clear();
paths.RemoveAt(i);
break;
}
}
}
// "Refresh" the menu to reflect the new path
RebuildTrafficMenu();
}
}
private static void ConeMenu_OnListChange(UIMenu sender, UIMenuListItem listItem, int index)
{
if (shadowCone.Exists())
{
shadowCone.IsVisible = false;
}
shadowCone = new Rage.Object(coneObjectNames[selectCone.Index], Game.LocalPlayer.Character.GetOffsetPosition(new Vector3(0f, 3f, -1f)));
shadowCone.Opacity = 70f;
shadowCone.IsCollisionEnabled = false;
}
private static void MainMenu_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
{
if (selectedItem == navigateToConeMenu)
{
if (EntryPoint.Settings.EnableHints)
{
Game.DisplayNotification($"~o~Scene Manager\n~y~[Hint]~y~ ~w~It's easier to place cones in first-person view.");
}
shadowCone = new Rage.Object(coneObjectNames[selectCone.Index], Game.LocalPlayer.Character.GetOffsetPosition(new Vector3(0f, 3f, -1f)));
shadowCone.IsCollisionEnabled = false;
shadowCone.Opacity = 70f;
GameFiber ConeHoverFiber = new GameFiber(() => ConeHover(sender, selectedItem, index));
ConeHoverFiber.Start();
}
}
private static void ConeHover(UIMenu sender, UIMenuItem selectedItem, int index)
{
// Run a loop to show currently selected cone hovering in front of player
//Game.LogTrivial("Creating shadow cone");
while (coneMenu.Visible)
{
shadowCone.Position = Game.LocalPlayer.Character.GetOffsetPosition(new Vector3(0f, 3f, -1f));
GameFiber.Yield();
}
}
private static void ConeMenu_OnItemSelected(UIMenu sender, UIMenuItem selectedItem, int index)
{
Rage.Object cone;
if (selectedItem == addCone)
{
// Attach some invisible object to the cone which the AI try to drive around
// Barrier, new rotate option in menu, barrier rotates with cone and becomes invisible similar to ASC when created
cone = new Rage.Object(shadowCone.Model, shadowCone.Position);
cones.Add(cone);
}
if (selectedItem == removeLastCone)
{
//Game.LogTrivial($"cones count before deletion: {cones.Count}");
cones[cones.Count - 1].Delete();
cones.RemoveAt(cones.Count - 1);
//Game.LogTrivial($"cones count after deletion: {cones.Count}");
}
if (selectedItem == removeNearestCone)
{
cones = cones.OrderBy(o => o.DistanceTo(Game.LocalPlayer.Character)).ToList();
cones[0].Delete();
cones.RemoveAt(0);
//Game.LogTrivial($"cones count: {cones.Count}");
}
if (selectedItem == removeAllCones)
{
foreach (Rage.Object c in cones)
{
c.Delete();
}
if (cones.Count > 0)
{
cones.Clear();
}
//Game.LogTrivial($"cones count: {cones.Count}");
}
coneMenu.RemoveItemAt(2);
coneMenu.RemoveItemAt(2);
coneMenu.RemoveItemAt(2);
coneMenu.AddItem(removeLastCone = new UIMenuItem("Remove Last Cone"));
if (cones.Count == 0)
{
removeLastCone.Enabled = false;
}
coneMenu.AddItem(removeNearestCone = new UIMenuItem("Remove Nearest Cone"));
if (cones.Count == 0)
{
removeNearestCone.Enabled = false;
}
coneMenu.AddItem(removeAllCones = new UIMenuItem("Remove All Cones"));
if (cones.Count == 0)
{
removeAllCones.Enabled = false;
}
}
private static void MyTerminationHandler(object sender, EventArgs e)
{
// Clean up paths
for (int i = 0; i < paths.Count; i++)
{
DeletePath(paths[i], i, deleteAllPaths);
}
// Clean up cones
foreach (Rage.Object cone in cones)
{
if (cone.IsValid() && cone.Exists())
{
cone.Delete();
}
}
// Clear everything
cones.Clear();
TrafficPathing.ControlledVehicles.Clear();
Game.LogTrivial($"Scene Manager has been terminated.");
Game.DisplayNotification($"~o~Scene Manager\n~r~[Notice]~w~ The plugin has shut down.");
}
}
}

View file

@ -0,0 +1,282 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Rage;
namespace SceneManager
{
public static class TrafficPathing
{
public static List<ControlledVehicle> ControlledVehicles = new List<ControlledVehicle> { };
public static void InitialWaypointVehicleCollector(List<WaypointData> waypointData)
{
waypointData[0].YieldZone = World.AddSpeedZone(waypointData[0].WaypointPos, 10f, waypointData[0].Speed);
// If there's a path with a single stop waypoint, run a loop to give all nearby AI the StopForVehicle driving flag so they don't just go around
if(waypointData.Count == 1)
{
GameFiber.StartNew(delegate
{
while (waypointData.ElementAtOrDefault(0) != null)
{
foreach (Vehicle v in GetNearbyVehicles(waypointData[0].WaypointPos, 50f))
{
if(v.Exists() && v.IsValid() && v.HasDriver && v.Driver.Exists() && v.Driver.IsValid())
{
SetDriveTaskDrivingFlags(v.Driver, EDrivingFlags.StopForVehicles);
}
}
GameFiber.Yield();
}
});
}
while (waypointData.ElementAtOrDefault(0) != null)
{
// Getting vehicles within 3f of waypoint
try
{
foreach (Vehicle v in GetNearbyVehicles(waypointData[0].WaypointPos, 3f))
{
// No protection for player if they drive into the waypoints
if(VehicleAndDriverValid(v) && v != Game.LocalPlayer.Character.CurrentVehicle && v.HasDriver && v.Driver.IsAlive && (v.IsCar || v.IsBike || v.IsBicycle || v.IsQuadBike))
{
// Check if there's an object in the list with a matching vehicle
var matchingVehicle = ControlledVehicles.Where(cv => cv.Vehicle == v).ToList();
// If there's a match, then check if the first match has tasksAssigned. If not, AssignTasks
if (matchingVehicle.ElementAtOrDefault(0) != null && !matchingVehicle[0].TasksAssigned && !matchingVehicle[0].DismissNow)
{
Game.LogTrivial($"[InitialWaypointVehicleCollector] {v.Model.Name} already in collection, but with no tasks. Assigning tasks.");
matchingVehicle[0].TasksAssigned = true;
GameFiber AssignTasksFiber = new GameFiber(() => AssignTasks(matchingVehicle[0], waypointData));
AssignTasksFiber.Start();
}
// Else if object doesn't exist, add to collection and AssignTasks
else if (matchingVehicle.ElementAtOrDefault(0) != null && matchingVehicle[0].TasksAssigned)
{
//Game.LogTrivial($"Vehicle already in collection with tasks. Do nothing.");
}
else
{
ControlledVehicles.Add(new ControlledVehicle(v, waypointData[0].Path, waypointData.Count, 1, true, false, false));
Game.LogTrivial($"Added {v.Model.Name} to collection from initial waypoint at path {waypointData[0].Path} with {waypointData.Count} waypoints");
GameFiber AssignTasksFiber = new GameFiber(() => AssignTasks(ControlledVehicles.Last(), waypointData));
AssignTasksFiber.Start();
}
}
GameFiber.Yield();
}
}
catch
{
Game.LogTrivial($"There was a problem getting vehicles near the start waypoint");
}
GameFiber.Yield();
}
}
public static void DirectTask(ControlledVehicle cv, List<WaypointData> waypointData)
{
cv.DismissNow = false;
if (VehicleAndDriverValid(cv))
{
cv.Vehicle.IsPersistent = true;
cv.Vehicle.Driver.BlockPermanentEvents = true;
cv.Vehicle.Driver.Tasks.Clear();
}
// Give vehicle task to initial waypoint of desired path, then run a loop to keep giving the task until they're close enough in case they try to wander away too early
cv.Vehicle.Driver.Tasks.DriveToPosition(waypointData[0].WaypointPos, waypointData[0].Speed, VehicleDrivingFlags.FollowTraffic, 1f);
while (waypointData.ElementAtOrDefault(0) != null && VehicleAndDriverValid(cv) && cv.Vehicle.DistanceTo(waypointData[0].WaypointPos) > 3f && !cv.DismissNow)
{
cv.Vehicle.Driver.Tasks.DriveToPosition(waypointData[0].WaypointPos, waypointData[0].Speed, VehicleDrivingFlags.FollowTraffic, 1f);
GameFiber.Sleep(500);
}
cv.Redirected = false;
Game.LogTrivial($"DirectTask loop over");
}
private static void AssignTasks(ControlledVehicle cv, List<WaypointData> waypointData)
{
if (VehicleAndDriverValid(cv))
{
cv.Vehicle.IsPersistent = true;
cv.Vehicle.Driver.BlockPermanentEvents = true;
cv.Vehicle.Driver.Tasks.Clear();
}
if (waypointData.Count == 1 && VehicleAndDriverValid(cv) && !cv.DismissNow)
{
AssignSingleWaypointTask(cv, waypointData);
}
else if(waypointData.Count > 1 && VehicleAndDriverValid(cv))
{
AssignMultiWaypointTasks(cv, waypointData);
}
while(!cv.DismissNow || cv.StoppedAtWaypoint)
{
GameFiber.Yield();
}
Game.LogTrivial($"AssignTasks exit");
}
private static void AssignSingleWaypointTask(ControlledVehicle cv, List<WaypointData> waypointData)
{
// Give driver a task to the single path waypoint. Run a loop with a condition checking for DismissNow for cases where the driver is dismissed or redirected
Game.LogTrivial($"Assigning task for single waypoint.");
cv.Vehicle.Driver.Tasks.DriveToPosition(waypointData[0].WaypointPos, waypointData[0].Speed, VehicleDrivingFlags.FollowTraffic, 1f);
while (waypointData.ElementAtOrDefault(0) != null && VehicleAndDriverValid(cv) && cv.Vehicle.DistanceTo(waypointData[0].WaypointPos) > 3f && !cv.DismissNow)
{
GameFiber.Sleep(1000);
}
Game.LogTrivial($"{cv.Vehicle.Model.Name} should be stopped at the waypoint.");
cv.Vehicle.Driver.Tasks.PerformDrivingManeuver(VehicleManeuver.GoForwardStraightBraking);//.WaitForCompletion();
cv.Vehicle.Driver.Tasks.PerformDrivingManeuver(VehicleManeuver.Wait);
cv.StoppedAtWaypoint = true;
}
private static void AssignMultiWaypointTasks(ControlledVehicle cv, List<WaypointData> waypointData)
{
// For each waypoint in the path, give driver a task to that waypoint
for (int i = 1; i < waypointData.Count; i++)
{
if (cv.DismissNow)
{
break;
}
Game.LogTrivial($"Assigning task to {cv.Vehicle.Model.Name} for waypoint {i+1} of {waypointData.Count}");
cv.CurrentWaypoint++;
//if (VehicleAndDriverValid(cv) && waypointData.ElementAtOrDefault(i) != null && i == waypointData.IndexOf(waypointData.Last()) && waypointData.Last().DrivingFlag == VehicleDrivingFlags.StopAtDestination)
if (VehicleAndDriverValid(cv) && waypointData.ElementAtOrDefault(i) != null && waypointData[i].DrivingFlag == VehicleDrivingFlags.StopAtDestination) // NEW
{
// Give driver a task to the waypoint. Run a loop with a condition checking for DismissNow for cases where the driver is dismissed or redirected
cv.Vehicle.Driver.Tasks.DriveToPosition(waypointData[i].WaypointPos, waypointData[i].Speed, VehicleDrivingFlags.FollowTraffic, 1f);
while (waypointData.ElementAtOrDefault(i) != null && cv.Vehicle.DistanceTo(waypointData[i].WaypointPos) > 3f && !cv.DismissNow)
{
GameFiber.Yield();
}
if (cv.DismissNow)
{
break;
}
if (waypointData.ElementAtOrDefault(i) != null)
{
Game.LogTrivial($"{cv.Vehicle.Model.Name} stopping at stop waypoint");
//Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(v, 3f, 1, false);
cv.Vehicle.Driver.Tasks.PerformDrivingManeuver(VehicleManeuver.GoForwardStraightBraking);
cv.StoppedAtWaypoint = true;
while(waypointData.ElementAtOrDefault(i) != null && cv.StoppedAtWaypoint && !cv.DismissNow)
{
GameFiber.Yield();
}
}
}
else if (VehicleAndDriverValid(cv) && waypointData.ElementAtOrDefault(i) != null && !cv.DismissNow)
{
cv.Vehicle.Driver.Tasks.DriveToPosition(waypointData[i].WaypointPos, waypointData[i].Speed, VehicleDrivingFlags.FollowTraffic, 1f).WaitForCompletion();
}
Game.LogTrivial($"{cv.Vehicle.Model.Name} waypoint {i+1} task complete");
}
if (cv.Redirected)
{
Game.LogTrivial($"{cv.Vehicle.Model.Name} was redirected, all old path tasks have been cleared.");
}
else
{
Game.LogTrivial($"{cv.Vehicle.Model.Name} all path {cv.Path} tasks complete.");
}
cv.TasksAssigned = false;
cv.DismissNow = true;
cv.StoppedAtWaypoint = false;
if (VehicleAndDriverValid(cv) && !cv.Redirected)
{
cv.Vehicle.Driver.Dismiss();
cv.Vehicle.Driver.Tasks.Clear();
//cv.Vehicle.IsPersistent = false;
cv.Vehicle.Driver.BlockPermanentEvents = false;
ControlledVehicles.Remove(cv);
}
else if(!VehicleAndDriverValid(cv))
{
Game.LogTrivial($"The vehicle is not valid after tasks completed.");
}
}
private static bool VehicleAndDriverValid(Vehicle v)
{
// Ensure everything is valid before we do stuff with them so there isn't a crash
if (v.Exists() && v.IsValid() && v.Driver.Exists() && v.Driver.IsValid())
{
return true;
}
else
{
return false;
}
}
private static bool VehicleAndDriverValid(ControlledVehicle cv)
{
// Ensure everything is valid before we do stuff with them so there isn't a crash
if(cv.Vehicle.Exists() && cv.Vehicle.IsValid() && cv.Vehicle.Driver.Exists() && cv.Vehicle.Driver.IsValid())
{
return true;
}
else
{
return false;
}
}
private static Vehicle[] GetNearbyVehicles(Vector3 OriginPosition, float radius)
{
return (from x in World.GetAllVehicles() where !x.IsTrailer && x.DistanceTo(OriginPosition) < radius select x).ToArray();
}
[Flags]
public enum EDrivingFlags
{
None = 0,
StopForVehicles = 1,
StopForPeds = 2,
AvoidEmptyVehicles = 8,
StopForTrafficLights = 128,
UseBlinkers = 256,
TakeShortestPath = 262144,
IgnoreRoads = 4194304,
AvoidHighways = 536870912,
Normal = StopForVehicles | StopForPeds | AvoidEmptyVehicles | StopForTrafficLights | UseBlinkers,
}
public static void SetDriveTaskDrivingFlags(this Ped ped, EDrivingFlags flags)
{
ulong SetDriveTaskDrivingFlagsHash = 0xDACE1BE37D88AF67;
Rage.Native.NativeFunction.CallByHash<int>(SetDriveTaskDrivingFlagsHash, ped, (int)flags);
}
}
}
/*
//while (waypointData.ElementAtOrDefault(0) != null && v.Exists() && v.IsValid() && v.Driver.Exists() && v.Driver.IsValid() && !cv.DismissNow)
//{
//if (waypointData.ElementAtOrDefault(0) == null || cv.DismissNow)
//{
//driver.Tasks.Clear();
//Game.LogTrivial($"{v.Model.Name} released from wait loop");
//break;
//}
//else if (waypointData.ElementAtOrDefault(0) != null && !cv.DismissNow && v.Driver.IsInVehicle(v, false))
//{
v.Driver.Tasks.PerformDrivingManeuver(VehicleManeuver.GoForwardStraightBraking);
//v.Driver.Tasks.PerformDrivingManeuver(VehicleManeuver.Wait);
//}
//GameFiber.Yield();
//}
//v.Driver.Tasks.Clear();
//Game.LogTrivial($"{v.Model.Name} is dismissed or the driver is not in the vehicle.");
*/

View file

@ -0,0 +1,68 @@
using System.Management;
using System.Text;
using Rage;
namespace SceneManager
{
class Verification
{
// https://www.codingame.com/playgrounds/11117/simple-encryption-using-c-and-xor-technique
// Get hardware ID from user
// encrypt hardware ID
// show encrypted ID in log
// decrypt ID for hardware ID
// Give user their hardware ID for ini
// Pass hardware ID through encryption for a match
public static string GetID()
{
// Get processor ID
ManagementObjectCollection mbsList = null;
ManagementObjectSearcher mbs = new ManagementObjectSearcher("Select * From Win32_processor");
mbsList = mbs.Get();
string processorID = "";
foreach (ManagementObject mo in mbsList)
{
processorID = mo["ProcessorID"].ToString();
}
// Get HD ID
/*ManagementObject dsk = new ManagementObject(@"win32_logicaldisk.deviceid=""c:""");
dsk.Get();
string hdID = dsk["VolumeSerialNumber"].ToString();*/
// Get MoBo ID
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_BaseBoard");
ManagementObjectCollection moc = mos.Get();
string motherBoardID = "";
foreach (ManagementObject mo in moc)
{
motherBoardID = (string)mo["SerialNumber"];
}
string uniqueID = processorID + motherBoardID;
string encrypted = passThrough(uniqueID);
//Game.LogTrivial($"Processor ID: {processorID}");
//Game.LogTrivial($"HD ID: {hdID}");
//Game.LogTrivial($"Motherboard ID: {motherBoardID}");
//Game.LogTrivial($"{uniqueID}");
Game.LogTrivial($"{encrypted}"); // Get this value from user's log as their key. When they put it in the .ini, it will go back through passThrough and match with their uniqueID
//Game.LogTrivial($"Decrypted: {passThrough(encrypted)}");
return encrypted;
}
public static string passThrough(string id)
{
StringBuilder szInputStringBuild = new StringBuilder(id);
StringBuilder szOutStringBuild = new StringBuilder(id.Length);
char Textch;
for (int iCount = 0; iCount < id.Length; iCount++)
{
Textch = szInputStringBuild[iCount];
Textch = (char)(Textch ^ 1);
szOutStringBuild.Append(Textch);
}
return szOutStringBuild.ToString();
}
}
}

View file

@ -0,0 +1,33 @@
using Rage;
namespace SceneManager
{
public class WaypointData
{
public int Path;
public Vector3 WaypointPos;
public float Speed;
public VehicleDrivingFlags DrivingFlag;
public Blip WaypointBlip;
public uint YieldZone;
public WaypointData(int path, Vector3 waypointPos, float speed, VehicleDrivingFlags drivingFlag, Blip waypointBlip, uint yieldZone)
{
Path = path;
WaypointPos = waypointPos;
Speed = speed;
DrivingFlag = drivingFlag;
WaypointBlip = waypointBlip;
YieldZone = yieldZone;
}
public WaypointData(int path, Vector3 waypointPos, float speed, VehicleDrivingFlags drivingFlag, Blip waypointBlip)
{
Path = path;
WaypointPos = waypointPos;
Speed = speed;
DrivingFlag = drivingFlag;
WaypointBlip = waypointBlip;
}
}
}