diff --git a/SceneManager/Objects/Path.cs b/SceneManager/Objects/Path.cs index ac59c7f..ffac48a 100644 --- a/SceneManager/Objects/Path.cs +++ b/SceneManager/Objects/Path.cs @@ -5,12 +5,15 @@ using System.Drawing; using System.Linq; using System.Xml.Serialization; using SceneManager.Utils; +using SceneManager.Menus; using System.IO; namespace SceneManager.Objects { - internal class Path // Change this to Public for import/export + [XmlRoot(ElementName = "Path", Namespace = "")] + public class Path // Change this to Public for import/export { + internal string Name { get; set; } internal int Number { get; set; } internal bool IsEnabled { get; set; } internal State State { get; set; } @@ -18,9 +21,8 @@ namespace SceneManager.Objects [XmlArray("Waypoints")] [XmlArrayItem("Waypoint")] public List Waypoints { get; set; } = new List(); - - internal List CollectedVehicles = new List(); - private List _blacklistedVehicles = new List(); + internal List CollectedVehicles { get; } = new List(); + private List BlacklistedVehicles { get; } = new List(); private Path() { } @@ -43,6 +45,18 @@ namespace SceneManager.Objects PathXMLManager.SaveItemToXML(this, SAVED_PATHS_DIRECTORY + filename); } + internal void Load() + { + State = State.Finished; + EnablePath(); + foreach(Waypoint waypoint in Waypoints) + { + waypoint.LoadFromImport(this); + } + DrawLinesBetweenWaypoints(); + PathManager.EndPath(this); + } + private void LowerWaypointBlipsOpacity() { foreach (Waypoint wp in Waypoints) @@ -77,7 +91,7 @@ namespace SceneManager.Objects { wp.RemoveSpeedZone(); } - if (SettingsMenu.mapBlips.Checked) + if (SettingsMenu.MapBlips.Checked) { LowerWaypointBlipsOpacity(); } @@ -93,7 +107,7 @@ namespace SceneManager.Objects wp.AddSpeedZone(); } } - if (SettingsMenu.mapBlips.Checked) + if (SettingsMenu.MapBlips.Checked) { RestoreWaypointBlipsOpacity(); } @@ -105,7 +119,7 @@ namespace SceneManager.Objects { while(true) { - if (SettingsMenu.threeDWaypoints.Checked && (State == State.Finished && MenuManager.menuPool.IsAnyMenuOpen()) || (State == State.Creating && PathCreationMenu.pathCreationMenu.Visible)) + if (SettingsMenu.ThreeDWaypoints.Checked && (State == State.Finished && MenuManager.MenuPool.IsAnyMenuOpen()) || (State == State.Creating && PathCreationMenu.Menu.Visible)) { for (int i = 0; i < Waypoints.Count; i++) { @@ -129,67 +143,57 @@ namespace SceneManager.Objects internal void LoopForVehiclesToBeDismissed() { - GameFiber.StartNew(() => + while (PathManager.Paths.Contains(this)) { - while (PathMainMenu.paths.Contains(this)) + //Logger.Log($"Dismissing unused vehicles for cleanup"); + foreach (CollectedVehicle cv in CollectedVehicles.Where(cv => cv.Vehicle && (!cv.Vehicle.IsDriveable || cv.Vehicle.IsUpsideDown || !cv.Vehicle.HasDriver))) { - //Logger.Log($"Dismissing unused vehicles for cleanup"); - foreach (CollectedVehicle cv in CollectedVehicles.Where(cv => cv.Vehicle)) + if (cv.Vehicle.HasDriver) { - if (!cv.Vehicle.IsDriveable || cv.Vehicle.IsUpsideDown || !cv.Vehicle.HasDriver) - { - if (cv.Vehicle.HasDriver) - { - cv.Vehicle.Driver.Dismiss(); - } - cv.Vehicle.Dismiss(); - } + cv.Vehicle.Driver.Dismiss(); } - - CollectedVehicles.RemoveAll(cv => !cv.Vehicle); - _blacklistedVehicles.RemoveAll(v => !v); - GameFiber.Sleep(60000); + cv.Vehicle.Dismiss(); } - }); + + CollectedVehicles.RemoveAll(cv => !cv.Vehicle); + BlacklistedVehicles.RemoveAll(v => !v); + GameFiber.Sleep(60000); + } } internal void LoopWaypointCollection() { uint lastProcessTime = Game.GameTime; // Store the last time the full loop finished; this is a value in ms int yieldAfterChecks = 50; // How many calculations to do before yielding - while (PathMainMenu.paths.Contains(this)) + while (PathManager.Paths.Contains(this)) { if (IsEnabled) { int checksDone = 0; try { - foreach (Waypoint waypoint in Waypoints) + foreach (Waypoint waypoint in Waypoints.Where(x => x != null && x.IsCollector)) { - if (waypoint != null & waypoint.IsCollector) + foreach (Vehicle v in World.GetAllVehicles()) { - foreach (Vehicle v in World.GetAllVehicles()) + if (VehicleIsValidForCollection(v) && VehicleIsNearWaypoint(v, waypoint)) { - if (VehicleIsNearWaypoint(v, waypoint) && VehicleIsValidForCollection(v)) - { - CollectedVehicle newCollectedVehicle = AddVehicleToCollection(v); - GameFiber AssignTasksFiber = new GameFiber(() => newCollectedVehicle.AssignWaypointTasks(this, waypoint)); - //GameFiber AssignTasksFiber = new GameFiber(() => AITasking.AssignWaypointTasks(newCollectedVehicle, this, waypoint)); - AssignTasksFiber.Start(); - } + CollectedVehicle newCollectedVehicle = AddVehicleToCollection(v); + GameFiber AssignTasksFiber = new GameFiber(() => newCollectedVehicle.AssignWaypointTasks(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 - } + 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 + catch(Exception ex) { - //return; + Game.LogTrivial($"Vehicle collection error: {ex}"); } } 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 @@ -211,9 +215,9 @@ namespace SceneManager.Objects bool VehicleIsValidForCollection(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) && !_blacklistedVehicles.Contains(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) && !BlacklistedVehicles.Contains(v)) { - var vehicleCollectedOnAnotherPath = PathMainMenu.paths.Any(p => p.Number != Number && p.CollectedVehicles.Any(cv => cv.Vehicle == v)); + var vehicleCollectedOnAnotherPath = PathManager.Paths.Any(p => p.Number != Number && p.CollectedVehicles.Any(cv => cv.Vehicle == v)); if (vehicleCollectedOnAnotherPath) { return false; @@ -223,12 +227,12 @@ namespace SceneManager.Objects if(!v.Driver.IsAlive) { Game.LogTrivial($"Vehicle's driver is dead."); - _blacklistedVehicles.Add(v); + BlacklistedVehicles.Add(v); return false; } if (v.IsPoliceVehicle && !v.Driver.IsAmbient()) { - _blacklistedVehicles.Add(v); + BlacklistedVehicles.Add(v); return false; } } @@ -257,5 +261,40 @@ namespace SceneManager.Objects } } } + + internal void Delete() + { + DismissCollectedDrivers(); + RemoveWaypoints(); + Game.LogTrivial($"Path {Number} deleted."); + } + + private void DismissCollectedDrivers() + { + List pathVehicles = CollectedVehicles.ToList(); // Have to enumerate over a copied list because you can't delete from the same list you're enumerating through + foreach (CollectedVehicle collectedVehicle in pathVehicles.Where(x => x != null && x.Vehicle && x.Driver)) + { + if (collectedVehicle.StoppedAtWaypoint) + { + Rage.Native.NativeFunction.Natives.x260BE8F09E326A20(collectedVehicle.Vehicle, 1f, 1, true); + } + if (collectedVehicle.Driver.GetAttachedBlip()) + { + collectedVehicle.Driver.GetAttachedBlip().Delete(); + } + collectedVehicle.Driver.Dismiss(); + collectedVehicle.Vehicle.IsSirenOn = false; + collectedVehicle.Vehicle.IsSirenSilent = true; + collectedVehicle.Vehicle.Dismiss(); + + CollectedVehicles.Remove(collectedVehicle); + } + } + + private void RemoveWaypoints() + { + Waypoints.ForEach(x => x.Delete()); + Waypoints.Clear(); + } } }