From d0e2c3f99eeb6588dfa30e09fbaf8287320e2d3f Mon Sep 17 00:00:00 2001 From: RMROC451 Date: Thu, 20 Jun 2024 17:41:50 -0500 Subject: [PATCH 1/4] #12 add configurable column for fuel status tracking in engine roster --- Directory.Build.targets | 2 +- .../Enums/EngineRosterFuelDisplayColumn.cs | 9 ++ TweaksAndThings/Patches/Car_SetIdent_Patch.cs | 122 ++++++++++++++++++ .../Patches/ExpandedConsole_Patch.cs | 7 +- .../RMROC451.TweaksAndThings.csproj | 1 + TweaksAndThings/Settings.cs | 58 --------- TweaksAndThings/Settings/Settings.cs | 76 +++++++++++ TweaksAndThings/TweaksAndThings.cs | 52 +++++++- 8 files changed, 257 insertions(+), 70 deletions(-) create mode 100644 TweaksAndThings/Enums/EngineRosterFuelDisplayColumn.cs create mode 100644 TweaksAndThings/Patches/Car_SetIdent_Patch.cs delete mode 100644 TweaksAndThings/Settings.cs create mode 100644 TweaksAndThings/Settings/Settings.cs diff --git a/Directory.Build.targets b/Directory.Build.targets index 96fab01..ce06d73 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -12,7 +12,7 @@ 0 1 - 4 + 5 $(MajorVersion).$(MinorVersion).$(PatchVersion) $(AssemblyVersion) $(AssemblyVersion) diff --git a/TweaksAndThings/Enums/EngineRosterFuelDisplayColumn.cs b/TweaksAndThings/Enums/EngineRosterFuelDisplayColumn.cs new file mode 100644 index 0000000..df06b96 --- /dev/null +++ b/TweaksAndThings/Enums/EngineRosterFuelDisplayColumn.cs @@ -0,0 +1,9 @@ +namespace TweaksAndThings.Enums; + +public enum EngineRosterFuelDisplayColumn +{ + None, + Engine, + Crew, + Status +} diff --git a/TweaksAndThings/Patches/Car_SetIdent_Patch.cs b/TweaksAndThings/Patches/Car_SetIdent_Patch.cs new file mode 100644 index 0000000..2d5944b --- /dev/null +++ b/TweaksAndThings/Patches/Car_SetIdent_Patch.cs @@ -0,0 +1,122 @@ +using HarmonyLib; +using Model; +using Model.Definition; +using Model.Definition.Data; +using Model.OpsNew; +using Model.Physics; +using Railloader; +using RMROC451.TweaksAndThings.Settings; +using Serilog; +using System; +using System.Collections.Generic; +using System.Linq; +using TMPro; +using TweaksAndThings.Enums; +using UI; +using UI.Builder; +using UI.EngineRoster; +using UI.Tooltips; +using UnityEngine; +using static Model.Car; + + +namespace TweaksAndThings.Patches; + +[HarmonyPatch(typeof(EngineRosterRow))] +[HarmonyPatch(nameof(EngineRosterRow.Refresh))] +[HarmonyPatchCategory("RMROC451TweaksAndThings")] +public class EngineRosterRow_Refresh_Patch +{ + public static void Postfix(EngineRosterRow __instance) + { + TweaksAndThings? tweaksAndThings = SingletonPluginBase.Shared; + RosterFuelColumnSettings? rosterFuelColumnSettings = tweaksAndThings?.settings?.EngineRosterFuelColumnSettings; + + if (tweaksAndThings == null || + rosterFuelColumnSettings == null || + !tweaksAndThings.IsEnabled || + rosterFuelColumnSettings.EngineRosterFuelStatusColumn == EngineRosterFuelDisplayColumn.None || (!GameInput.IsAltDown && !rosterFuelColumnSettings.EngineRosterShowsFuelStatusAlways)) + { + return; + } + + try + { + string fuelInfoText = string.Empty; + string fuelInfoTooltip = string.Empty; + Car engineOrTender = __instance._engine; + List loadSlots = __instance._engine.Definition.LoadSlots; + if (!loadSlots.Any()) + { + engineOrTender = DetermineFuelCar(__instance._engine); + loadSlots = engineOrTender != null ? engineOrTender.Definition.LoadSlots : Enumerable.Empty().ToList(); + } + + var offender = loadSlots.OrderBy(ls => (engineOrTender.GetLoadInfo(ls.RequiredLoadIdentifier, out int slotIndex)?.Quantity ?? 0) / loadSlots[slotIndex].MaximumCapacity).FirstOrDefault().RequiredLoadIdentifier; + + for (int i = 0; i < loadSlots.Count; i++) + { + CarLoadInfo? loadInfo = engineOrTender.GetLoadInfo(i); + if (loadInfo.HasValue) + { + CarLoadInfo valueOrDefault = loadInfo.GetValueOrDefault(); + var fuelLevel = FuelLevel(valueOrDefault.Quantity, loadSlots[i].MaximumCapacity); + fuelInfoText += loadSlots[i].RequiredLoadIdentifier == offender ? fuelLevel + " " : string.Empty; + //fuelInfoText += TextSprites.PiePercent(valueOrDefault.Quantity, loadSlots[i].MaximumCapacity) + " "; + fuelInfoTooltip += $"{TextSprites.PiePercent(valueOrDefault.Quantity, loadSlots[i].MaximumCapacity)} {valueOrDefault.LoadString(CarPrototypeLibrary.instance.LoadForId(valueOrDefault.LoadId))}\n"; + } + } + + switch (rosterFuelColumnSettings.EngineRosterFuelStatusColumn) + { + case EngineRosterFuelDisplayColumn.Engine: + SetLabelAndTooltip(ref __instance.nameLabel, ref __instance.nameTooltip, fuelInfoText, fuelInfoTooltip); + break; + case EngineRosterFuelDisplayColumn.Crew: + SetLabelAndTooltip(ref __instance.crewLabel, ref __instance.crewTooltip, fuelInfoText, fuelInfoTooltip); + break; + case EngineRosterFuelDisplayColumn.Status: + SetLabelAndTooltip(ref __instance.infoLabel, ref __instance.infoTooltip, fuelInfoText, fuelInfoTooltip); + break; + default: + break; + } + + } catch (Exception ex) + { + rosterFuelColumnSettings.EngineRosterFuelStatusColumn = EngineRosterFuelDisplayColumn.None; + Log.Error(ex, "Error Detecting fuel status for engine roster"); + } + } + + private static void SetLabelAndTooltip(ref TMP_Text label, ref UITooltipProvider tooltip, string fuelInfoText, string fuelInfoTooltip) + { + label.text = $" {fuelInfoText} {label.text}"; + tooltip.TooltipInfo = new TooltipInfo(tooltip.tooltipTitle, fuelInfoTooltip); + } + + public static string FuelLevel(float quantity, float capacity) + { + float num = capacity <= 0f ? 0 : Mathf.Clamp(quantity / capacity * 100, 0, 100); + + return $"{Mathf.FloorToInt(num):D2}%"; + } + + public static Car DetermineFuelCar(BaseLocomotive engine) + { + Car car; + if (engine is SteamLocomotive steamLocomotive && new Func(steamLocomotive.FuelCar) != null) + { + car = steamLocomotive.FuelCar(); + } + else + { + if (!(engine is DieselLocomotive)) + { + throw new InvalidOperationException($"Unable to detect locomotive fuel source for {engine}"); + } + car = engine; + } + return car; + } +} diff --git a/TweaksAndThings/Patches/ExpandedConsole_Patch.cs b/TweaksAndThings/Patches/ExpandedConsole_Patch.cs index 98fb6c4..8579666 100644 --- a/TweaksAndThings/Patches/ExpandedConsole_Patch.cs +++ b/TweaksAndThings/Patches/ExpandedConsole_Patch.cs @@ -4,6 +4,7 @@ using HarmonyLib; using Helpers; using Newtonsoft.Json; using Railloader; +using RMROC451.TweaksAndThings.Settings; using Serilog; using System; using System.Collections.Generic; @@ -35,9 +36,7 @@ public class ExpandedConsole_Add_Patch TweaksAndThings tweaksAndThings = SingletonPluginBase.Shared; StateManager shared = StateManager.Shared; GameStorage gameStorage = shared.Storage; - WebhookSettings settings = tweaksAndThings.settings.WebhookSettingsList.FirstOrDefault(ws => ws.RailroadMark == gameStorage.RailroadMark); - - Log.Information(entry.Text); + WebhookSettings settings = tweaksAndThings?.settings?.WebhookSettingsList?.FirstOrDefault(ws => ws.RailroadMark == gameStorage.RailroadMark); if ( settings != null && @@ -50,7 +49,6 @@ public class ExpandedConsole_Add_Patch var carId = t.IsMatch(entry.Text) ? Regex.Match(entry.Text, "car:(.*?)\"").Groups[1].Captures[0].ToString() : string.Empty; Model.Car? car = TrainController.Shared.CarForString(carId); - Log.Information($"|{carId}| {car?.IsLocomotive}"); bool engineInMessage = car?.IsLocomotive ?? false; var image = engineInMessage ? new @@ -91,7 +89,6 @@ public class ExpandedConsole_Add_Patch } }; string EndPoint = settings.WebhookUrl; - Log.Information(JsonConvert.SerializeObject(SuccessWebHook)); var content = new StringContent(JsonConvert.SerializeObject(SuccessWebHook), Encoding.UTF8, "application/json"); diff --git a/TweaksAndThings/RMROC451.TweaksAndThings.csproj b/TweaksAndThings/RMROC451.TweaksAndThings.csproj index af81fa5..ccf421d 100644 --- a/TweaksAndThings/RMROC451.TweaksAndThings.csproj +++ b/TweaksAndThings/RMROC451.TweaksAndThings.csproj @@ -11,6 +11,7 @@ + diff --git a/TweaksAndThings/Settings.cs b/TweaksAndThings/Settings.cs deleted file mode 100644 index fc92a17..0000000 --- a/TweaksAndThings/Settings.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Newtonsoft.Json; -using System.IO; -using System.Runtime; -using System; -using Serilog; -using System.Collections.Generic; -using System.Linq; - -namespace TweaksAndThings; - -public class Settings -{ - - public Settings() - { - WebhookSettingsList = new[] { new WebhookSettings() }.ToList(); - } - - public Settings( - List webhookSettingsList, - bool handBrakeAndAirTagModifiers - ) - { - this.WebhookSettingsList = webhookSettingsList; - this.HandBrakeAndAirTagModifiers = handBrakeAndAirTagModifiers; - } - - public List WebhookSettingsList; - public bool HandBrakeAndAirTagModifiers; - - internal void AddAnotherRow() - { - if (!string.IsNullOrEmpty(WebhookSettingsList.Last().WebhookUrl)) - { - WebhookSettingsList.Add(new()); - Log.Information($"Adding another {nameof(WebhookSettings)} list entry, last one was filled in"); - } - } -} - -public class WebhookSettings -{ - public WebhookSettings() { } - public WebhookSettings( - bool webhookEnabled, - string railroadMark, - string webhookUrl - ) - { - this.WebhookEnabled = webhookEnabled; - this.RailroadMark = railroadMark; - this.WebhookUrl = webhookUrl; - } - - public bool WebhookEnabled = false; - public string RailroadMark = string.Empty; - public string WebhookUrl = string.Empty; -} \ No newline at end of file diff --git a/TweaksAndThings/Settings/Settings.cs b/TweaksAndThings/Settings/Settings.cs new file mode 100644 index 0000000..2e7ae63 --- /dev/null +++ b/TweaksAndThings/Settings/Settings.cs @@ -0,0 +1,76 @@ +using Serilog; +using System.Collections.Generic; +using System.Linq; +using TweaksAndThings.Enums; + +namespace RMROC451.TweaksAndThings.Settings; + +public class Settings +{ + + public Settings() + { + WebhookSettingsList = new[] { new WebhookSettings() }.ToList(); + EngineRosterFuelColumnSettings = new(); + } + + public Settings( + List webhookSettingsList, + bool handBrakeAndAirTagModifiers, + RosterFuelColumnSettings engineRosterFuelColumnSettings + ) + { + WebhookSettingsList = webhookSettingsList; + HandBrakeAndAirTagModifiers = handBrakeAndAirTagModifiers; + EngineRosterFuelColumnSettings = engineRosterFuelColumnSettings; + } + + public List? WebhookSettingsList; + public bool HandBrakeAndAirTagModifiers; + public RosterFuelColumnSettings? EngineRosterFuelColumnSettings; + + internal void AddAnotherRow() + { + WebhookSettingsList = !WebhookSettingsList?.Any() ?? false ? new[] { new WebhookSettings() }.ToList() : new List(); + if (!string.IsNullOrEmpty(WebhookSettingsList.OrderByDescending(wsl => wsl.WebhookUrl).Last().WebhookUrl)) + { + WebhookSettingsList.Add(new()); + Log.Information($"Adding another {nameof(WebhookSettings)} list entry, last one was filled in"); + } + } +} + +public class WebhookSettings +{ + public WebhookSettings() { } + public WebhookSettings( + bool webhookEnabled, + string railroadMark, + string webhookUrl + ) + { + WebhookEnabled = webhookEnabled; + RailroadMark = railroadMark; + WebhookUrl = webhookUrl; + } + + public bool WebhookEnabled = false; + public string RailroadMark = string.Empty; + public string WebhookUrl = string.Empty; +} + +public class RosterFuelColumnSettings +{ + public RosterFuelColumnSettings() { } + public RosterFuelColumnSettings( + bool engineRosterShowsFuelStatusAlways, + EngineRosterFuelDisplayColumn engineRosterFuelStatusColumn + ) + { + this.EngineRosterShowsFuelStatusAlways = engineRosterShowsFuelStatusAlways; + this.EngineRosterFuelStatusColumn = engineRosterFuelStatusColumn; + } + + public bool EngineRosterShowsFuelStatusAlways; + public EngineRosterFuelDisplayColumn EngineRosterFuelStatusColumn; +} \ No newline at end of file diff --git a/TweaksAndThings/TweaksAndThings.cs b/TweaksAndThings/TweaksAndThings.cs index c7800d1..6e7fea5 100644 --- a/TweaksAndThings/TweaksAndThings.cs +++ b/TweaksAndThings/TweaksAndThings.cs @@ -2,10 +2,14 @@ using Game.State; using HarmonyLib; using Railloader; +using RMROC451.TweaksAndThings.Settings; using Serilog; +using System; using System.Linq; using System.Net.Http; +using TweaksAndThings.Enums; using UI.Builder; +using static Model.Car; namespace TweaksAndThings { @@ -43,12 +47,6 @@ namespace TweaksAndThings //moddingContext.RegisterConsoleCommand(new EchoCommand()); settings = moddingContext.LoadSettingsData(self.Id); - if (!settings?.WebhookSettingsList?.Any() ?? true) - { - if (settings == null) settings = new(); - settings.WebhookSettingsList = new[] { new WebhookSettings() }.ToList(); - this.moddingContext.SaveSettingsData(this.modDefinition.Id, settings ?? new()); - } } public override void OnEnable() @@ -73,11 +71,53 @@ namespace TweaksAndThings public void ModTabDidOpen(UIPanelBuilder builder) { logger.Information("Daytime!"); + + if (!settings?.WebhookSettingsList?.Any() ?? true) + { + if (settings == null) settings = new(); + settings.WebhookSettingsList = new[] { new WebhookSettings() }.ToList(); + settings.EngineRosterFuelColumnSettings = new(); + } + //WebhookUISection(ref builder); //builder.AddExpandingVerticalSpacer(); WebhooksListUISection(ref builder); builder.AddExpandingVerticalSpacer(); HandbrakesAndAnglecocksUISection(ref builder); + builder.AddExpandingVerticalSpacer(); + EnginRosterShowsFuelStatusUISection(ref builder); + } + + private void EnginRosterShowsFuelStatusUISection(ref UIPanelBuilder builder) + { + var columns = Enum.GetValues(typeof(EngineRosterFuelDisplayColumn)).Cast().Select(i => i.ToString()).ToList(); + builder.AddSection("Fuel Display in Engine Roster", delegate (UIPanelBuilder builder) + { + builder.AddField( + "Enable", + builder.AddDropdown(columns, (int)(settings?.EngineRosterFuelColumnSettings?.EngineRosterFuelStatusColumn ?? EngineRosterFuelDisplayColumn.None), + delegate (int column) + { + if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList(), EngineRosterFuelColumnSettings = new() }; + settings.EngineRosterFuelColumnSettings.EngineRosterFuelStatusColumn = (EngineRosterFuelDisplayColumn)column; + builder.Rebuild(); + } + ) + ).Tooltip("Enable Fuel Display in Engine Roster", $"Will add remaing fuel indication to Engine Roster (with details in roster row tooltip), Examples : {string.Join(" ", Enumerable.Range(0,4).Select(i => TextSprites.PiePercent(i, 4)))}"); + + builder.AddField( + "Always Visible?", + builder.AddToggle( + () => settings?.EngineRosterFuelColumnSettings?.EngineRosterShowsFuelStatusAlways ?? false, + delegate (bool enabled) + { + if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList(), EngineRosterFuelColumnSettings = new() }; + settings.EngineRosterFuelColumnSettings.EngineRosterShowsFuelStatusAlways = enabled; + builder.Rebuild(); + } + ) + ).Tooltip("Fuel Display in Engine Roster Always Visible", $"Always displayed, if you want it hidden and only shown when you care to see, uncheck this, and then you can press ALT for it to populate on the next UI refresh cycle."); + }); } private void HandbrakesAndAnglecocksUISection(ref UIPanelBuilder builder) From d780b075dc630364a84d9f62810537d1a6b1c671 Mon Sep 17 00:00:00 2001 From: RMROC451 Date: Thu, 20 Jun 2024 17:44:45 -0500 Subject: [PATCH 2/4] #12 updated the ModTabDidOpen logic for the new column section. --- TweaksAndThings/TweaksAndThings.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/TweaksAndThings/TweaksAndThings.cs b/TweaksAndThings/TweaksAndThings.cs index 6e7fea5..44477d9 100644 --- a/TweaksAndThings/TweaksAndThings.cs +++ b/TweaksAndThings/TweaksAndThings.cs @@ -72,12 +72,9 @@ namespace TweaksAndThings { logger.Information("Daytime!"); - if (!settings?.WebhookSettingsList?.Any() ?? true) - { - if (settings == null) settings = new(); - settings.WebhookSettingsList = new[] { new WebhookSettings() }.ToList(); - settings.EngineRosterFuelColumnSettings = new(); - } + if (settings == null) settings = new(); + if (!settings?.WebhookSettingsList?.Any() ?? true) settings.WebhookSettingsList = new[] { new WebhookSettings() }.ToList(); + if (settings?.EngineRosterFuelColumnSettings == null) settings.EngineRosterFuelColumnSettings = new(); //WebhookUISection(ref builder); //builder.AddExpandingVerticalSpacer(); From 1ea3d9917d175ebe6b4948fa06992c7760c5ce9b Mon Sep 17 00:00:00 2001 From: RMROC451 Date: Thu, 20 Jun 2024 21:41:56 -0500 Subject: [PATCH 3/4] spell checking, fixing #14 and some other pieces needed for #14. --- README.md | 6 +- .../Enums/EngineRosterFuelDisplayColumn.cs | 2 +- TweaksAndThings/Enums/MrocHelperType.cs | 2 +- TweaksAndThings/Extensions/Car_Extensions.cs | 40 ++ .../CarInspector_PopulateCarPanel_Patch.cs | 21 +- ...ch.cs => EngineRosterRow_Refresh_Patch.cs} | 30 +- .../Patches/ExpandedConsole_Patch.cs | 3 +- .../Patches/TagController_UpdateTag_Patch.cs | 23 +- TweaksAndThings/Settings/Settings.cs | 4 +- TweaksAndThings/TweaksAndThings.cs | 376 +++++++++--------- 10 files changed, 259 insertions(+), 248 deletions(-) create mode 100644 TweaksAndThings/Extensions/Car_Extensions.cs rename TweaksAndThings/Patches/{Car_SetIdent_Patch.cs => EngineRosterRow_Refresh_Patch.cs} (84%) diff --git a/README.md b/README.md index 61541d2..8911242 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This mod requires Railloader by Zamu. 3. Run the game and enjoy all of the tweaks and things! ## Notes -1. This mod currently supports Railroader verison 2024.4.4. This mod may break in future updates. I will do my best to continue to update this mod. +1. This mod currently supports Railroader version 2024.4.4. This mod may break in future updates. I will do my best to continue to update this mod. 2. It is possible that the developers of Railroader will implement their own fix for this issue. At such time this mod will be deprecated and no longer maintained. 3. As the saying goes, use mods at your own risk. @@ -29,13 +29,13 @@ This mod requires Railloader by Zamu. **PLEASE READ AS THE WAY THIS MOD FUNCTIONS HAS CHANGED FROM PRIOR VERSIONS** 1. Car Inspector : Handbrake & Air Line Helper - * Gives two buttons that will scan the current car's connections, including the whole consist, and automatically release handbrakes, set anglecocks and connect glad hands. + * Gives two buttons that will scan the current car's connections, including the whole consist, and automatically release hand brakes, set anglecocks and connect glad hands. 2. Car Tag Updates * Shows an indication of which cars in the FOV have Air System or Handbrake issues. * **hold SHIFT** to only show the tags in the FOV for cars with an issue! 3. Discord Webhooks * Allows the console messages to post to a discord webhook. useful for those wanting to keep an eye on 24/7 hosted saves. - * Locomotive messages grab the locomotive `Ident.RoadNumber` and check the `CTC Panel Markers` if they exist. If found, they will use the red/green color and embed the locmotive as an image in the message. If no marker is found, it defaults to blue. + * Locomotive messages grab the locomotive `Ident.RoadNumber` and check the `CTC Panel Markers` if they exist. If found, they will use the red/green color and embed the locomotive as an image in the message. If no marker is found, it defaults to blue. * Currently, One person per server should have this per discord webhook, otherwise you will get duplicate messages to the webhook. * **Multiple hooks**: Allows for many different webhooks per client to be setup, and filtered to the `Ident.ReportingMark` so you can get messages to different hooks based on what save/server you are playing on. * **Customizable** from the in-game Railloader settings, find `RMROC451.TweaksAndThings` diff --git a/TweaksAndThings/Enums/EngineRosterFuelDisplayColumn.cs b/TweaksAndThings/Enums/EngineRosterFuelDisplayColumn.cs index df06b96..ca0b9cc 100644 --- a/TweaksAndThings/Enums/EngineRosterFuelDisplayColumn.cs +++ b/TweaksAndThings/Enums/EngineRosterFuelDisplayColumn.cs @@ -1,4 +1,4 @@ -namespace TweaksAndThings.Enums; +namespace RMROC451.TweaksAndThings.Enums; public enum EngineRosterFuelDisplayColumn { diff --git a/TweaksAndThings/Enums/MrocHelperType.cs b/TweaksAndThings/Enums/MrocHelperType.cs index bdca199..27bceb0 100644 --- a/TweaksAndThings/Enums/MrocHelperType.cs +++ b/TweaksAndThings/Enums/MrocHelperType.cs @@ -1,4 +1,4 @@ -namespace TweaksAndThings.Enums; +namespace RMROC451.TweaksAndThings.Enums; public enum MrocHelperType { diff --git a/TweaksAndThings/Extensions/Car_Extensions.cs b/TweaksAndThings/Extensions/Car_Extensions.cs new file mode 100644 index 0000000..6415c92 --- /dev/null +++ b/TweaksAndThings/Extensions/Car_Extensions.cs @@ -0,0 +1,40 @@ +using Model; +using System; + +namespace RMROC451.TweaksAndThings.Extensions +{ + public static class Car_Extensions + { + public static bool EndAirSystemIssue(this Car car) + { + bool AEndAirSystemIssue = car[Car.LogicalEnd.A].IsCoupled && !car[Car.LogicalEnd.A].IsAirConnectedAndOpen; + bool BEndAirSystemIssue = car[Car.LogicalEnd.B].IsCoupled && !car[Car.LogicalEnd.B].IsAirConnectedAndOpen; + bool EndAirSystemIssue = AEndAirSystemIssue || BEndAirSystemIssue; + return EndAirSystemIssue; + } + + public static bool HandbrakeApplied(this Model.Car car) => + car.air.handbrakeApplied; + + public static bool CarOrEndGearIssue(this Model.Car car) => + car.EndAirSystemIssue() || car.HandbrakeApplied(); + + public static bool CarAndEndGearIssue(this Model.Car car) => + car.EndAirSystemIssue() && car.HandbrakeApplied(); + + public static Car? DetermineFuelCar(this Car engine, bool returnEngineIfNull = false) + { + Car? car; + if (engine is SteamLocomotive steamLocomotive && new Func(steamLocomotive.FuelCar) != null) + { + car = steamLocomotive.FuelCar(); + } + else + { + car = engine is DieselLocomotive ? engine : null; + if (returnEngineIfNull && car == null) car = engine; + } + return car; + } + } +} diff --git a/TweaksAndThings/Patches/CarInspector_PopulateCarPanel_Patch.cs b/TweaksAndThings/Patches/CarInspector_PopulateCarPanel_Patch.cs index 42efc20..aba4344 100644 --- a/TweaksAndThings/Patches/CarInspector_PopulateCarPanel_Patch.cs +++ b/TweaksAndThings/Patches/CarInspector_PopulateCarPanel_Patch.cs @@ -3,16 +3,17 @@ using Game.State; using HarmonyLib; using KeyValue.Runtime; using Railloader; +using RMROC451.TweaksAndThings.Enums; +using RMROC451.TweaksAndThings.Extensions; using Serilog; using System; using System.Collections.Generic; using System.Linq; -using TweaksAndThings.Enums; using UI.Builder; using UI.CarInspector; using static Model.Car; -namespace TweaksAndThings.Patches; +namespace RMROC451.TweaksAndThings.Patches; [HarmonyPatch(typeof(CarInspector))] [HarmonyPatch(nameof(CarInspector.PopulateCarPanel), typeof(UIPanelBuilder))] @@ -22,7 +23,7 @@ public class CarInspector_PopulateCarPanel_Patch private static IEnumerable ends = Enum.GetValues(typeof(LogicalEnd)).Cast(); /// - /// If a caboose inspector is opened, it will auto set Anglecocks, gladhands and handbrakes + /// If a caboose inspector is opened, it will auto set Anglecocks, gladhands and hand brakes /// /// /// @@ -90,6 +91,16 @@ public class CarInspector_PopulateCarPanel_Patch return builder; } + //var dh = new DownloadHandlerAudioClip($"file://{cacheFileName}", AudioType.MPEG); + //dh.compressed = true; // This + + //using (UnityWebRequest wr = new UnityWebRequest($"file://{cacheFileName}", "GET", dh, null)) { + // yield return wr.SendWebRequest(); + // if (wr.responseCode == 200) { + // audioSource.clip = dh.audioClip; + // } + //} + public static void MrocConsistHelper(Model.Car car, MrocHelperType mrocHelperType) { IEnumerable consist = car.EnumerateCoupled(LogicalEnd.A); @@ -104,7 +115,9 @@ public class CarInspector_PopulateCarPanel_Patch } else { TrainController tc = UnityEngine.Object.FindObjectOfType(); - tc.ApplyHandbrakesAsNeeded(consist.ToList(), PlaceTrainHandbrakes.Automatic); + + //when ApplyHandbrakesAsNeeded is called, and the consist contains an engine, it stops applying brakes. + tc.ApplyHandbrakesAsNeeded(consist.Where(c => c.DetermineFuelCar(true) != null).ToList(), PlaceTrainHandbrakes.Automatic); } break; diff --git a/TweaksAndThings/Patches/Car_SetIdent_Patch.cs b/TweaksAndThings/Patches/EngineRosterRow_Refresh_Patch.cs similarity index 84% rename from TweaksAndThings/Patches/Car_SetIdent_Patch.cs rename to TweaksAndThings/Patches/EngineRosterRow_Refresh_Patch.cs index 2d5944b..6906bb7 100644 --- a/TweaksAndThings/Patches/Car_SetIdent_Patch.cs +++ b/TweaksAndThings/Patches/EngineRosterRow_Refresh_Patch.cs @@ -1,26 +1,22 @@ using HarmonyLib; using Model; -using Model.Definition; using Model.Definition.Data; using Model.OpsNew; -using Model.Physics; using Railloader; -using RMROC451.TweaksAndThings.Settings; +using RMROC451.TweaksAndThings.Extensions; using Serilog; using System; using System.Collections.Generic; using System.Linq; using TMPro; -using TweaksAndThings.Enums; +using RMROC451.TweaksAndThings.Enums; using UI; -using UI.Builder; using UI.EngineRoster; using UI.Tooltips; using UnityEngine; -using static Model.Car; -namespace TweaksAndThings.Patches; +namespace RMROC451.TweaksAndThings.Patches; [HarmonyPatch(typeof(EngineRosterRow))] [HarmonyPatch(nameof(EngineRosterRow.Refresh))] @@ -48,7 +44,7 @@ public class EngineRosterRow_Refresh_Patch List loadSlots = __instance._engine.Definition.LoadSlots; if (!loadSlots.Any()) { - engineOrTender = DetermineFuelCar(__instance._engine); + engineOrTender = __instance._engine.DetermineFuelCar()!; loadSlots = engineOrTender != null ? engineOrTender.Definition.LoadSlots : Enumerable.Empty().ToList(); } @@ -101,22 +97,4 @@ public class EngineRosterRow_Refresh_Patch return $"{Mathf.FloorToInt(num):D2}%"; } - - public static Car DetermineFuelCar(BaseLocomotive engine) - { - Car car; - if (engine is SteamLocomotive steamLocomotive && new Func(steamLocomotive.FuelCar) != null) - { - car = steamLocomotive.FuelCar(); - } - else - { - if (!(engine is DieselLocomotive)) - { - throw new InvalidOperationException($"Unable to detect locomotive fuel source for {engine}"); - } - car = engine; - } - return car; - } } diff --git a/TweaksAndThings/Patches/ExpandedConsole_Patch.cs b/TweaksAndThings/Patches/ExpandedConsole_Patch.cs index 8579666..cc6740a 100644 --- a/TweaksAndThings/Patches/ExpandedConsole_Patch.cs +++ b/TweaksAndThings/Patches/ExpandedConsole_Patch.cs @@ -4,7 +4,6 @@ using HarmonyLib; using Helpers; using Newtonsoft.Json; using Railloader; -using RMROC451.TweaksAndThings.Settings; using Serilog; using System; using System.Collections.Generic; @@ -15,7 +14,7 @@ using System.Text.RegularExpressions; using Track.Signals.Panel; using UI.Console; -namespace TweaksAndThings.Patches; +namespace RMROC451.TweaksAndThings.Patches; [HarmonyPatch(typeof(ExpandedConsole))] [HarmonyPatch(nameof(ExpandedConsole.Add))] diff --git a/TweaksAndThings/Patches/TagController_UpdateTag_Patch.cs b/TweaksAndThings/Patches/TagController_UpdateTag_Patch.cs index c123f3c..acd0eb4 100644 --- a/TweaksAndThings/Patches/TagController_UpdateTag_Patch.cs +++ b/TweaksAndThings/Patches/TagController_UpdateTag_Patch.cs @@ -2,11 +2,12 @@ using Model; using Model.OpsNew; using Railloader; +using RMROC451.TweaksAndThings.Extensions; using UI; using UI.Tags; using UnityEngine; -namespace TweaksAndThings.Patches; +namespace RMROC451.TweaksAndThings.Patches; [HarmonyPatch(typeof(TagController))] [HarmonyPatch(nameof(TagController.UpdateTag), typeof(Car), typeof(TagCallout), typeof(OpsController))] @@ -55,23 +56,3 @@ public class TagController_UpdateTag_Patch }; } } - -public static class ModelCarExtensions -{ - public static bool EndAirSystemIssue(this Model.Car car) - { - bool AEndAirSystemIssue = car[Car.LogicalEnd.A].IsCoupled && !car[Car.LogicalEnd.A].IsAirConnectedAndOpen; - bool BEndAirSystemIssue = car[Car.LogicalEnd.B].IsCoupled && !car[Car.LogicalEnd.B].IsAirConnectedAndOpen; - bool EndAirSystemIssue = AEndAirSystemIssue || BEndAirSystemIssue; - return EndAirSystemIssue; - } - - public static bool HandbrakeApplied(this Model.Car car) => - car.air.handbrakeApplied; - - public static bool CarOrEndGearIssue(this Model.Car car) => - car.EndAirSystemIssue() || car.HandbrakeApplied(); - - public static bool CarAndEndGearIssue(this Model.Car car) => - car.EndAirSystemIssue() && car.HandbrakeApplied(); -} diff --git a/TweaksAndThings/Settings/Settings.cs b/TweaksAndThings/Settings/Settings.cs index 2e7ae63..f90685f 100644 --- a/TweaksAndThings/Settings/Settings.cs +++ b/TweaksAndThings/Settings/Settings.cs @@ -1,9 +1,9 @@ using Serilog; using System.Collections.Generic; using System.Linq; -using TweaksAndThings.Enums; +using RMROC451.TweaksAndThings.Enums; -namespace RMROC451.TweaksAndThings.Settings; +namespace RMROC451.TweaksAndThings; public class Settings { diff --git a/TweaksAndThings/TweaksAndThings.cs b/TweaksAndThings/TweaksAndThings.cs index 44477d9..fe59771 100644 --- a/TweaksAndThings/TweaksAndThings.cs +++ b/TweaksAndThings/TweaksAndThings.cs @@ -1,204 +1,204 @@ -using GalaSoft.MvvmLight.Messaging; +// Ignore Spelling: RMROC + +using GalaSoft.MvvmLight.Messaging; using Game.State; using HarmonyLib; using Railloader; -using RMROC451.TweaksAndThings.Settings; using Serilog; using System; using System.Linq; using System.Net.Http; -using TweaksAndThings.Enums; using UI.Builder; -using static Model.Car; -namespace TweaksAndThings +using RMROC451.TweaksAndThings.Enums; + +namespace RMROC451.TweaksAndThings; + +public class TweaksAndThings : SingletonPluginBase, IUpdateHandler, IModTabHandler { - public class TweaksAndThings : SingletonPluginBase, IUpdateHandler, IModTabHandler + private HttpClient client; + internal HttpClient Client { - private HttpClient client; - internal HttpClient Client + get { - get - { - if (client == null) - client = new HttpClient(); + if (client == null) + client = new HttpClient(); - return client; - } - } - internal Settings? settings { get; private set; } = null; - readonly ILogger logger = Log.ForContext(); - IModdingContext moddingContext { get; set; } - IModDefinition modDefinition { get; set; } - - static TweaksAndThings() - { - Log.Information("Hello! Static Constructor was called!"); - } - - public TweaksAndThings(IModdingContext moddingContext, IModDefinition self) - { - this.modDefinition = self; - - this.moddingContext = moddingContext; - - logger.Information("Hello! Constructor was called for {modId}/{modVersion}!", self.Id, self.Version); - - //moddingContext.RegisterConsoleCommand(new EchoCommand()); - - settings = moddingContext.LoadSettingsData(self.Id); - } - - public override void OnEnable() - { - logger.Information("OnEnable() was called!"); - var harmony = new Harmony(modDefinition.Id); - harmony.PatchCategory(modDefinition.Id.Replace(".",string.Empty)); - } - - public override void OnDisable() - { - var harmony = new Harmony(modDefinition.Id); - harmony.UnpatchAll(modDefinition.Id); - Messenger.Default.Unregister(this); - } - - public void Update() - { - logger.Verbose("UPDATE()"); - } - - public void ModTabDidOpen(UIPanelBuilder builder) - { - logger.Information("Daytime!"); - - if (settings == null) settings = new(); - if (!settings?.WebhookSettingsList?.Any() ?? true) settings.WebhookSettingsList = new[] { new WebhookSettings() }.ToList(); - if (settings?.EngineRosterFuelColumnSettings == null) settings.EngineRosterFuelColumnSettings = new(); - - //WebhookUISection(ref builder); - //builder.AddExpandingVerticalSpacer(); - WebhooksListUISection(ref builder); - builder.AddExpandingVerticalSpacer(); - HandbrakesAndAnglecocksUISection(ref builder); - builder.AddExpandingVerticalSpacer(); - EnginRosterShowsFuelStatusUISection(ref builder); - } - - private void EnginRosterShowsFuelStatusUISection(ref UIPanelBuilder builder) - { - var columns = Enum.GetValues(typeof(EngineRosterFuelDisplayColumn)).Cast().Select(i => i.ToString()).ToList(); - builder.AddSection("Fuel Display in Engine Roster", delegate (UIPanelBuilder builder) - { - builder.AddField( - "Enable", - builder.AddDropdown(columns, (int)(settings?.EngineRosterFuelColumnSettings?.EngineRosterFuelStatusColumn ?? EngineRosterFuelDisplayColumn.None), - delegate (int column) - { - if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList(), EngineRosterFuelColumnSettings = new() }; - settings.EngineRosterFuelColumnSettings.EngineRosterFuelStatusColumn = (EngineRosterFuelDisplayColumn)column; - builder.Rebuild(); - } - ) - ).Tooltip("Enable Fuel Display in Engine Roster", $"Will add remaing fuel indication to Engine Roster (with details in roster row tooltip), Examples : {string.Join(" ", Enumerable.Range(0,4).Select(i => TextSprites.PiePercent(i, 4)))}"); - - builder.AddField( - "Always Visible?", - builder.AddToggle( - () => settings?.EngineRosterFuelColumnSettings?.EngineRosterShowsFuelStatusAlways ?? false, - delegate (bool enabled) - { - if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList(), EngineRosterFuelColumnSettings = new() }; - settings.EngineRosterFuelColumnSettings.EngineRosterShowsFuelStatusAlways = enabled; - builder.Rebuild(); - } - ) - ).Tooltip("Fuel Display in Engine Roster Always Visible", $"Always displayed, if you want it hidden and only shown when you care to see, uncheck this, and then you can press ALT for it to populate on the next UI refresh cycle."); - }); - } - - private void HandbrakesAndAnglecocksUISection(ref UIPanelBuilder builder) - { - builder.AddSection("Tag Callout Handbrake and Air System Helper", delegate (UIPanelBuilder builder) - { - builder.AddField( - "Enable Tag Updates", - builder.AddToggle( - () => settings?.HandBrakeAndAirTagModifiers ?? false, - delegate (bool enabled) - { - if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList() }; - settings.HandBrakeAndAirTagModifiers = enabled; - builder.Rebuild(); - } - ) - ).Tooltip("Enable Tag Updates", $"Will add {TextSprites.CycleWaybills} to the car tag title having Air System issues. Also prepends {TextSprites.HandbrakeWheel} if there is a handbrake set.\n\nHolding Left Alt while tags are displayed only shows tag titles that have issues."); - }); - } - - private void WebhooksListUISection(ref UIPanelBuilder builder) - { - builder.AddSection("Webhooks List", delegate (UIPanelBuilder builder) - { - for (int i = 1; i <= settings.WebhookSettingsList.Count; i++) - { - int z = i - 1; - builder.AddSection($"Webhook {i}", delegate (UIPanelBuilder builder) - { - builder.AddField( - "Webhook Enabled", - builder.AddToggle( - () => settings?.WebhookSettingsList[z]?.WebhookEnabled ?? false, - delegate (bool enabled) - { - if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList() }; - settings.WebhookSettingsList[z].WebhookEnabled = enabled; - settings.AddAnotherRow(); - builder.Rebuild(); - } - ) - ).Tooltip("Webhook Enabled", "Will parse the console messages and transmit to a Discord webhook."); - - builder.AddField( - "Reporting Mark", - builder.HStack(delegate (UIPanelBuilder field) - { - field.AddInputField( - settings?.WebhookSettingsList[z]?.RailroadMark, - delegate (string railroadMark) - { - if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList() }; - settings.WebhookSettingsList[z].RailroadMark = railroadMark; - settings.AddAnotherRow(); - builder.Rebuild(); - }, characterLimit: GameStorage.ReportingMarkMaxLength).FlexibleWidth(); - }) - ).Tooltip("Reporting Mark", "Reporting mark of the company this Discord webhook applies to.."); - - builder.AddField( - "Webhook Url", - builder.HStack(delegate (UIPanelBuilder field) - { - field.AddInputField( - settings?.WebhookSettingsList[z]?.WebhookUrl, - delegate (string webhookUrl) - { - if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList() }; - settings.WebhookSettingsList[z].WebhookUrl = webhookUrl; - settings.AddAnotherRow(); - builder.Rebuild(); - }).FlexibleWidth(); - }) - ).Tooltip("Webhook Url", "Url of Discord webhook to publish messages to."); - }); - } - }); - } - - public void ModTabDidClose() - { - logger.Information("Nighttime..."); - this.moddingContext.SaveSettingsData(this.modDefinition.Id, settings ?? new()); + return client; } } + internal Settings? settings { get; private set; } = null; + readonly ILogger logger = Log.ForContext(); + IModdingContext moddingContext { get; set; } + IModDefinition modDefinition { get; set; } + + static TweaksAndThings() + { + Log.Information("Hello! Static Constructor was called!"); + } + + public TweaksAndThings(IModdingContext moddingContext, IModDefinition self) + { + this.modDefinition = self; + + this.moddingContext = moddingContext; + + logger.Information("Hello! Constructor was called for {modId}/{modVersion}!", self.Id, self.Version); + + //moddingContext.RegisterConsoleCommand(new EchoCommand()); + + settings = moddingContext.LoadSettingsData(self.Id); + } + + public override void OnEnable() + { + logger.Information("OnEnable() was called!"); + var harmony = new Harmony(modDefinition.Id); + harmony.PatchCategory(modDefinition.Id.Replace(".",string.Empty)); + } + + public override void OnDisable() + { + var harmony = new Harmony(modDefinition.Id); + harmony.UnpatchAll(modDefinition.Id); + Messenger.Default.Unregister(this); + } + + public void Update() + { + logger.Verbose("UPDATE()"); + } + + public void ModTabDidOpen(UIPanelBuilder builder) + { + logger.Information("Daytime!"); + + if (settings == null) settings = new(); + if (!settings?.WebhookSettingsList?.Any() ?? true) settings.WebhookSettingsList = new[] { new WebhookSettings() }.ToList(); + if (settings?.EngineRosterFuelColumnSettings == null) settings.EngineRosterFuelColumnSettings = new(); + + //WebhookUISection(ref builder); + //builder.AddExpandingVerticalSpacer(); + WebhooksListUISection(ref builder); + builder.AddExpandingVerticalSpacer(); + HandbrakesAndAnglecocksUISection(ref builder); + builder.AddExpandingVerticalSpacer(); + EnginRosterShowsFuelStatusUISection(ref builder); + } + + private void EnginRosterShowsFuelStatusUISection(ref UIPanelBuilder builder) + { + var columns = Enum.GetValues(typeof(EngineRosterFuelDisplayColumn)).Cast().Select(i => i.ToString()).ToList(); + builder.AddSection("Fuel Display in Engine Roster", delegate (UIPanelBuilder builder) + { + builder.AddField( + "Enable", + builder.AddDropdown(columns, (int)(settings?.EngineRosterFuelColumnSettings?.EngineRosterFuelStatusColumn ?? EngineRosterFuelDisplayColumn.None), + delegate (int column) + { + if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList(), EngineRosterFuelColumnSettings = new() }; + settings.EngineRosterFuelColumnSettings.EngineRosterFuelStatusColumn = (EngineRosterFuelDisplayColumn)column; + builder.Rebuild(); + } + ) + ).Tooltip("Enable Fuel Display in Engine Roster", $"Will add reaming fuel indication to Engine Roster (with details in roster row tool tip), Examples : {string.Join(" ", Enumerable.Range(0,4).Select(i => TextSprites.PiePercent(i, 4)))}"); + + builder.AddField( + "Always Visible?", + builder.AddToggle( + () => settings?.EngineRosterFuelColumnSettings?.EngineRosterShowsFuelStatusAlways ?? false, + delegate (bool enabled) + { + if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList(), EngineRosterFuelColumnSettings = new() }; + settings.EngineRosterFuelColumnSettings.EngineRosterShowsFuelStatusAlways = enabled; + builder.Rebuild(); + } + ) + ).Tooltip("Fuel Display in Engine Roster Always Visible", $"Always displayed, if you want it hidden and only shown when you care to see, uncheck this, and then you can press ALT for it to populate on the next UI refresh cycle."); + }); + } + + private void HandbrakesAndAnglecocksUISection(ref UIPanelBuilder builder) + { + builder.AddSection("Tag Callout Handbrake and Air System Helper", delegate (UIPanelBuilder builder) + { + builder.AddField( + "Enable Tag Updates", + builder.AddToggle( + () => settings?.HandBrakeAndAirTagModifiers ?? false, + delegate (bool enabled) + { + if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList() }; + settings.HandBrakeAndAirTagModifiers = enabled; + builder.Rebuild(); + } + ) + ).Tooltip("Enable Tag Updates", $"Will add {TextSprites.CycleWaybills} to the car tag title having Air System issues. Also prepends {TextSprites.HandbrakeWheel} if there is a handbrake set.\n\nHolding Left Alt while tags are displayed only shows tag titles that have issues."); + }); + } + + private void WebhooksListUISection(ref UIPanelBuilder builder) + { + builder.AddSection("Webhooks List", delegate (UIPanelBuilder builder) + { + for (int i = 1; i <= settings.WebhookSettingsList.Count; i++) + { + int z = i - 1; + builder.AddSection($"Webhook {i}", delegate (UIPanelBuilder builder) + { + builder.AddField( + "Webhook Enabled", + builder.AddToggle( + () => settings?.WebhookSettingsList[z]?.WebhookEnabled ?? false, + delegate (bool enabled) + { + if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList() }; + settings.WebhookSettingsList[z].WebhookEnabled = enabled; + settings.AddAnotherRow(); + builder.Rebuild(); + } + ) + ).Tooltip("Webhook Enabled", "Will parse the console messages and transmit to a Discord webhook."); + + builder.AddField( + "Reporting Mark", + builder.HStack(delegate (UIPanelBuilder field) + { + field.AddInputField( + settings?.WebhookSettingsList[z]?.RailroadMark, + delegate (string railroadMark) + { + if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList() }; + settings.WebhookSettingsList[z].RailroadMark = railroadMark; + settings.AddAnotherRow(); + builder.Rebuild(); + }, characterLimit: GameStorage.ReportingMarkMaxLength).FlexibleWidth(); + }) + ).Tooltip("Reporting Mark", "Reporting mark of the company this Discord webhook applies to.."); + + builder.AddField( + "Webhook Url", + builder.HStack(delegate (UIPanelBuilder field) + { + field.AddInputField( + settings?.WebhookSettingsList[z]?.WebhookUrl, + delegate (string webhookUrl) + { + if (settings == null) settings = new() { WebhookSettingsList = new[] { new WebhookSettings() }.ToList() }; + settings.WebhookSettingsList[z].WebhookUrl = webhookUrl; + settings.AddAnotherRow(); + builder.Rebuild(); + }).FlexibleWidth(); + }) + ).Tooltip("Webhook Url", "Url of Discord webhook to publish messages to."); + }); + } + }); + } + + public void ModTabDidClose() + { + logger.Information("Nighttime..."); + this.moddingContext.SaveSettingsData(this.modDefinition.Id, settings ?? new()); + } } From 715629394dc14cb6441f7df448ae6315196d6609 Mon Sep 17 00:00:00 2001 From: RMROC451 Date: Thu, 20 Jun 2024 22:10:47 -0500 Subject: [PATCH 4/4] getting a little bit of logging around set hand brakes. --- .../Patches/CarInspector_PopulateCarPanel_Patch.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/TweaksAndThings/Patches/CarInspector_PopulateCarPanel_Patch.cs b/TweaksAndThings/Patches/CarInspector_PopulateCarPanel_Patch.cs index aba4344..acb418e 100644 --- a/TweaksAndThings/Patches/CarInspector_PopulateCarPanel_Patch.cs +++ b/TweaksAndThings/Patches/CarInspector_PopulateCarPanel_Patch.cs @@ -115,9 +115,10 @@ public class CarInspector_PopulateCarPanel_Patch } else { TrainController tc = UnityEngine.Object.FindObjectOfType(); - + consist = consist.Where(c => c.DetermineFuelCar(true) != null); + Log.Information($"{car} => {mrocHelperType} => {string.Join("/", consist.Select(c => c.ToString()))}"); //when ApplyHandbrakesAsNeeded is called, and the consist contains an engine, it stops applying brakes. - tc.ApplyHandbrakesAsNeeded(consist.Where(c => c.DetermineFuelCar(true) != null).ToList(), PlaceTrainHandbrakes.Automatic); + tc.ApplyHandbrakesAsNeeded(consist.ToList(), PlaceTrainHandbrakes.Automatic); } break;