Compare commits

...

5 Commits

16 changed files with 38 additions and 176 deletions

View File

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

View File

@@ -21,7 +21,6 @@
"mixintos": {
"container:ne-caboose01": "file(mroc-cabeese.json)",
"container:ne-caboose02": "file(mroc-cabeese.json)",
"container:ne-caboose03": "file(mroc-cabeese.json)",
"game-graph": "file(tweakedLoadIDS.json)"
"container:ne-caboose03": "file(mroc-cabeese.json)"
}
}

View File

@@ -19,7 +19,7 @@ namespace RMROC451.TweaksAndThings.Extensions
public static IEnumerator MrocAutoOilerLoop(this AutoOiler oiler, Serilog.ILogger _log, bool cabooseRequired)
{
int originIndex = oiler.FindOriginIndex();
Model.Car? foundCaboose = oiler._originCar.FindMyCaboose(0.0f, false);
Model.Car? foundCaboose = oiler._originCar.FindMyCabooseSansLoadRequirement();
if (originIndex < 0)
{
_log.Error("Couldn't find origin car {car}", oiler._originCar);
@@ -41,7 +41,7 @@ namespace RMROC451.TweaksAndThings.Extensions
while (true)
{
yield return new WaitForSeconds(AutoOiler.StartDelay.CabooseHalvedFloat(foundCaboose));
foundCaboose = oiler._originCar.FindMyCaboose(0.0f,false);
foundCaboose = oiler._originCar.FindMyCabooseSansLoadRequirement();
int carIndex = originIndex;
float adjustedTimeToWalk = AutoOiler.TimeToWalkCar.CabooseHalvedFloat(foundCaboose);
do
@@ -80,7 +80,7 @@ namespace RMROC451.TweaksAndThings.Extensions
public static IEnumerator MrocAutoHotboxSpotterLoop(this AutoHotboxSpotter spotter, Serilog.ILogger _log, bool cabooseRequired)
{
Func<Model.Car?> foundCaboose = () => spotter._locomotive.FindMyCaboose(0.0f, false);
Func<Model.Car?> foundCaboose = () => spotter._locomotive.FindMyCabooseSansLoadRequirement();
while (true)
{
if (!spotter.HasCars)

View File

@@ -7,6 +7,7 @@ using Model.Definition.Data;
using Model.Ops;
using Model.Ops.Timetable;
using Railloader;
using RMROC451.TweaksAndThings.Patches;
using Serilog;
using System;
using System.Collections.Generic;
@@ -98,21 +99,28 @@ public static class Car_Extensions
input.SelectedLocomotive.TryGetTimetableTrain(out Timetable.Train t) &&
t.TrainClass == Timetable.TrainClass.First;
public static Car? FindMyCaboose(this Car car, float timeNeeded, bool decrement = false) =>
public static Car? FindMyCabooseSansLoadRequirement(this Car car) =>
FindMyCaboose(car, 0f, decrement: false, requireLoad: false);
public static Car? FindMyCabooseWithLoadRequirement(this Car car, float timeNeeded, bool decrement) =>
FindMyCaboose(car, timeNeeded, decrement, requireLoad: false);
private static Car? FindMyCaboose(this Car car, float timeNeeded, bool decrement = false, bool requireLoad = true) =>
(
car.CarCaboose() ?? car.CarsNearCurrentCar(timeNeeded, decrement).FindNearestCabooseFromNearbyCars()
)?.CabooseWithSufficientCrewHours(timeNeeded, decrement);
)?.CabooseWithSufficientCrewHours(timeNeeded: timeNeeded, requireLoad:requireLoad, decrement: decrement);
public static Car? CabooseWithSufficientCrewHours(this Car car, float timeNeeded, bool decrement = false)
public static Car? CabooseWithSufficientCrewHours(this Car car, float timeNeeded, bool requireLoad, bool decrement = false)
{
Car? output = null;
if (car is null || !car.IsCaboose()) return null;
if (!requireLoad) return car;
List<LoadSlot> loadSlots = car.Definition.LoadSlots;
for (int i = 0; i < loadSlots.Count; i++)
{
CarLoadInfo? loadInfo = car.GetLoadInfo(i);
if (loadInfo.HasValue)
if (loadInfo.HasValue && loadInfo.Value.LoadId == OpsController_AnnounceCoalescedPayments_Patch.CrewLoadHours.id)
{
CarLoadInfo valueOrDefault = loadInfo.GetValueOrDefault();
output = valueOrDefault.Quantity >= timeNeeded ? car : null;

View File

@@ -72,7 +72,7 @@ internal class AutoEngineerOrdersHelper_SendAutoEngineerCommand_Patch
Func<bool> noCaboose = () =>
{
var output = TrainController.Shared.SelectedLocomotive.FindMyCaboose(0.0f, false) == null;
bool output = TrainController.Shared.SelectedLocomotive.FindMyCabooseSansLoadRequirement() == null;
logMessage += $"\ncaboose? {!output}";
return output;
};
@@ -87,7 +87,7 @@ internal class AutoEngineerOrdersHelper_SendAutoEngineerCommand_Patch
logMessage += $"\nGovern AE? {output}";
_log.Debug(logMessage);
_log.Information(logMessage);
return output;
}

View File

@@ -206,7 +206,7 @@ internal class AutoEngineerWaypointControls_ConfigureOptionsDropdown_Patch
o.Dispose();
}
var loco = TrainController.Shared.SelectedLocomotive;
TrainController.Shared.SelectedCar = null;
if (!TrainController.Shared.SelectRecall()) TrainController.Shared.SelectedCar = null;
_keyChangeObservers.Clear();
recalcing = true;
new WaitForSeconds(0.25f);

View File

@@ -227,8 +227,8 @@ internal class CarInspector_PopulateCarPanel_Patch
float originalTimeCost = consist.CalculateCostForAutoEngineerEndGearSetting();
float timeCost = originalTimeCost;
float crewCost = timeCost / 3600; //hours of time deducted from caboose.
var tsString = crewCost.FormatCrewHours(OpsController_AnnounceCoalescedPayments_Patch.CrewHoursLoad().description);
Car? cabooseWithAvailCrew = car.FindMyCaboose(crewCost, buttonsHaveCost);
var tsString = crewCost.FormatCrewHours(OpsController_AnnounceCoalescedPayments_Patch.CrewLoadHours.description);
Car? cabooseWithAvailCrew = car.FindMyCabooseWithLoadRequirement(crewCost, buttonsHaveCost);
if (cabooseWithAvailCrew == null) timeCost *= 1.5f;
var cabooseFoundDisplay = cabooseWithAvailCrew?.DisplayName ?? "No caboose";

View File

@@ -62,7 +62,7 @@ internal class CarPickable_Activate_Patch
var consist = car.EnumerateCoupled();
bool handbrakesApplied = consist.Any(c => c.HandbrakeApplied());
bool airSystemIssues = consist.Any(c => c.EndAirSystemIssue());
Func<bool> cabooseNear = () => (bool)car.FindMyCaboose(0.0f, false);
Func<bool> cabooseNear = () => (bool)car.FindMyCabooseSansLoadRequirement();
bool needsOiling = GameInput.IsShiftDown && consist.All(c => c.IsStopped()) && consist.Any(c => c.NeedsOiling || c.HasHotbox) && (!tweaksAndThings.RequireConsistCabooseForOilerAndHotboxSpotter() || cabooseNear());
var chargeIt = handbrakesApplied || airSystemIssues || needsOiling;
//CTRL + ALT + SHIFT : BrakesAngleCocksAndOiling

View File

@@ -4,6 +4,7 @@ using Railloader;
using RMROC451.TweaksAndThings.Enums;
using RMROC451.TweaksAndThings.Extensions;
using RollingStock;
using System;
using System.Linq;
using UI;
using UI.ContextMenu;
@@ -35,8 +36,6 @@ internal class CarPickable_HandleShowContextMenu_Patch
});
if (GameInput.IsShiftDown)
{
if (!car.EnumerateCoupled().Any(c => !c.SupportsBleed()))
{
shared.AddButton(ContextMenuQuadrant.Brakes, $"Bleed Consist", SpriteName.Bleed, delegate
@@ -52,7 +51,7 @@ internal class CarPickable_HandleShowContextMenu_Patch
if (car.EnumerateCoupled().Any(c => c.EndAirSystemIssue()))
{
shared.AddButton(ContextMenuQuadrant.Unused2, $"Air Up Consist", SpriteName.Select, delegate
shared.AddButton(ContextMenuQuadrant.General, $"Air Up Consist", SpriteName.Select, delegate
{
CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.GladhandAndAnglecock, buttonsHaveCost);
});
@@ -76,7 +75,9 @@ internal class CarPickable_HandleShowContextMenu_Patch
CameraSelector.shared.FollowCar(car);
});
shared.Show(car.DisplayName);
string secondaryLine = car.Waybill.HasValue ? $"{Environment.NewLine}{car.Waybill.Value.Destination.DisplayName}" : string.Empty;
secondaryLine = secondaryLine.Length > 10 + Environment.NewLine.Length ? $"{secondaryLine.Substring(0, 7+ Environment.NewLine.Length)}..." : secondaryLine;
shared.Show($"{car.DisplayName}{secondaryLine}");
shared.BuildItemAngles();
shared.StartCoroutine(shared.AnimateButtonsShown());
return false;

View File

@@ -1,128 +0,0 @@
using HarmonyLib;
using Helpers;
using Railloader;
using Serilog;
using System;
using System.Collections.Generic;
using UI;
using UI.ContextMenu;
using UnityEngine;
using UnityEngine.UI;
namespace RMROC451.TweaksAndThings.Patches;
[HarmonyPatch(typeof(UI.ContextMenu.ContextMenu))]
[HarmonyPatch(nameof(UI.ContextMenu.ContextMenu.Show), typeof(string))]
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
internal class ContextMenu_Show_Patch
{
static bool Prefix(UI.ContextMenu.ContextMenu __instance, string centerText)
{
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
if (!tweaksAndThings.IsEnabled()) return true;
if (!__instance.GetRootCanvas(out var rootCanvas))
{
Log.Warning("Couldn't get root canvas");
return true;
}
__instance.CancelHideCoroutine();
if (__instance.contentRectTransform.childCount >= 1) __instance.contentRectTransform.GetChild(0).DestroyAllChildren(); //YOINK DEM CIRCLES!
__instance.SetupTemplate(rootCanvas);
__instance.centerLabel.text = centerText;
Canvas componentInParent = ((Component)__instance.contentRectTransform).GetComponentInParent<Canvas>();
Vector3 mousePosition = Input.mousePosition;
Vector2 val = componentInParent.ScreenToCanvasPosition(mousePosition).XY();
Vector2 renderingDisplaySize = rootCanvas.renderingDisplaySize;
float num = __instance.radius + 50f;
if (val.x < num)
{
val.x = num;
}
if (val.x > renderingDisplaySize.x - num)
{
val.x = renderingDisplaySize.x - num;
}
if (val.y < num)
{
val.y = num;
}
if (val.y > renderingDisplaySize.y - num)
{
val.y = renderingDisplaySize.y - num;
}
__instance.contentRectTransform.anchoredPosition = val;
__instance.BuildItemAngles();
((MonoBehaviour)__instance).StartCoroutine(__instance.AnimateButtonsShown());
((Component)__instance.contentRectTransform).gameObject.SetActive(true);
UI.ContextMenu.ContextMenu.IsShown = true;
__instance._blocker = __instance.CreateBlocker(rootCanvas);
GameInput.RegisterEscapeHandler(GameInput.EscapeHandler.Transient, delegate
{
__instance.Hide();
return true;
});
return false;
}
}
[HarmonyPatch(typeof(UI.ContextMenu.ContextMenu))]
[HarmonyPatch(nameof(UI.ContextMenu.ContextMenu.DefaultAngleForItem), typeof(ContextMenuQuadrant), typeof(int), typeof(int))]
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
internal class ContextMenu_DefaultAngleForItem_Patch
{
static bool Prefix(UI.ContextMenu.ContextMenu __instance, ref float __result, ContextMenuQuadrant quadrant, int index, int quadrantItemCount)
{
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
if (!tweaksAndThings.IsEnabled()) return true;
int num = quadrant switch
{
ContextMenuQuadrant.General => 0,
ContextMenuQuadrant.Unused1 => 90,
ContextMenuQuadrant.Brakes => 180,
ContextMenuQuadrant.Unused2 => -90,
_ => throw new ArgumentOutOfRangeException("quadrant", quadrant, null),
};
if (quadrantItemCount <= 1)
{
__result = num;
return false;
}
int num2 = ((quadrantItemCount <= 3) ? 30 : (90 / (quadrantItemCount - 1)));
__result = (float)num + -0.5f * (float)((quadrantItemCount - 1) * num2) + (float)(num2 * index);
return false;
}
}
[HarmonyPatch(typeof(UI.ContextMenu.ContextMenu))]
[HarmonyPatch(nameof(UI.ContextMenu.ContextMenu.AddButton), typeof(ContextMenuQuadrant), typeof(string), typeof(Sprite), typeof(Action))]
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
internal class ContextMenu_AddButton_Patch
{
static bool Prefix(UI.ContextMenu.ContextMenu __instance, ContextMenuQuadrant quadrant, string title, Sprite sprite, Action action)
{
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
if (!tweaksAndThings.IsEnabled()) return true;
List<ContextMenuItem> list = __instance._quadrants[(int)quadrant];
int index = list.Count;
ContextMenuItem contextMenuItem = UnityEngine.Object.Instantiate<ContextMenuItem>(__instance.itemPrefab, (Transform)(object)__instance.contentRectTransform);
contextMenuItem.image.sprite = sprite;
contextMenuItem.label.text = title;
contextMenuItem.OnClick = delegate
{
action();
__instance.Hide((quadrant, index));
};
((Component)contextMenuItem).gameObject.AddComponent<LayoutElement>().preferredHeight = 30f;
list.Add(contextMenuItem);
return false;
}
}

View File

@@ -52,7 +52,7 @@ internal class EngineRosterRow_Refresh_Patch
bool cabooseRequirementFulfilled =
!tweaksAndThings.RequireConsistCabooseForOilerAndHotboxSpotter()
|| consist.ConsistNoFreight()
|| (bool)engineOrTender.FindMyCaboose(0.0f, false);
|| (bool)engineOrTender.FindMyCabooseSansLoadRequirement();
float offendingPercentage = 100f;
foreach (Car loco in locos)

View File

@@ -24,7 +24,7 @@ internal class CarExtensions_LoadString_Patch
{
public static bool Prefix(CarLoadInfo info, Load load, ref string __result)
{
bool output = load.id == OpsController_AnnounceCoalescedPayments_Patch.CrewHoursLoad().id;
bool output = load.id == OpsController_AnnounceCoalescedPayments_Patch.CrewLoadHours.id;
if (output) __result = info.Quantity.FormatCrewHours(load.description);
return !output;
@@ -38,7 +38,7 @@ internal class CarPrototypeLibrary_LoadForId_Patch
{
public static bool Prefix(string loadId, ref Load __result)
{
Load load = OpsController_AnnounceCoalescedPayments_Patch.CrewHoursLoad();
Load load = OpsController_AnnounceCoalescedPayments_Patch.CrewLoadHours;
if (loadId == load.id) __result = load;
return __result == null;
@@ -70,7 +70,9 @@ internal class OpsController_AnnounceCoalescedPayments_Patch
typeof(RepairTrack)
};
public static Load CrewHoursLoad()
private static Load _crewLoadHours;
internal static Load CrewLoadHours => _crewLoadHours ?? CrewHoursLoad();
private static Load CrewHoursLoad()
{
Load load = (Load)ScriptableObject.CreateInstance(typeof(Load));
load.name = "crew-hours";

View File

@@ -36,11 +36,11 @@ internal class StateManager_OnDayDidChange_Patch
{
foreach (var car in TrainController.Shared.Cars.Where(Car_Extensions.IsCaboose))
{
var data = car.QuantityCapacityOfLoad(OpsController_AnnounceCoalescedPayments_Patch.CrewHoursLoad());
var data = car.QuantityCapacityOfLoad(OpsController_AnnounceCoalescedPayments_Patch.CrewLoadHours);
if (data.quantity < data.capacity)
{
Multiplayer.Broadcast($"{Hyperlink.To(car)}: \"Caboose crew topped off.\"");
new OpsCarAdapter(car, OpsController.Shared).Load(OpsController_AnnounceCoalescedPayments_Patch.CrewHoursLoad(), data.capacity - data.quantity);
new OpsCarAdapter(car, OpsController.Shared).Load(OpsController_AnnounceCoalescedPayments_Patch.CrewLoadHours, data.capacity - data.quantity);
}
}
}

View File

@@ -43,7 +43,7 @@ internal class TagController_UpdateTag_Patch
//if (car.EnableOiling) tags.Add(car.HasHotbox ? TextSprites.Hotbox : $"<cspace=-1em>{TextSprites.Warning}{car.Oiled.TriColorPiePercent(1)}</cspace>");
if (car.EnableOiling) tags.Add(car.HasHotbox ? TextSprites.Hotbox : car.Oiled.TriColorPiePercent(1, oilSpriteName));
IEnumerable<Car> consist = car.EnumerateCoupled().Where(c => c.EnableOiling);
Func<bool> cabooseRequirementFulfilled = () => (!cabooseRequired || consist.ConsistNoFreight() || car.FindMyCaboose(0.0f, false));
Func<bool> cabooseRequirementFulfilled = () => (!cabooseRequired || consist.ConsistNoFreight() || (bool)car.FindMyCabooseSansLoadRequirement());
if (StateManager.Shared.Storage.OilFeature
&& car.IsLocomotive
&& !car.NeedsOiling

View File

@@ -1,20 +0,0 @@
using HarmonyLib;
using Railloader;
using UI.ContextMenu;
using UnityEngine.UI;
namespace RMROC451.TweaksAndThings.Patches;
[HarmonyPatch(typeof(WedgeImage))]
[HarmonyPatch(nameof(WedgeImage.OnPopulateMesh), typeof(VertexHelper))]
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
internal class WedgeImage_OnPopulateMesh_Patch
{
private static void Postfix(VertexHelper vh)
{
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
if (!tweaksAndThings.IsEnabled()) return;
vh.Clear(); //clear the image backgrounds for now.
}
}

View File

@@ -129,7 +129,7 @@ public static class SettingsExtensions
public static bool RequireConsistCabooseForOilerAndHotboxSpotter(this TweaksAndThingsPlugin input) =>
input?.settings?.RequireConsistCabooseForOilerAndHotboxSpotter ?? false;
public static bool CabooseNonMotiveAllowedSetting(this TweaksAndThingsPlugin input, Car car) =>
input.EndGearHelpersRequirePayment() && !car.MotivePower() && (bool)car.FindMyCaboose(0.0f, false);
input.EndGearHelpersRequirePayment() && !car.MotivePower() && (bool)car.FindMyCabooseSansLoadRequirement();
public static bool CabooseRequiredForLocoOilIndicator(this TweaksAndThingsPlugin input) =>
input?.settings?.CabooseRequiredForLocoTagOilIndication ?? false;
public static bool ServiceFundPenalties(this TweaksAndThingsPlugin input) =>