mirror of
https://github.com/rmroc451/TweaksAndThings.git
synced 2025-12-16 17:29:37 -06:00
Merge pull request #38 from rmroc451/37-passenger-stops-not-filling-crew-hours-on-cabeese
#37 refactored caboose crew hours load refill logic, condensing and a…
This commit is contained in:
@@ -208,7 +208,7 @@ 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(IndustryComponent_Service_Patch.CrewHoursLoad().description);
|
||||
var tsString = crewCost.FormatCrewHours(OpsController_AnnounceCoalescedPayments_Patch.CrewHoursLoad().description);
|
||||
Car? cabooseWithAvailCrew = NearbyCabooseWithAvailableCrew(car, crewCost, buttonsHaveCost);
|
||||
if (cabooseWithAvailCrew == null) timeCost *= 1.5f;
|
||||
var cabooseFoundDisplay = cabooseWithAvailCrew?.DisplayName ?? "No caboose";
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
using Game.State;
|
||||
using HarmonyLib;
|
||||
using Model;
|
||||
using Model.Definition.Data;
|
||||
using Model.Ops.Definition;
|
||||
using Model.OpsNew;
|
||||
using Railloader;
|
||||
using RMROC451.TweaksAndThings.Extensions;
|
||||
using Serilog;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RMROC451.TweaksAndThings.Patches;
|
||||
|
||||
[HarmonyPatch(typeof(CarExtensions))]
|
||||
[HarmonyPatch(nameof(CarExtensions.LoadString), typeof(CarLoadInfo), typeof(Load))]
|
||||
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
|
||||
internal class CarExtensions_LoadString_Patch
|
||||
{
|
||||
public static bool Prefix(CarLoadInfo info, Load load, ref string __result)
|
||||
{
|
||||
bool output = load.id == IndustryComponent_Service_Patch.CrewHoursLoad().id;
|
||||
if (output) __result = info.Quantity.FormatCrewHours(load.description);
|
||||
|
||||
return !output;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(CarPrototypeLibrary))]
|
||||
[HarmonyPatch(nameof(CarPrototypeLibrary.LoadForId), typeof(string))]
|
||||
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
|
||||
internal class CarPrototypeLibrary_LoadForId_Patch
|
||||
{
|
||||
public static bool Prefix(string loadId, ref Load __result)
|
||||
{
|
||||
Load load = IndustryComponent_Service_Patch.CrewHoursLoad();
|
||||
if (loadId == load.id) __result = load;
|
||||
|
||||
return __result == null;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(TeamTrack))]
|
||||
[HarmonyPatch(nameof(TeamTrack.Service), typeof(IIndustryContext))]
|
||||
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
|
||||
internal class TeamTrack_Service_Patch
|
||||
{
|
||||
public static bool Prefix(IndustryComponent __instance, IIndustryContext ctx)
|
||||
{
|
||||
//Log.Information($"{nameof(SimplePassengerStop_Service_Patch)} => {((IndustryContext)ctx)._industry.name}");
|
||||
return IndustryComponent_Service_Patch.Prefix(__instance, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(RepairTrack))]
|
||||
[HarmonyPatch(nameof(RepairTrack.Service), typeof(IIndustryContext))]
|
||||
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
|
||||
internal class RepairTrack_Service_Patch
|
||||
{
|
||||
public static bool Prefix(IndustryComponent __instance, IIndustryContext ctx)
|
||||
{
|
||||
//Log.Information($"{nameof(SimplePassengerStop_Service_Patch)} => {((IndustryContext)ctx)._industry.name}");
|
||||
return IndustryComponent_Service_Patch.Prefix(__instance, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(SimplePassengerStop))]
|
||||
[HarmonyPatch(nameof(SimplePassengerStop.Service), typeof(IIndustryContext))]
|
||||
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
|
||||
internal class SimplePassengerStop_Service_Patch
|
||||
{
|
||||
public static bool Prefix(IndustryComponent __instance, IIndustryContext ctx)
|
||||
{
|
||||
Log.Information($"{nameof(SimplePassengerStop_Service_Patch)} => {((IndustryContext)ctx)._industry.name}");
|
||||
return IndustryComponent_Service_Patch.Prefix(__instance, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
internal static class IndustryComponent_Service_Patch
|
||||
{
|
||||
public static Load CrewHoursLoad()
|
||||
{
|
||||
Load load = (Load)ScriptableObject.CreateInstance(typeof(Load));
|
||||
load.name = "crew-hours";
|
||||
load.description = "Crew";
|
||||
load.units = LoadUnits.Quantity;
|
||||
|
||||
return load;
|
||||
}
|
||||
|
||||
public static bool Prefix(IndustryComponent __instance, IIndustryContext ctx)
|
||||
{
|
||||
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
|
||||
if (!StateManager.IsHost || !tweaksAndThings.IsEnabled || !(tweaksAndThings?.settings?.EndGearHelpersRequirePayment ?? false)) return true;
|
||||
|
||||
Load load = CrewHoursLoad();
|
||||
|
||||
float rate2 = 24 * 2 * 8;// carLoadRate = 8 crew hours in 30 min loading; (24h * 2 to get half hour chunks * 8 hours to load in those chunks)
|
||||
float num2 = 99999999; //QuantityInStorage for crew-hours (infinite where crew can be shuffling about)
|
||||
float quantityToLoad = Mathf.Min(num2, IndustryComponent.RateToValue(rate2, ctx.DeltaTime));
|
||||
|
||||
var carsAtPosition = ctx.CarsAtPosition();
|
||||
|
||||
var cabeese = from car in carsAtPosition.Where(c => c.CarType == "NE")
|
||||
where car.IsEmptyOrContains(load)
|
||||
orderby car.QuantityOfLoad(load).quantity descending
|
||||
select car;
|
||||
|
||||
foreach (IOpsCar item in cabeese)
|
||||
{
|
||||
TrainController tc = UnityEngine.Object.FindAnyObjectByType<TrainController>();
|
||||
if (tc.TryGetCarForId(item.Id, out Car car))
|
||||
{
|
||||
List<LoadSlot> loadSlots = car.Definition.LoadSlots;
|
||||
float quantity = 0f;
|
||||
float max = 0f;
|
||||
for (int i = 0; i < loadSlots.Count; i++)
|
||||
{
|
||||
LoadSlot loadSlot = loadSlots[i];
|
||||
if (loadSlot.LoadRequirementsMatch(load) && loadSlot.LoadUnits == load.units)
|
||||
{
|
||||
CarLoadInfo? loadInfo = car.GetLoadInfo(i);
|
||||
|
||||
quantity = loadInfo.HasValue ? loadInfo.Value.Quantity : 0f;
|
||||
max = loadSlots[i].MaximumCapacity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Log.Information($"{nameof(IndustryComponent_Service_Patch)} {car} => {car.StoppedDuration} => {quantityToLoad} => {quantity}/{max}");
|
||||
if (car.StoppedDuration > 30) item.Load(load, quantityToLoad);
|
||||
}
|
||||
|
||||
//todo:crew refresh message?
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
using Game;
|
||||
using Game.State;
|
||||
using HarmonyLib;
|
||||
using Model;
|
||||
using Model.Definition.Data;
|
||||
using Model.Ops.Definition;
|
||||
using Model.OpsNew;
|
||||
using Network;
|
||||
using Railloader;
|
||||
using RMROC451.TweaksAndThings.Extensions;
|
||||
using RollingStock;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RMROC451.TweaksAndThings.Patches;
|
||||
|
||||
[HarmonyPatch(typeof(CarExtensions))]
|
||||
[HarmonyPatch(nameof(CarExtensions.LoadString), typeof(CarLoadInfo), typeof(Load))]
|
||||
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
|
||||
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;
|
||||
if (output) __result = info.Quantity.FormatCrewHours(load.description);
|
||||
|
||||
return !output;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(CarPrototypeLibrary))]
|
||||
[HarmonyPatch(nameof(CarPrototypeLibrary.LoadForId), typeof(string))]
|
||||
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
|
||||
internal class CarPrototypeLibrary_LoadForId_Patch
|
||||
{
|
||||
public static bool Prefix(string loadId, ref Load __result)
|
||||
{
|
||||
Load load = OpsController_AnnounceCoalescedPayments_Patch.CrewHoursLoad();
|
||||
if (loadId == load.id) __result = load;
|
||||
|
||||
return __result == null;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(OpsController))]
|
||||
[HarmonyPatch(nameof(OpsController.AnnounceCoalescedPayments))]
|
||||
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
|
||||
internal class OpsController_AnnounceCoalescedPayments_Patch
|
||||
{
|
||||
static Dictionary<string, (bool spotted, bool filling)> CrewCarDict = [];
|
||||
public static (bool spotted, bool filling) CrewCarStatus(Car car)
|
||||
{
|
||||
bool found = CrewCarDict.TryGetValue(car.id, out (bool spotted, bool filling) val);
|
||||
|
||||
if (!found) CrewCarDict.Add(car.id, (false, false));
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static GameDateTime dateTime = TimeWeather.Now;
|
||||
static readonly IEnumerable<Type> refillLocations = [
|
||||
typeof(PassengerStop),
|
||||
typeof(SimplePassengerStop),
|
||||
typeof(TeamTrack),
|
||||
typeof(RepairTrack)
|
||||
];
|
||||
|
||||
public static Load CrewHoursLoad()
|
||||
{
|
||||
Load load = (Load)ScriptableObject.CreateInstance(typeof(Load));
|
||||
load.name = "crew-hours";
|
||||
load.description = "Crew";
|
||||
load.units = LoadUnits.Quantity;
|
||||
|
||||
return load;
|
||||
}
|
||||
|
||||
private static void CarLoadCrewHelper(Car car, float deltaTime)
|
||||
{
|
||||
float rate2 = 24 * 2 * 8;// carLoadRate = 8 crew hours in 30 min loading; (24h * 2 to get half hour chunks * 8 hours to load in those chunks)
|
||||
float num2 = 99999999; //QuantityInStorage for crew-hours (infinite where crew can be shuffling about)
|
||||
float quantityToLoad = Mathf.Min(num2, IndustryComponent.RateToValue(rate2, deltaTime));
|
||||
|
||||
if (car.IsCaboose() && !CrewCarStatus(car).spotted)
|
||||
{
|
||||
CrewCarDict[car.id] = (true, CrewCarDict[car.id].filling);
|
||||
}
|
||||
if (car.IsCabooseAndStoppedForLoadRefresh())
|
||||
{
|
||||
if (!CrewCarDict[car.id].filling) Multiplayer.Broadcast($"{Hyperlink.To(car)}: \"Topping off caboose crew.\"");
|
||||
CrewCarDict[car.id] = (CrewCarDict[car.id].spotted, true);
|
||||
var data = car.QuantityCapacityOfLoad(CrewHoursLoad());
|
||||
if ((data.quantity + quantityToLoad > data.capacity) && data.quantity < data.capacity)
|
||||
{
|
||||
Multiplayer.Broadcast($"{Hyperlink.To(car)}: \"Caboose crew topped off.\"");
|
||||
CrewCarDict[car.id] = (CrewCarDict[car.id].spotted, false);
|
||||
}
|
||||
new OpsCarAdapter(car, OpsController.Shared).Load(CrewHoursLoad(), quantityToLoad);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Prefix(IndustryComponent __instance)
|
||||
{
|
||||
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
|
||||
if (!StateManager.IsHost || !tweaksAndThings.IsEnabled || !(tweaksAndThings?.settings?.EndGearHelpersRequirePayment ?? false)) return true;
|
||||
|
||||
|
||||
TrainController tc = UnityEngine.Object.FindAnyObjectByType<TrainController>();
|
||||
try {
|
||||
|
||||
var passengerStops = OpsController.Shared.AllIndustries
|
||||
.SelectMany(i => i.TrackDisplayables.Where(t => refillLocations.Contains(t.GetType())));
|
||||
//Log.Information($"{nameof(OpsController_AnnounceCoalescedPayments_Patch)} => Caboose Helper => PassengerStops => {string.Join(",", passengerStops)}");
|
||||
|
||||
var cabeese = passengerStops
|
||||
.SelectMany(t => t.TrackSpans?.Select(s => (tc.CarsOnSpan(s) ?? []).Where(c => c.IsCaboose()))?.SelectMany(c => c?.Select(c2 => (t, c2))));
|
||||
//Log.Information($"{nameof(OpsController_AnnounceCoalescedPayments_Patch)} => Caboose Helper => PassengerStops Cabeese => {string.Join(",", cabeese?.Select(c => $"{c.t} : {c.c2}") ?? [])}");
|
||||
|
||||
CrewCarDict = CrewCarDict.Where(kvp => cabeese.Select(c => c.c2.id).Contains(kvp.Key)).ToDictionary(k => k.Key, v => v.Value);
|
||||
|
||||
var deltaTime = (float)(TimeWeather.Now.TotalSeconds - dateTime.TotalSeconds);
|
||||
foreach (var caboose in cabeese)
|
||||
{
|
||||
//Log.Information($"{nameof(OpsController_AnnounceCoalescedPayments_Patch)} => Caboose Helper ({deltaTime}) => {caboose.t} : {caboose.c2}");
|
||||
CarLoadCrewHelper(caboose.c2, deltaTime);
|
||||
}
|
||||
dateTime = TimeWeather.Now;
|
||||
} catch (System.Exception ex)
|
||||
{
|
||||
Log.Error(ex, "error with announce caboose helper");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ internal class TagController_UpdateTag_Patch
|
||||
tagCallout.callout.Title = string.Format(tagTitleFormat, "{0}", car.DisplayName);
|
||||
List<string> tags = [];
|
||||
|
||||
if (OpsController_AnnounceCoalescedPayments_Patch.CrewCarStatus(car).spotted) tags.Add("+");
|
||||
if (car.HasHotbox) tags.Add(TextSprites.Hotbox);
|
||||
if (car.EndAirSystemIssue()) tags.Add(TextSprites.CycleWaybills);
|
||||
if (car.HandbrakeApplied()) tags.Add(TextSprites.HandbrakeWheel);
|
||||
|
||||
Reference in New Issue
Block a user