mirror of
https://github.com/rmroc451/TweaksAndThings.git
synced 2025-12-16 09:19:37 -06:00
Merge pull request #31 from rmroc451/v1.0.0-prep
Closes #27 fix issue with last car end gear issue detection Closes #28 add hotbox icon to tag update info Closes #25 adding follow to car context menu Closes #24 adding consist info to non motive power cars, that have a caboose when Caboose Use mod setting is enabled. Closes #29, #30 Allow caboose setting to require that a caboose is present in the consist to use the AI Engineer's AutoOiler & - AutoHotboxSpotter.
This commit is contained in:
@@ -2,17 +2,18 @@
|
||||
<PropertyGroup>
|
||||
<!-- Try to find the directory on our own -->
|
||||
<GameManagedDir Condition="'$(GameManagedDir)' == ''">$([System.IO.Directory]::GetDirectories(`$(GameDir)`, `*_Data`)[0])\Managed</GameManagedDir>
|
||||
|
||||
|
||||
<!-- Copy the mod to the game directory -->
|
||||
<GameModDir Condition="'$(GameModDir)' == ''">$(GameDir)/Mods/$(AssemblyName)</GameModDir>
|
||||
<OutDir Condition="'$(Configuration)' == 'Debug'">$(GameModDir)/</OutDir>
|
||||
<VersionTimestamp>$([System.DateTime]::UtcNow.ToString(`o`))</VersionTimestamp>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Replace the default version if something was set for it -->
|
||||
<PropertyGroup Condition="'$(AssemblyVersion)' == '' OR '$(MajorVersion)' != '' OR '$(MinorVersion)' != ''">
|
||||
<MajorVersion Condition="'$(MajorVersion)' == ''">0</MajorVersion>
|
||||
<MinorVersion Condition="'$(MinorVersion)' == ''">1</MinorVersion>
|
||||
<PatchVersion Condition="'$(PatchVersion)' == ''">8</PatchVersion>
|
||||
<MajorVersion Condition="'$(MajorVersion)' == ''">1</MajorVersion>
|
||||
<MinorVersion Condition="'$(MinorVersion)' == ''">0</MinorVersion>
|
||||
<PatchVersion Condition="'$(PatchVersion)' == ''">0</PatchVersion>
|
||||
<AssemblyVersion>$(MajorVersion).$(MinorVersion).$(PatchVersion)</AssemblyVersion>
|
||||
<FileVersion>$(AssemblyVersion)</FileVersion>
|
||||
<ProductVersion>$(AssemblyVersion)</ProductVersion>
|
||||
@@ -30,7 +31,7 @@
|
||||
<!-- Publish the mod as a neat zip file -->
|
||||
<Target Name="PrepareForPublishing" AfterTargets="AfterBuild" Condition="'$(Configuration)' == 'Release'">
|
||||
<!-- Replace $(AssemblyVersion) with the actual version -->
|
||||
<Exec Command="powershell -Command "(Get-Content '$(OutputPath)Definition.json') -replace '\$\(AssemblyVersion\)', '$(AssemblyVersion)' | Set-Content '$(OutputPath)Definition.json'"" />
|
||||
<Exec Command="powershell -Command "(Get-Content '$(OutputPath)Definition.json') -replace '\$\(AssemblyVersion\)', '$(AssemblyVersion)_$(VersionTimestamp)' | Set-Content '$(OutputPath)Definition.json'"" />
|
||||
|
||||
<PropertyGroup>
|
||||
<ModsDirectory>$(OutputPath)/Mods</ModsDirectory>
|
||||
@@ -43,15 +44,15 @@
|
||||
|
||||
<!-- Assure the output path exists -->
|
||||
<MakeDir Directories="$(PublishPath)" />
|
||||
|
||||
|
||||
<!-- Remove the old Mods directory, and Zips file if any is lying around -->
|
||||
<ItemGroup>
|
||||
<OldZips Include="$(PublishPath)/$(AssemblyName)_*.zip" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<RemoveDir Directories="$(ModsDirectory)" ContinueOnError="true" />
|
||||
<Delete Files="@(OldZips)" />
|
||||
|
||||
|
||||
<!-- Create the Mods directory again -->
|
||||
<MakeDir Directories="$(ModDirectory)" />
|
||||
|
||||
@@ -64,7 +65,7 @@
|
||||
|
||||
<!-- Zip it up -->
|
||||
<Exec Command="powershell -Command "Compress-Archive -Path '$(ModsDirectory)' -Destination '$(ZipName)'"" />
|
||||
|
||||
|
||||
<!-- Move them to the game directory -->
|
||||
<Copy SourceFiles="@(OutputFiles)" DestinationFolder="$(GameModDir)" />
|
||||
</Target>
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace RMROC451.TweaksAndThings.Extensions
|
||||
private static float CabooseAutoOilerLimit(this bool hasCaboose) =>
|
||||
hasCaboose ? 0.99f : AutoOiler.OilIfBelow;
|
||||
|
||||
public static IEnumerator MrocAutoOilerLoop(this AutoOiler oiler, Serilog.ILogger _log)
|
||||
public static IEnumerator MrocAutoOilerLoop(this AutoOiler oiler, Serilog.ILogger _log, bool cabooseRequired)
|
||||
{
|
||||
int originIndex = oiler.FindOriginIndex();
|
||||
bool hasCaboose = oiler._cars.CabooseInConsist();
|
||||
@@ -21,13 +21,17 @@ namespace RMROC451.TweaksAndThings.Extensions
|
||||
_log.Error("Couldn't find origin car {car}", oiler._originCar);
|
||||
oiler._coroutine = null;
|
||||
yield break;
|
||||
} else if (CabooseRequirementChecker(string.Format("{0} {1}", oiler.GetType().Name, oiler.name), cabooseRequired, hasCaboose, _log))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
oiler._reverse = originIndex > oiler._cars.Count - originIndex;
|
||||
_log.Information(
|
||||
"AutoOiler {name} starting, rev = {reverse}, caboose halving adjustment = {hasCaboose}, oil limit = {limit}",
|
||||
oiler.name,
|
||||
oiler._reverse,
|
||||
hasCaboose,
|
||||
"AutoOiler {name} starting, rev = {reverse}, caboose required = {req}, caboose halving adjustment = {hasCaboose}, oil limit = {limit}",
|
||||
oiler.name,
|
||||
oiler._reverse,
|
||||
cabooseRequired,
|
||||
hasCaboose,
|
||||
hasCaboose.CabooseAutoOilerLimit()
|
||||
);
|
||||
while (true)
|
||||
@@ -63,7 +67,7 @@ namespace RMROC451.TweaksAndThings.Extensions
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerator MrocAutoHotboxSpotterLoop(this AutoHotboxSpotter spotter, Serilog.ILogger _log)
|
||||
public static IEnumerator MrocAutoHotboxSpotterLoop(this AutoHotboxSpotter spotter, Serilog.ILogger _log, bool cabooseRequired)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
@@ -73,7 +77,11 @@ namespace RMROC451.TweaksAndThings.Extensions
|
||||
yield return new WaitForSeconds(1f);
|
||||
continue;
|
||||
}
|
||||
_log.Information("AutoHotboxSpotter {name}: Hotbox Spotter Running, Has Caboose => {hasCaboose}; Has Cars {hasCars}", spotter.name, hasCaboose, spotter.HasCars);
|
||||
_log.Information("AutoHotboxSpotter {name}: Hotbox Spotter Running, Has Caboose => {hasCaboose}; Has Cars {hasCars}; Requires Caboose {requiresCaboose}", spotter.name, hasCaboose, spotter.HasCars, cabooseRequired);
|
||||
if (CabooseRequirementChecker(string.Format("{0} {1}", spotter.GetType().Name, spotter.name), cabooseRequired, hasCaboose, _log))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
spotter.CheckForHotbox();
|
||||
while (spotter.HasCars)
|
||||
{
|
||||
@@ -82,12 +90,21 @@ namespace RMROC451.TweaksAndThings.Extensions
|
||||
{
|
||||
var numOrig = num;
|
||||
num = Random.Range(15, 30);
|
||||
_log.Information("AutoHotboxSpotter {name}: Next check went from num(60,300) => {numOrig}; to num(15,30) => {hasCaboose}", spotter.name, numOrig, num);
|
||||
_log.Information("AutoHotboxSpotter {name}: Next check went from num(60,300) => {numOrig}; to num(15,30) => {hasCaboose}; Requires Caboose {requiresCaboose}", spotter.name, numOrig, num, hasCaboose, cabooseRequired);
|
||||
}
|
||||
yield return new WaitForSeconds(num);
|
||||
spotter.CheckForHotbox();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CabooseRequirementChecker(string name, bool cabooseRequired, bool hasCaboose, Serilog.ILogger _log)
|
||||
{
|
||||
bool error = cabooseRequired && !hasCaboose;
|
||||
if (error) {
|
||||
_log.Debug("{name}: Couldn't find required caboose!", name);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,14 @@ namespace RMROC451.TweaksAndThings.Extensions;
|
||||
|
||||
public static class Car_Extensions
|
||||
{
|
||||
private static bool EndGearIssue(this Car car, Car.LogicalEnd end) =>
|
||||
(!car[end].IsCoupled && car[end].IsAnglecockOpen) ||
|
||||
(car[end].IsCoupled && !car[end].IsAirConnectedAndOpen);
|
||||
|
||||
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 AEndAirSystemIssue = car.EndGearIssue(Car.LogicalEnd.A);
|
||||
bool BEndAirSystemIssue = car.EndGearIssue(Car.LogicalEnd.B);
|
||||
bool EndAirSystemIssue = AEndAirSystemIssue || BEndAirSystemIssue;
|
||||
return EndAirSystemIssue;
|
||||
}
|
||||
@@ -104,18 +108,18 @@ public static class Car_Extensions
|
||||
Rect rect = new Rect(new Vector2(center.x - 30f, center.z - 30f), Vector2.one * 30f * 2f);
|
||||
var cars = tc.CarIdsInRect(rect);
|
||||
Log.Information($"{nameof(HuntingForCabeeseNearCar)} => {cars.Count()}");
|
||||
List<(string carId, float distance)> source =
|
||||
List<(string carId, float distance)> source =
|
||||
cars
|
||||
.Select(carId =>
|
||||
{
|
||||
Car car = tc.CarForId(carId);
|
||||
if (car == null || !car.CabooseWithSufficientCrewHours(timeNeeded, carIdsCheckedAlready))
|
||||
{
|
||||
Car car = tc.CarForId(carId);
|
||||
if (car == null || !car.CabooseWithSufficientCrewHours(timeNeeded, carIdsCheckedAlready))
|
||||
{
|
||||
return (carId: carId, distance: 1000f);
|
||||
}
|
||||
Vector3 a = WorldTransformer.WorldToGame(car.GetMotionSnapshot().Position);
|
||||
return (carId: carId, distance: Vector3.Distance(a, center));
|
||||
}).ToList();
|
||||
return (carId: carId, distance: 1000f);
|
||||
}
|
||||
Vector3 a = WorldTransformer.WorldToGame(car.GetMotionSnapshot().Position);
|
||||
return (carId: carId, distance: Vector3.Distance(a, center));
|
||||
}).ToList();
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,10 @@ internal class AutoHotboxSpotter_SpotterLoop_Patch
|
||||
{
|
||||
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
|
||||
if (!tweaksAndThings.IsEnabled) return true;
|
||||
bool buttonsHaveCost = tweaksAndThings?.settings?.EndGearHelpersRequirePayment ?? false;
|
||||
bool buttonsHaveCost = tweaksAndThings.EndGearHelpersRequirePayment();
|
||||
bool cabooseRequired = tweaksAndThings.RequireConsistCabooseForOilerAndHotboxSpotter();
|
||||
|
||||
if (buttonsHaveCost) __result = __instance.MrocAutoHotboxSpotterLoop(_log);
|
||||
if (buttonsHaveCost) __result = __instance.MrocAutoHotboxSpotterLoop(_log, cabooseRequired);
|
||||
return !buttonsHaveCost; //only hit this if !buttonsHaveCost, since Loop is a coroutine
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,10 @@ internal class AutoOiler_Loop_Patch
|
||||
{
|
||||
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
|
||||
if (!tweaksAndThings.IsEnabled) return true;
|
||||
bool buttonsHaveCost = tweaksAndThings?.settings?.EndGearHelpersRequirePayment ?? false;
|
||||
bool buttonsHaveCost = tweaksAndThings.EndGearHelpersRequirePayment();
|
||||
bool cabooseRequired = tweaksAndThings.RequireConsistCabooseForOilerAndHotboxSpotter();
|
||||
|
||||
if (buttonsHaveCost)__result = __instance.MrocAutoOilerLoop(_log);
|
||||
if (buttonsHaveCost) __result = __instance.MrocAutoOilerLoop(_log, cabooseRequired);
|
||||
return !buttonsHaveCost; //only hit this if !buttonsHaveCost, since Loop is a coroutine
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Game.Messages;
|
||||
using Core;
|
||||
using Game.Messages;
|
||||
using Game.State;
|
||||
using HarmonyLib;
|
||||
using KeyValue.Runtime;
|
||||
using Model;
|
||||
using Model.OpsNew;
|
||||
using Network;
|
||||
using Railloader;
|
||||
using RMROC451.TweaksAndThings.Enums;
|
||||
@@ -13,6 +13,7 @@ using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UI;
|
||||
using UI.Builder;
|
||||
using UI.CarInspector;
|
||||
using UI.ContextMenu;
|
||||
@@ -40,36 +41,61 @@ internal class CarInspector_PopulateCarPanel_Patch
|
||||
|
||||
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
|
||||
if (!tweaksAndThings.IsEnabled) return true;
|
||||
bool buttonsHaveCost = tweaksAndThings?.settings?.EndGearHelpersRequirePayment ?? false;
|
||||
bool buttonsHaveCost = tweaksAndThings.EndGearHelpersRequirePayment();
|
||||
|
||||
var consist = __instance._car.EnumerateCoupled(LogicalEnd.A);
|
||||
var consist = __instance._car._set.Cars;
|
||||
builder = AddCarConsistRebuildObservers(builder, consist);
|
||||
|
||||
builder.HStack(delegate (UIPanelBuilder hstack)
|
||||
{
|
||||
var buttonName = $"{(consist.Any(c => c.HandbrakeApplied()) ? "Release " : "Set ")} {TextSprites.HandbrakeWheel}";
|
||||
hstack.AddButtonCompact(buttonName, delegate {
|
||||
hstack.AddButtonCompact(buttonName, delegate
|
||||
{
|
||||
MrocConsistHelper(__instance._car, MrocHelperType.Handbrake, buttonsHaveCost);
|
||||
hstack.Rebuild();
|
||||
}).Tooltip(buttonName, $"Iterates over cars in this consist and {(consist.Any(c => c.HandbrakeApplied()) ? "releases" : "sets")} {TextSprites.HandbrakeWheel}.");
|
||||
|
||||
if (consist.Any(c => c.EndAirSystemIssue()))
|
||||
{
|
||||
hstack.AddButtonCompact("Connect Air", delegate {
|
||||
hstack.AddButtonCompact("Connect Air", delegate
|
||||
{
|
||||
MrocConsistHelper(__instance._car, MrocHelperType.GladhandAndAnglecock, buttonsHaveCost);
|
||||
hstack.Rebuild();
|
||||
}).Tooltip("Connect Consist Air", "Iterates over each car in this consist and connects gladhands and opens anglecocks.");
|
||||
}
|
||||
|
||||
hstack.AddButtonCompact("Bleed Consist", delegate {
|
||||
hstack.AddButtonCompact("Bleed Consist", delegate
|
||||
{
|
||||
MrocConsistHelper(__instance._car, MrocHelperType.BleedAirSystem, buttonsHaveCost);
|
||||
hstack.Rebuild();
|
||||
}).Tooltip("Bleed Air Lines", "Iterates over each car in this consist and bleeds the air out of the lines.");
|
||||
});
|
||||
|
||||
CabooseUiEnhancer(__instance, builder, consist, tweaksAndThings);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void CabooseUiEnhancer(CarInspector __instance, UIPanelBuilder builder, IEnumerable<Car> consist, TweaksAndThingsPlugin plugin)
|
||||
{
|
||||
if (plugin.CabooseNonMotiveAllowedSetting(__instance._car))
|
||||
{
|
||||
builder.HStack(delegate (UIPanelBuilder hstack)
|
||||
{
|
||||
hstack.AddField("Consist Info", hstack.HStack(delegate (UIPanelBuilder field)
|
||||
{
|
||||
int consistLength = consist.Count();
|
||||
int tonnage = LocomotiveControlsHoverArea.CalculateTonnage(consist);
|
||||
int lengthInMeters = UnityEngine.Mathf.CeilToInt(LocomotiveControlsHoverArea.CalculateLengthInMeters(consist.ToList()) * 3.28084f);
|
||||
var newSubTitle = () => string.Format("{0}, {1:N0}T, {2:N0}ft, {3:0.0} mph", consistLength.Pluralize("car"), tonnage, lengthInMeters, __instance._car.VelocityMphAbs);
|
||||
|
||||
field.AddLabel(() => newSubTitle(), UIPanelBuilder.Frequency.Fast)
|
||||
.Tooltip("Consist Info", "Reflects info about consist.").FlexibleWidth();
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static UIPanelBuilder AddCarConsistRebuildObservers(UIPanelBuilder builder, IEnumerable<Model.Car> consist)
|
||||
{
|
||||
TagController tagController = UnityEngine.Object.FindFirstObjectByType<TagController>();
|
||||
@@ -100,7 +126,7 @@ internal class CarInspector_PopulateCarPanel_Patch
|
||||
if (car.TagCallout != null) tagController.UpdateTags(CameraSelector.shared._currentCamera.GroundPosition, true); //tagController.UpdateTag(car, car.TagCallout, OpsController.Shared);
|
||||
if (ContextMenu.IsShown && ContextMenu.Shared.centerLabel.text == car.DisplayName) CarPickable.HandleShowContextMenu(car);
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.ForContext("car", car).Warning(ex, $"{nameof(AddObserver)} {car} Exception logged for {key}");
|
||||
}
|
||||
@@ -114,7 +140,7 @@ internal class CarInspector_PopulateCarPanel_Patch
|
||||
|
||||
//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) {
|
||||
@@ -125,7 +151,7 @@ internal class CarInspector_PopulateCarPanel_Patch
|
||||
public static void MrocConsistHelper(Model.Car car, MrocHelperType mrocHelperType, bool buttonsHaveCost)
|
||||
{
|
||||
TrainController tc = UnityEngine.Object.FindObjectOfType<TrainController>();
|
||||
IEnumerable<Model.Car> consist = car.EnumerateCoupled(LogicalEnd.A);
|
||||
IEnumerable<Model.Car> consist = car._set.Cars;
|
||||
_log.ForContext("car", car).Verbose($"{car} => {mrocHelperType} => {string.Join("/", consist.Select(c => c.ToString()))}");
|
||||
|
||||
CalculateCostIfEnabled(car, mrocHelperType, buttonsHaveCost, consist);
|
||||
@@ -194,7 +220,7 @@ internal class CarInspector_PopulateCarPanel_Patch
|
||||
|
||||
StateManager_OnDayDidChange_Patch.UnbilledAutoBrakeCrewRunDuration += timeCost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Car? NearbyCabooseWithAvailableCrew(Car car, float timeNeeded, bool decrement = false)
|
||||
{
|
||||
@@ -206,7 +232,7 @@ internal class CarInspector_PopulateCarPanel_Patch
|
||||
carIdsCheckedAlready.Add(car.id);
|
||||
|
||||
//check consist, for cabeese
|
||||
IEnumerable<Car> consist = car.EnumerateCoupled(LogicalEnd.A);
|
||||
IEnumerable<Car> consist = car._set.Cars;
|
||||
output = consist.FirstOrDefault(c => c.CabooseWithSufficientCrewHours(timeNeeded, carIdsCheckedAlready, decrement));
|
||||
if (output != null) return output; //short out if we are good
|
||||
carIdsCheckedAlready.UnionWith(consist.Select(c => c.id));
|
||||
|
||||
@@ -7,7 +7,6 @@ using RollingStock;
|
||||
using System.Linq;
|
||||
using UI;
|
||||
using UI.ContextMenu;
|
||||
using static Model.Car;
|
||||
|
||||
namespace RMROC451.TweaksAndThings.Patches;
|
||||
|
||||
@@ -21,15 +20,14 @@ internal class CarPickable_HandleShowContextMenu_Patch
|
||||
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
|
||||
if (!tweaksAndThings.IsEnabled) return;
|
||||
|
||||
bool buttonsHaveCost = tweaksAndThings?.settings?.EndGearHelpersRequirePayment ?? false;
|
||||
bool buttonsHaveCost = tweaksAndThings.EndGearHelpersRequirePayment();
|
||||
ContextMenu shared = ContextMenu.Shared;
|
||||
var consist = car.EnumerateCoupled(LogicalEnd.A);
|
||||
shared.AddButton(ContextMenuQuadrant.Unused2, $"{(consist.Any(c => c.HandbrakeApplied()) ? "Release " : "Set ")} Consist", SpriteName.Handbrake, delegate
|
||||
shared.AddButton(ContextMenuQuadrant.Unused2, $"{(car._set.Cars.Any(c => c.HandbrakeApplied()) ? "Release " : "Set ")} Consist", SpriteName.Handbrake, delegate
|
||||
{
|
||||
CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.Handbrake, buttonsHaveCost);
|
||||
});
|
||||
|
||||
if (consist.Any(c => c.EndAirSystemIssue()))
|
||||
if (car._set.Cars.Any(c => c.EndAirSystemIssue()))
|
||||
{
|
||||
shared.AddButton(ContextMenuQuadrant.Unused2, $"Air Up Consist", SpriteName.Select, delegate
|
||||
{
|
||||
@@ -37,7 +35,7 @@ internal class CarPickable_HandleShowContextMenu_Patch
|
||||
});
|
||||
}
|
||||
|
||||
if (consist.Any(c => c.SupportsBleed()))
|
||||
if (car._set.Cars.Any(c => c.SupportsBleed()))
|
||||
{
|
||||
shared.AddButton(ContextMenuQuadrant.Unused2, $"Bleed Consist", SpriteName.Bleed, delegate
|
||||
{
|
||||
@@ -45,6 +43,11 @@ internal class CarPickable_HandleShowContextMenu_Patch
|
||||
});
|
||||
}
|
||||
|
||||
shared.AddButton(ContextMenuQuadrant.Unused2, $"Follow", SpriteName.Inspect, delegate
|
||||
{
|
||||
CameraSelector.shared.FollowCar(car);
|
||||
});
|
||||
|
||||
shared.BuildItemAngles();
|
||||
shared.StartCoroutine(shared.AnimateButtonsShown());
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ using Model;
|
||||
using Model.OpsNew;
|
||||
using Railloader;
|
||||
using RMROC451.TweaksAndThings.Extensions;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UI.Tags;
|
||||
|
||||
namespace RMROC451.TweaksAndThings.Patches;
|
||||
@@ -32,13 +34,16 @@ internal class TagController_UpdateTag_Patch
|
||||
private static void ProceedWithPostFix(Car car, TagCallout tagCallout)
|
||||
{
|
||||
tagCallout.callout.Title = string.Format(tagTitleFormat, "{0}", car.DisplayName);
|
||||
List<string> tags = [];
|
||||
|
||||
if (car.HasHotbox) tags.Add(TextSprites.Hotbox);
|
||||
if (car.EndAirSystemIssue()) tags.Add(TextSprites.CycleWaybills);
|
||||
if (car.HandbrakeApplied()) tags.Add(TextSprites.HandbrakeWheel);
|
||||
|
||||
tagCallout.callout.Title =
|
||||
(car.CarAndEndGearIssue(), car.EndAirSystemIssue(), car.HandbrakeApplied()) switch
|
||||
tags.Any() switch
|
||||
{
|
||||
(true, _, _) => $"{tagCallout.callout.Title}{tagTitleAndIconDelimeter}{TextSprites.CycleWaybills}{TextSprites.HandbrakeWheel}".Replace("{0}", "2"),
|
||||
(_, true, _) => $"{tagCallout.callout.Title}{tagTitleAndIconDelimeter}{TextSprites.CycleWaybills}".Replace("{0}", "1"),
|
||||
(_, _, true) => $"{tagCallout.callout.Title}{tagTitleAndIconDelimeter}{TextSprites.HandbrakeWheel}".Replace("{0}", "1"),
|
||||
true => $"{tagCallout.callout.Title}{tagTitleAndIconDelimeter}{string.Join("", tags)}".Replace("{0}", tags.Count().ToString()),
|
||||
_ => car.DisplayName
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RMROC451.TweaksAndThings.Enums;
|
||||
using UI.Builder;
|
||||
using Model;
|
||||
using RMROC451.TweaksAndThings.Extensions;
|
||||
|
||||
namespace RMROC451.TweaksAndThings;
|
||||
|
||||
@@ -18,19 +21,26 @@ public class Settings
|
||||
List<WebhookSettings> webhookSettingsList,
|
||||
bool handBrakeAndAirTagModifiers,
|
||||
RosterFuelColumnSettings engineRosterFuelColumnSettings,
|
||||
bool endGearHelpersRequirePayment
|
||||
bool endGearHelpersRequirePayment,
|
||||
bool requireConsistCabooseForOilerAndHotboxSpotter,
|
||||
bool cabooseAllowsConsistInfo
|
||||
)
|
||||
{
|
||||
WebhookSettingsList = webhookSettingsList;
|
||||
HandBrakeAndAirTagModifiers = handBrakeAndAirTagModifiers;
|
||||
EngineRosterFuelColumnSettings = engineRosterFuelColumnSettings;
|
||||
EndGearHelpersRequirePayment = endGearHelpersRequirePayment;
|
||||
RequireConsistCabooseForOilerAndHotboxSpotter = requireConsistCabooseForOilerAndHotboxSpotter;
|
||||
CabooseAllowsConsistInfo = cabooseAllowsConsistInfo;
|
||||
}
|
||||
|
||||
public readonly UIState<string> _selectedTabState = new UIState<string>(null);
|
||||
public List<WebhookSettings>? WebhookSettingsList;
|
||||
public bool HandBrakeAndAirTagModifiers;
|
||||
public RosterFuelColumnSettings? EngineRosterFuelColumnSettings;
|
||||
public bool EndGearHelpersRequirePayment;
|
||||
public bool RequireConsistCabooseForOilerAndHotboxSpotter;
|
||||
public bool CabooseAllowsConsistInfo;
|
||||
|
||||
internal void AddAnotherRow()
|
||||
{
|
||||
@@ -82,13 +92,22 @@ public static class SettingsExtensions
|
||||
{
|
||||
public static List<WebhookSettings> SanitizeEmptySettings(this IEnumerable<WebhookSettings>? settings)
|
||||
{
|
||||
List<WebhookSettings> output =
|
||||
settings?.Where(s => !string.IsNullOrEmpty(s.WebhookUrl))?.ToList() ??
|
||||
List<WebhookSettings> output =
|
||||
settings?.Where(s => !string.IsNullOrEmpty(s.WebhookUrl))?.ToList() ??
|
||||
new();
|
||||
|
||||
output.Add(new());
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
public static bool CabooseAllowsConsistInfo(this TweaksAndThingsPlugin input) =>
|
||||
input?.settings?.CabooseAllowsConsistInfo ?? false;
|
||||
public static bool EndGearHelpersRequirePayment(this TweaksAndThingsPlugin input) =>
|
||||
input?.settings?.EndGearHelpersRequirePayment ?? false;
|
||||
public static bool RequireConsistCabooseForOilerAndHotboxSpotter(this TweaksAndThingsPlugin input) =>
|
||||
input?.settings?.RequireConsistCabooseForOilerAndHotboxSpotter ?? false;
|
||||
public static bool CabooseNonMotiveAllowedSetting(this TweaksAndThingsPlugin input, Car car) =>
|
||||
input.EndGearHelpersRequirePayment() && car.set.Cars.CabooseInConsist() && car.NotMotivePower();
|
||||
|
||||
}
|
||||
@@ -82,16 +82,73 @@ public class TweaksAndThingsPlugin : SingletonPluginBase<TweaksAndThingsPlugin>,
|
||||
settings.WebhookSettingsList =
|
||||
settings?.WebhookSettingsList.SanitizeEmptySettings();
|
||||
|
||||
//WebhookUISection(ref builder);
|
||||
//builder.AddExpandingVerticalSpacer();
|
||||
WebhooksListUISection(ref builder);
|
||||
builder.AddExpandingVerticalSpacer();
|
||||
HandbrakesAndAnglecocksUISection(ref builder);
|
||||
builder.AddExpandingVerticalSpacer();
|
||||
EnginRosterShowsFuelStatusUISection(ref builder);
|
||||
builder.AddTabbedPanels(settings._selectedTabState, delegate (UITabbedPanelBuilder tabBuilder)
|
||||
{
|
||||
tabBuilder.AddTab("Caboose Mods", "cabooseUpdates", CabooseMods);
|
||||
tabBuilder.AddTab("UI", "rosterUi", UiUpdates);
|
||||
tabBuilder.AddTab("Webhooks", "webhooks", WebhooksListUISection);
|
||||
});
|
||||
}
|
||||
|
||||
private void EnginRosterShowsFuelStatusUISection(ref UIPanelBuilder builder)
|
||||
private void CabooseMods(UIPanelBuilder builder)
|
||||
{
|
||||
builder.AddField(
|
||||
"Caboose Use",
|
||||
builder.AddToggle(
|
||||
() => settings?.EndGearHelpersRequirePayment ?? false,
|
||||
delegate (bool enabled)
|
||||
{
|
||||
if (settings == null) settings = new();
|
||||
settings.EndGearHelpersRequirePayment = enabled;
|
||||
builder.Rebuild();
|
||||
}
|
||||
)
|
||||
).Tooltip("Enable End Gear Helper Cost", @$"Will cost 1 minute of AI Brake Crew & Caboose Crew time per car in the consist when the new inspector buttons are utilized.
|
||||
|
||||
1.5x multiplier penalty to AI Brake Crew cost if no sufficiently crewed caboose nearby.
|
||||
|
||||
Caboose starts reloading `Crew Hours` at any Team or Repair track (no waybill), after being stationary for 30 seconds.
|
||||
|
||||
AutoOiler Update: Increases limit that crew will oiling a car from 75% -> 99%, also halves the time it takes (simulating crew from lead end and caboose handling half the train)
|
||||
|
||||
AutoHotboxSpotter Update: decrease the random wait from 30 - 300 seconds to 15 - 30 seconds (Safety Is Everyone's Job)");
|
||||
|
||||
builder.AddField(
|
||||
$"AutoAI\nRequirement",
|
||||
builder.AddToggle(
|
||||
() => settings?.RequireConsistCabooseForOilerAndHotboxSpotter ?? false,
|
||||
delegate (bool enabled)
|
||||
{
|
||||
if (settings == null) settings = new();
|
||||
settings.RequireConsistCabooseForOilerAndHotboxSpotter = enabled;
|
||||
builder.Rebuild();
|
||||
}
|
||||
)
|
||||
).Tooltip("AI Engineer Requires Caboose", $@"A caboose is required in the consist to check for Hotboxes and perform Auto Oiler, if checked.");
|
||||
}
|
||||
|
||||
private void UiUpdates(UIPanelBuilder builder)
|
||||
{
|
||||
builder.AddField(
|
||||
"Enable Tag Updates",
|
||||
builder.AddToggle(
|
||||
() => settings?.HandBrakeAndAirTagModifiers ?? false,
|
||||
delegate (bool enabled)
|
||||
{
|
||||
if (settings == null) settings = new();
|
||||
settings.HandBrakeAndAirTagModifiers = enabled;
|
||||
builder.Rebuild();
|
||||
}
|
||||
)
|
||||
).Tooltip("Enable Tag Updates", $@"Will suffix tag title with:
|
||||
{TextSprites.CycleWaybills} if Air System issue.
|
||||
{TextSprites.HandbrakeWheel} if there is a handbrake set.
|
||||
{TextSprites.Hotbox} if a hotbox.");
|
||||
|
||||
EngineRosterShowsFuelStatusUISection(builder);
|
||||
}
|
||||
|
||||
private void EngineRosterShowsFuelStatusUISection(UIPanelBuilder builder)
|
||||
{
|
||||
var columns = Enum.GetValues(typeof(EngineRosterFuelDisplayColumn)).Cast<EngineRosterFuelDisplayColumn>().Select(i => i.ToString()).ToList();
|
||||
builder.AddSection("Fuel Display in Engine Roster", delegate (UIPanelBuilder builder)
|
||||
@@ -123,39 +180,7 @@ public class TweaksAndThingsPlugin : SingletonPluginBase<TweaksAndThingsPlugin>,
|
||||
});
|
||||
}
|
||||
|
||||
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();
|
||||
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.");
|
||||
|
||||
builder.AddField(
|
||||
"Caboose Use",
|
||||
builder.AddToggle(
|
||||
() => settings?.EndGearHelpersRequirePayment ?? false,
|
||||
delegate (bool enabled)
|
||||
{
|
||||
if (settings == null) settings = new();
|
||||
settings.EndGearHelpersRequirePayment = enabled;
|
||||
builder.Rebuild();
|
||||
}
|
||||
)
|
||||
).Tooltip("Enable End Gear Helper Cost", $"Will cost 1 minute of AI Brake Crew & Caboose Crew time per car in the consist when the new inspector buttons are utilized.\n\n1.5x multiplier penalty to AI Brake Crew cost if no sufficiently crewed caboose nearby.\n\nCaboose starts reloading `Crew Hours` at any Team or Repair track (no waybill), after being stationary for 30 seconds.");
|
||||
});
|
||||
}
|
||||
|
||||
private void WebhooksListUISection(ref UIPanelBuilder builder)
|
||||
private void WebhooksListUISection(UIPanelBuilder builder)
|
||||
{
|
||||
builder.AddSection("Webhooks List", delegate (UIPanelBuilder builder)
|
||||
{
|
||||
|
||||
12
updates.json
Normal file
12
updates.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"RMROC451.TweaksAndThings": {
|
||||
"version": "1.0.0",
|
||||
"changelog": [
|
||||
{
|
||||
"version": "*",
|
||||
"date": "2024-07-26T14:31:49.0948925Z",
|
||||
"desc": "https://github.com/rmroc451/TweaksAndThings/releases"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user