diff --git a/SceneManager/Menus/PathCreationMenu.cs b/SceneManager/Menus/PathCreationMenu.cs index 00eccc3..bf9553d 100644 --- a/SceneManager/Menus/PathCreationMenu.cs +++ b/SceneManager/Menus/PathCreationMenu.cs @@ -211,12 +211,13 @@ namespace SceneManager GameFiber.StartNew(() => { - foreach(Waypoint waypoint in PathMainMenu.paths[i].Waypoints) - { - GameFiber WaypointVehicleCollectorFiber = new GameFiber(() => waypoint.CollectVehicles(PathMainMenu.paths)); - WaypointVehicleCollectorFiber.Start(); - GameFiber.Sleep(1000); - } + 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"; diff --git a/SceneManager/Object Classes/Path.cs b/SceneManager/Object Classes/Path.cs index cef1325..53dc7ed 100644 --- a/SceneManager/Object Classes/Path.cs +++ b/SceneManager/Object Classes/Path.cs @@ -1,4 +1,5 @@ using Rage; +using System; using System.Collections.Generic; using System.Drawing; using System.Linq; @@ -128,5 +129,100 @@ 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)) + { + if (IsEnabled) + { + int checksDone = 0; + try + { + foreach (Waypoint waypoint in Waypoints) + { + if (waypoint != null & waypoint.IsCollector) + { + foreach (Vehicle v in World.GetAllVehicles()) + { + if (IsNearWaypoint(v, waypoint) && IsValidForCollection(v)) + { + CollectedVehicle newCollectedVehicle = AddVehicleToCollection(v); + GameFiber AssignTasksFiber = new GameFiber(() => AITasking.AssignWaypointTasks(newCollectedVehicle, this, waypoint)); + AssignTasksFiber.Start(); + } + + checksDone++; // Increment the counter inside the vehicle loop + if (checksDone % yieldAfterChecks == 0) + { + GameFiber.Yield(); // Yield the game fiber after the specified number of vehicles have been checked + } + } + } + } + } + catch + { + //return; + } + } + GameFiber.Sleep((int)Math.Max(1, Game.GameTime - lastProcessTime)); // If the prior lines took more than a second to run, then you'll run again almost immediately, but if they ran fairly quickly, you can sleep the loop until the remainder of the time between checks has passed + lastProcessTime = Game.GameTime; + } + + CollectedVehicle AddVehicleToCollection(Vehicle vehicle) + { + var collectedVehicle = new CollectedVehicle(vehicle, this); + CollectedVehicles.Add(collectedVehicle); + Logger.Log($"Added {vehicle.Model.Name} to collection from path {Number} waypoint {1}."); + return collectedVehicle; + } + + bool IsNearWaypoint(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) + { + if (v && v.Speed > 1 && v.IsOnAllWheels && v.IsEngineOn && v != Game.LocalPlayer.Character.CurrentVehicle && v != Game.LocalPlayer.Character.LastVehicle && (v.IsCar || v.IsBike || v.IsBicycle || v.IsQuadBike) && !v.IsSirenOn && !CollectedVehicles.Any(cv => cv?.Vehicle == v)) + { + var vehicleCollectedOnAnotherPath = PathMainMenu.paths.Any(p => p.Number != Number && p.CollectedVehicles.Any(cv => cv.Vehicle == v)); + if (vehicleCollectedOnAnotherPath) + { + return false; + } + if (v.HasDriver && v.Driver && !v.Driver.IsAlive) + { + return false; + } + if (!v.HasDriver) + { + v.CreateRandomDriver(); + while (!v.HasDriver) + { + GameFiber.Yield(); + } + if (v && v.Driver) + { + v.Driver.IsPersistent = true; + v.Driver.BlockPermanentEvents = true; + } + else + { + return false; + } + } + return true; + } + else + { + return false; + } + } + } } }