Merge pull request #83 from Refizar08/main

Fixes [Copy Repair, Disable Waypoint, Enable Simple Controls]
This commit is contained in:
2026-05-19 18:23:13 -05:00
committed by GitHub
7 changed files with 155 additions and 10 deletions

5
.gitignore vendored
View File

@@ -396,3 +396,8 @@ FodyWeavers.xsd
# JetBrains Rider
*.sln.iml
# Trash
.claude
claude.md
todo.md

View File

@@ -2,6 +2,6 @@
<PropertyGroup>
<MajorVersion>2</MajorVersion>
<MinorVersion>1</MinorVersion>
<PatchVersion>7</PatchVersion>
<PatchVersion>8</PatchVersion>
</PropertyGroup>
</Project>

View File

@@ -6,6 +6,18 @@ This is a mod for Railroader which is available on Steam.
This mod requires Railloader by Zamu.
## Credits & Project History
This project was originally created and developed by RMROC451.
I have created fixes and additional features which maybe pulled to main project over time.
The goal of this repository is to preserve, maintain, and continue improving the mod for the Railroader community while respecting and crediting the original work and vision of RMROC451.
Special thanks to:
- RMROC451 — original creator of Tweaks and Things
- Zamu
## Usage
1. Download and install Railloader by Zamu from here: https://railroader.stelltis.ch/
* Verify you have a Mods folder in the root of your railroader directory. If You do NOT have a Mods folder, you didn't complete this step successfully.

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,75 @@
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;
using Core;
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 {"car".Pluralize(updatedCount == 1 ? 1 : 0)}."
: $"Cleared repair destination from {updatedCount} connected {"car".Pluralize(updatedCount == 1 ? 1 : 0)}.",
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);
}