diff --git a/SceneManager/Object Classes/Waypoint.cs b/SceneManager/Object Classes/Waypoint.cs index 6c0cb13..92b4d30 100644 --- a/SceneManager/Object Classes/Waypoint.cs +++ b/SceneManager/Object Classes/Waypoint.cs @@ -1,4 +1,6 @@ using Rage; +using System; +using System.Collections.Generic; using System.Drawing; using System.Linq; @@ -77,7 +79,7 @@ namespace SceneManager if (IsStopWaypoint && !stopWaypoint) { Blip.Color = Color.Green; - foreach(CollectedVehicle cv in VehicleCollector.collectedVehicles.Where(cv => cv.Vehicle && cv.Path == Path && cv.CurrentWaypoint == this && cv.StoppedAtWaypoint)) + foreach(CollectedVehicle cv in Path.CollectedVehicles.Where(cv => cv.Vehicle && cv.Path == Path && cv.CurrentWaypoint == this && cv.StoppedAtWaypoint)) { // Logger.Log($"Setting StoppedAtWaypoint to false for {cv.Vehicle.Model.Name}"); cv.Dismiss(DismissOption.FromWaypoint); @@ -286,5 +288,102 @@ namespace SceneManager CollectorRadiusBlip.Alpha = 0; } } + + internal void CollectVehicles(List paths) + { + var sleepInterval = 1000; + Logger.Log($"Starting collection loop on waypoint {Number}"); + while (paths.Contains(Path) && Path.Waypoints.Contains(this)) + { + if (Path.IsEnabled && IsCollector) + { + sleepInterval = 100; + LoopForNearbyValidVehicles(); + } + else + { + sleepInterval = 1000; + } + + var collectedVehiclePlayerIsIn = Path.CollectedVehicles.Where(x => x.Vehicle == Game.LocalPlayer.Character.CurrentVehicle).FirstOrDefault(); + if (collectedVehiclePlayerIsIn != null) + { + collectedVehiclePlayerIsIn.Dismiss(DismissOption.FromPlayer); + Logger.Log($"Dismissed a collected vehicle the player was in."); + } + GameFiber.Sleep(sleepInterval); + } + + void LoopForNearbyValidVehicles() + { + foreach (Vehicle vehicle in GetNearbyVehiclesForCollection(Position, CollectorRadius)) + { + if (!vehicle) + { + break; + } + + var collectedVehicle = Path.CollectedVehicles.Where(cv => cv.Vehicle == vehicle).FirstOrDefault(); + if (collectedVehicle == null) + { + CollectedVehicle newCollectedVehicle = AddVehicleToCollection(vehicle); + //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)); + AssignTasksFiber.Start(); + } + } + + Vehicle[] GetNearbyVehiclesForCollection(Vector3 collectorWaypointPosition, float collectorRadius) + { + return (from v in World.GetAllVehicles() where v.FrontPosition.DistanceTo2D(collectorWaypointPosition) <= collectorRadius && Math.Abs(collectorWaypointPosition.Z - v.Position.Z) < 3 && IsValidForCollection(v) select v).ToArray(); + } + } + + CollectedVehicle AddVehicleToCollection(Vehicle vehicle) + { + var collectedVehicle = new CollectedVehicle(vehicle, Path, this); + Path.CollectedVehicles.Add(collectedVehicle); + Logger.Log($"Added {vehicle.Model.Name} to collection from path {Path.Number} waypoint {this.Number}."); + return collectedVehicle; + } + + bool IsValidForCollection(Vehicle v) + { + if (v && v.Speed > 1 && v.IsOnAllWheels && v.IsEngineOn && v != Game.LocalPlayer.Character.CurrentVehicle && v != Game.LocalPlayer.Character.LastVehicle && (v.IsCar || v.IsBike || v.IsBicycle || v.IsQuadBike) && !v.IsSirenOn && !Path.CollectedVehicles.Any(cv => cv?.Vehicle == v)) + { + var vehicleCollectedOnAnotherPath = paths.Any(p => p.Number != Path.Number && p.CollectedVehicles.Any(cv => cv.Vehicle == v)); + if (vehicleCollectedOnAnotherPath) + { + return false; + } + if (v.HasDriver && v.Driver && !v.Driver.IsAlive) + { + return false; + } + if (!v.HasDriver) + { + v.CreateRandomDriver(); + while (!v.HasDriver) + { + GameFiber.Yield(); + } + if (v && v.Driver) + { + v.Driver.IsPersistent = true; + v.Driver.BlockPermanentEvents = true; + } + else + { + return false; + } + } + return true; + } + else + { + return false; + } + } + } } }