Support fallback to vanilla icons if files are not found. Allow configuration for context menu pagination between car/consist option preferences by player

This commit is contained in:
2025-09-06 22:03:25 -05:00
parent 3a04405dad
commit 8a21ec2e79
5 changed files with 51 additions and 55 deletions

View File

@@ -38,57 +38,70 @@ internal class CarPickable_HandleShowContextMenu_Patch
trainController.SelectedCar = ((trainController.SelectedCar == car) ? null : car); trainController.SelectedCar = ((trainController.SelectedCar == car) ? null : car);
}); });
if (!car.EnumerateCoupled().Any(c => !c.SupportsBleed())) bool shiftPagination = (tweaksAndThings.ShiftForPagination() && GameInput.IsShiftDown) || !tweaksAndThings.ShiftForPagination();
bool nonShiftShow = (tweaksAndThings.ShiftForPagination() && !GameInput.IsShiftDown) || !tweaksAndThings.ShiftForPagination();
if (shiftPagination && car.EnumerateCoupled().Any(c => c.SupportsBleed()))
{ {
Sprite bleedConsist = MapWindow_OnClick_Patch.LoadTexture("BleedConsist.png", "BleedConsist"); Sprite? bleedConsist = MapWindow_OnClick_Patch.LoadTexture("BleedConsist.png", "BleedConsist");
if (bleedConsist == null) bleedConsist = SpriteName.Bleed.Sprite();
shared.AddButton(ContextMenuQuadrant.Brakes, $"Bleed Consist", bleedConsist, delegate shared.AddButton(ContextMenuQuadrant.Brakes, $"Bleed Consist", bleedConsist, delegate
{ {
CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.BleedAirSystem, buttonsHaveCost); CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.BleedAirSystem, buttonsHaveCost);
}); });
} }
if (car.SupportsBleed()) if (nonShiftShow && car.SupportsBleed())
{ {
Sprite bleedCar = MapWindow_OnClick_Patch.LoadTexture("BleedCar.png", "BleedCar"); Sprite? bleedCar = MapWindow_OnClick_Patch.LoadTexture("BleedCar.png", "BleedCar");
if (bleedCar == null) bleedCar = SpriteName.Bleed.Sprite();
shared.AddButton(ContextMenuQuadrant.Brakes, "Bleed", bleedCar, car.SetBleed); shared.AddButton(ContextMenuQuadrant.Brakes, "Bleed", bleedCar, car.SetBleed);
} }
if (shiftPagination)
{
string text = car.EnumerateCoupled().Any(c => c.HandbrakeApplied()) ? "Release " : "Set "; string text = car.EnumerateCoupled().Any(c => c.HandbrakeApplied()) ? "Release " : "Set ";
Sprite consistBrakes = MapWindow_OnClick_Patch.LoadTexture($"Consist{text.Trim()}Brake.png", $"{text.Trim()}Consist"); Sprite? consistBrakes = MapWindow_OnClick_Patch.LoadTexture($"Consist{text.Trim()}Brake.png", $"{text.Trim()}Consist");
if (consistBrakes == null) consistBrakes = SpriteName.Handbrake.Sprite();
shared.AddButton(ContextMenuQuadrant.Brakes, $"{text}Consist", consistBrakes, delegate shared.AddButton(ContextMenuQuadrant.Brakes, $"{text}Consist", consistBrakes, delegate
{ {
CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.Handbrake, buttonsHaveCost); CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.Handbrake, buttonsHaveCost);
}); });
}
if (nonShiftShow)
{
string textCar = car.HandbrakeApplied() ? "Release " : "Set "; string textCar = car.HandbrakeApplied() ? "Release " : "Set ";
Sprite carBrakes = MapWindow_OnClick_Patch.LoadTexture($"{text.Trim()}Brake.png", $"{text.Trim()}Consist"); Sprite? carBrakes = MapWindow_OnClick_Patch.LoadTexture($"{textCar.Trim()}Brake.png", $"{textCar.Trim()}Brake");
if (carBrakes == null) carBrakes = SpriteName.Handbrake.Sprite();
shared.AddButton(ContextMenuQuadrant.Brakes, $"{textCar}Handbrake", carBrakes, delegate shared.AddButton(ContextMenuQuadrant.Brakes, $"{textCar}Handbrake", carBrakes, delegate
{ {
bool apply = !car.air.handbrakeApplied; bool apply = !car.air.handbrakeApplied;
car.SetHandbrake(apply); car.SetHandbrake(apply);
}); });
}
if (shiftPagination && car.EnumerateCoupled().Any(c => c.EndAirSystemIssue()))
if (car.EnumerateCoupled().Any(c => c.EndAirSystemIssue()))
{ {
Sprite connectAir = MapWindow_OnClick_Patch.LoadTexture($"ConnectAir.png", "ConnectAir"); Sprite? connectAir = MapWindow_OnClick_Patch.LoadTexture($"ConnectAir.png", "ConnectAir");
if (connectAir == null) connectAir = SpriteName.Select.Sprite();
shared.AddButton(ContextMenuQuadrant.General, $"Air Up Consist", connectAir, delegate shared.AddButton(ContextMenuQuadrant.General, $"Air Up Consist", connectAir, delegate
{ {
CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.GladhandAndAnglecock, buttonsHaveCost); CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.GladhandAndAnglecock, buttonsHaveCost);
}); });
} }
if (StateManager.IsHost && car.EnumerateCoupled().Any(c => c.NeedsOiling || c.HasHotbox)) if (StateManager.IsHost && shiftPagination && car.EnumerateCoupled().Any(c => c.NeedsOiling || c.HasHotbox))
{ {
Sprite oilCan = MapWindow_OnClick_Patch.LoadTexture("OilCan.png", "OilCan"); Sprite? oilCan = MapWindow_OnClick_Patch.LoadTexture("OilCan.png", "OilCan");
if (oilCan == null) oilCan = SpriteName.Select.Sprite();
shared.AddButton(ContextMenuQuadrant.General, $"Oil Consist", oilCan, delegate shared.AddButton(ContextMenuQuadrant.General, $"Oil Consist", oilCan, delegate
{ {
CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.Oil, buttonsHaveCost); CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.Oil, buttonsHaveCost);
}); });
} }
Sprite follow = MapWindow_OnClick_Patch.LoadTexture($"Follow.png", "ConnectAir"); Sprite? follow = MapWindow_OnClick_Patch.LoadTexture($"Follow.png", "ConnectAir");
if (follow == null) follow = SpriteName.Inspect.Sprite();
shared.AddButton(ContextMenuQuadrant.General, $"Follow", follow, delegate shared.AddButton(ContextMenuQuadrant.General, $"Follow", follow, delegate
{ {
CameraSelector.shared.FollowCar(car); CameraSelector.shared.FollowCar(car);

View File

@@ -34,6 +34,11 @@ internal class MapWindow_OnClick_Patch
public static Sprite? LoadTexture(string fileName, string name) public static Sprite? LoadTexture(string fileName, string name)
{ {
string path = Path.Combine(SingletonPluginBase<TweaksAndThingsPlugin>.Shared.ModDirectory, fileName); string path = Path.Combine(SingletonPluginBase<TweaksAndThingsPlugin>.Shared.ModDirectory, fileName);
if (!File.Exists(path))
{
_log.Debug($"Unable to find {name} icon at {path}!");
return null;
}
Texture2D texture2D = new Texture2D(128, 128, TextureFormat.DXT5, mipChain: false); Texture2D texture2D = new Texture2D(128, 128, TextureFormat.DXT5, mipChain: false);
texture2D.name = name; texture2D.name = name;
texture2D.wrapMode = TextureWrapMode.Clamp; texture2D.wrapMode = TextureWrapMode.Clamp;

View File

@@ -57,45 +57,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Images\" /> <None Include="Images\**" CopyToOutputDirectory="Always"/>
</ItemGroup>
<ItemGroup>
<None Update="Images\BleedCar.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Images\BleedConsist.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Images\ConnectAir.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Images\ConsistReleaseBrake.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Images\ConsistSetBrake.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Images\Follow.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Images\Hourglass_icon.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Images\Map_pin_icon.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Images\OilCan.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Images\ReleaseBrake.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Images\SetBrake.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Images\Thumbs.db">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -31,7 +31,8 @@ public class Settings
bool safetyFirstClientEnforce, bool safetyFirstClientEnforce,
CrewHourLoadMethod loadCrewHoursMethod, CrewHourLoadMethod loadCrewHoursMethod,
float cabeeseSearchRadiusFtInMeters, float cabeeseSearchRadiusFtInMeters,
bool trainBrakeDisplayShowsColorsInCalloutMode bool trainBrakeDisplayShowsColorsInCalloutMode,
bool shiftPaginationOnContextMenu
) )
{ {
WebhookSettingsList = webhookSettingsList; WebhookSettingsList = webhookSettingsList;
@@ -47,6 +48,7 @@ public class Settings
LoadCrewHoursMethod = loadCrewHoursMethod; LoadCrewHoursMethod = loadCrewHoursMethod;
CabeeseSearchRadiusFtInMeters = cabeeseSearchRadiusFtInMeters; CabeeseSearchRadiusFtInMeters = cabeeseSearchRadiusFtInMeters;
TrainBrakeDisplayShowsColorsInCalloutMode = trainBrakeDisplayShowsColorsInCalloutMode; TrainBrakeDisplayShowsColorsInCalloutMode = trainBrakeDisplayShowsColorsInCalloutMode;
ShiftPaginationOnContextMenu = shiftPaginationOnContextMenu;
} }
public readonly UIState<string> _selectedTabState = new UIState<string>(null); public readonly UIState<string> _selectedTabState = new UIState<string>(null);
@@ -63,6 +65,7 @@ public class Settings
public CrewHourLoadMethod LoadCrewHoursMethod; public CrewHourLoadMethod LoadCrewHoursMethod;
public float CabeeseSearchRadiusFtInMeters; public float CabeeseSearchRadiusFtInMeters;
public bool TrainBrakeDisplayShowsColorsInCalloutMode; public bool TrainBrakeDisplayShowsColorsInCalloutMode;
public bool ShiftPaginationOnContextMenu;
internal void AddAnotherRow() internal void AddAnotherRow()
{ {
@@ -145,5 +148,7 @@ public static class SettingsExtensions
(input?.settings?.LoadCrewHoursMethod ?? CrewHourLoadMethod.Tracks) == CrewHourLoadMethod.Daily; (input?.settings?.LoadCrewHoursMethod ?? CrewHourLoadMethod.Tracks) == CrewHourLoadMethod.Daily;
public static bool TrainBrakeDisplayShowsColorsInCalloutMode(this TweaksAndThingsPlugin input) => public static bool TrainBrakeDisplayShowsColorsInCalloutMode(this TweaksAndThingsPlugin input) =>
input?.settings?.TrainBrakeDisplayShowsColorsInCalloutMode ?? false; input?.settings?.TrainBrakeDisplayShowsColorsInCalloutMode ?? false;
public static bool ShiftForPagination(this TweaksAndThingsPlugin input) =>
input?.settings?.ShiftPaginationOnContextMenu ?? 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."); ).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(
"Context Menu Shift Modifier",
() => this.ShiftForPagination(),
delegate (bool enabled)
{
if (settings == null) settings = new();
settings.ShiftPaginationOnContextMenu = enabled;
builder.Rebuild();
}
).Tooltip("Context Menu Shift Modifier", $@"When enabled/checked, utilizing `SHIFT` while initiating the context menu of a car will show consist level options, and without shows only car level. If this is unchecked, all car/consist options show up in a happy goulash!");
builder.Spacer(spacing); builder.Spacer(spacing);
EngineRosterShowsFuelStatusUISection(builder); EngineRosterShowsFuelStatusUISection(builder);
} }