Fixes [Copy Repair, Disable Waypoint, Enable Simple Controls]

- Added Copy Repair Destination Feature  (Equipment Tab)
- Option to disable waypoint jump/get back the option for simplified controls
This commit is contained in:
Faizan Khan
2026-05-17 01:12:26 +05:30
parent cbca69d66b
commit 0c93a507ba
4 changed files with 136 additions and 9 deletions

View File

@@ -1,4 +1,5 @@
using Game.Messages;
using Game.Notices;
using Game.State;
using HarmonyLib;
using Model;
@@ -41,12 +42,22 @@ internal class LocomotiveControlsUIAdapter_UpdateCarText_Postfix()
{
try
{
if (lastLocoSeenCarId != null &&
lastLocoSeenCarId.Equals(TrainController.Shared?.SelectedLocomotive.id) &&
watchyWatchy != null)
return;
if (watchyWatchy != null)
((MonoBehaviour)__instance).StopCoroutine(watchyWatchy);
if (lastLocoSeenCarId != null && lastLocoSeenCarId.Equals(TrainController.Shared?.SelectedLocomotive.id) && watchyWatchy != null) return;
if (watchyWatchy != null) ((MonoBehaviour)__instance).StopCoroutine(watchyWatchy);
watchyWatchy = null;
if (__instance._persistence.Orders.Mode == AutoEngineerMode.Waypoint) watchyWatchy = ((MonoBehaviour)__instance).StartCoroutine(UpdateCogCoroutine(__instance));
if (__instance._persistence.Orders.Mode == AutoEngineerMode.Waypoint)
{
watchyWatchy =
((MonoBehaviour)__instance)
.StartCoroutine(UpdateCogCoroutine(__instance));
}
}
catch (Exception ex)
{
@@ -61,11 +72,19 @@ internal class LocomotiveControlsUIAdapter_UpdateCarText_Postfix()
while (true)
{
if (__instance._persistence.Orders.Mode != AutoEngineerMode.Waypoint || ((AutoEngineerWaypointControls)__instance.aiWaypointControls).Locomotive == null) yield return wait;
if (__instance._persistence.Orders.Mode != AutoEngineerMode.Waypoint || ((AutoEngineerWaypointControls)__instance.aiWaypointControls).Locomotive == null)
{
yield return wait;
continue;
}
PrepLocoUsage((AutoEngineerWaypointControls)__instance.aiWaypointControls, out BaseLocomotive selectedLoco, out int numberOfCars);
HashSet<OpsCarPosition?> destinations = [];
if (!tweaksAndThings.IsEnabled() || !ShouldRecalc(__instance, selectedLoco, out destinations)) yield return wait;
if (!tweaksAndThings.IsEnabled() || tweaksAndThings.DisableWaypointControls() || !ShouldRecalc(__instance, selectedLoco, out destinations))
{
yield return wait;
continue;
}
timetableSaveTime = TimetableController.Shared.CurrentDocument.Modified;
lastSeenIntegrationSetCount = selectedLoco.set.NumberOfCars;
@@ -132,7 +151,18 @@ internal class LocomotiveControlsUIAdapter_UpdateCarText_Postfix()
private static OptionsDropdownConfiguration WireUpJumpTosToSettingMenu(AutoEngineerWaypointControls __instance, BaseLocomotive selectedLoco, List<DropdownMenu.RowData> rowDatas, Action<int> func, int origCount, int maxRowOrig, AutoEngineerOrdersHelper aeoh, ref List<(string destinationId, string destination, float? distance, float sortDistance, Location? location)> jumpTos)
{
OptionsDropdownConfiguration __result;
jumpTos = jumpTos?.OrderBy(c => c.sortDistance)?.ToList() ?? default;
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
// Check if waypoint controls are disabled
if (tweaksAndThings.DisableWaypointControls())
{
jumpTos = new List<(string, string, float?, float, Location?)>();
}
else
{
jumpTos = jumpTos?.OrderBy(c => c.sortDistance)?.ToList() ?? default;
}
var localJumpTos = jumpTos.ToList();
var safetyFirst = AutoEngineerPlanner_HandleCommand_Patch.SafetyFirstGoverningApplies(selectedLoco) && jumpTos.Any();
@@ -364,6 +394,12 @@ internal class LocomotiveControlsUIAdapter_UpdateOptionsDropdown_Prefix
{
static bool Prefix(LocomotiveControlsUIAdapter __instance)
{
return false;
TweaksAndThingsPlugin tweaksAndThings =
SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
if (!tweaksAndThings.IsEnabled())
return true;
return tweaksAndThings.DisableWaypointControls();
}
}
}

View File

@@ -0,0 +1,74 @@
using Game.Messages;
using Game.Notices;
using Game.State;
using HarmonyLib;
using Model;
using Model.Ops;
using Network;
using Railloader;
using System;
using System.Linq;
using UI.Builder;
using UI.CarInspector;
namespace RMROC451.TweaksAndThings.Patches;
[HarmonyPatch(typeof(CarInspector))]
[HarmonyPatch(nameof(CarInspector.PopulateEquipmentPanel))]
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
internal static class CarInspector_PopulateEquipmentPanel_Patch
{
[HarmonyPrefix]
private static void Prefix(CarInspector __instance, UIPanelBuilder builder)
{
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
if (!tweaksAndThings.IsEnabled()) return;
builder.HStack(hstack =>
{
hstack.AddButtonCompact("Copy Repair Dest", delegate
{
Car selectedCar = __instance._car;
bool hasDestination = selectedCar.TryGetOverrideDestination(
OverrideDestination.Repair,
OpsController.Shared,
out (OpsCarPosition, string)? destination);
int updatedCount = selectedCar
.EnumerateCoupled()
.Where(car => car.id != selectedCar.id)
.Select(car =>
{
if (hasDestination)
{
car.SetOverrideDestination(
OverrideDestination.Repair,
destination);
}
else
{
car.SetOverrideDestination(
OverrideDestination.Repair,
null);
}
return 1;
})
.Sum();
Multiplayer.SendError(
StateManager.Shared.PlayersManager.LocalPlayer,
hasDestination
? $"Copied repair destination to {updatedCount} connected {(updatedCount == 1 ? "car" : "cars")}."
: $"Cleared repair destination from {updatedCount} connected {(updatedCount == 1 ? "car" : "cars")}.",
default);
hstack.Rebuild();
})
.Tooltip(
"Copy Repair Destination",
"Copies or clears this car's repair destination across all connected cars in the consist.");
});
}
}

View File

@@ -31,7 +31,8 @@ public class Settings
bool safetyFirstClientEnforce,
CrewHourLoadMethod loadCrewHoursMethod,
float cabeeseSearchRadiusFtInMeters,
bool trainBrakeDisplayShowsColorsInCalloutMode
bool trainBrakeDisplayShowsColorsInCalloutMode,
bool disableWaypointControls
)
{
WebhookSettingsList = webhookSettingsList;
@@ -47,6 +48,7 @@ public class Settings
LoadCrewHoursMethod = loadCrewHoursMethod;
CabeeseSearchRadiusFtInMeters = cabeeseSearchRadiusFtInMeters;
TrainBrakeDisplayShowsColorsInCalloutMode = trainBrakeDisplayShowsColorsInCalloutMode;
DisableWaypointControls = disableWaypointControls;
}
public readonly UIState<string> _selectedTabState = new UIState<string>(null);
@@ -63,6 +65,7 @@ public class Settings
public CrewHourLoadMethod LoadCrewHoursMethod;
public float CabeeseSearchRadiusFtInMeters;
public bool TrainBrakeDisplayShowsColorsInCalloutMode;
public bool DisableWaypointControls;
internal void AddAnotherRow()
{
@@ -145,5 +148,7 @@ public static class SettingsExtensions
(input?.settings?.LoadCrewHoursMethod ?? CrewHourLoadMethod.Tracks) == CrewHourLoadMethod.Daily;
public static bool TrainBrakeDisplayShowsColorsInCalloutMode(this TweaksAndThingsPlugin input) =>
input?.settings?.TrainBrakeDisplayShowsColorsInCalloutMode ?? false;
public static bool DisableWaypointControls(this TweaksAndThingsPlugin input) =>
input?.settings?.DisableWaypointControls ?? false;
}

View File

@@ -262,6 +262,18 @@ AutoHotboxSpotter Update: decrease the random wait from 30 - 300 seconds to 15 -
}
).Tooltip("Train Brake Color Mode", $@"When enabled/checked and car tag callout mode is enabled (showing car tags hovering over them), the train brake display of the selected locomotive will change the cars/engines to their destination area's color to help you visualize sets of cars at a glance.");
builder.Spacer(spacing);
builder.AddFieldToggle(
"Disable Waypoint Controls",
() => settings?.DisableWaypointControls ?? false,
delegate (bool enabled)
{
if (settings == null) settings = new();
settings.DisableWaypointControls = enabled;
builder.Rebuild();
}
).Tooltip("Disable Waypoint Controls", @"When enabled, removes the waypoint set/jump options from the engine control menu. This disables the option to jump to waypoints or set waypoints based on consist car destinations, allowing only default engine controls.");
builder.Spacer(spacing);
EngineRosterShowsFuelStatusUISection(builder);
}