mirror of
https://github.com/rmroc451/TweaksAndThings.git
synced 2025-12-17 01:39:38 -06:00
coroutine vs observers
This commit is contained in:
@@ -1,79 +1,80 @@
|
|||||||
using GalaSoft.MvvmLight.Messaging;
|
using Game.Messages;
|
||||||
using Game.Events;
|
|
||||||
using Game.Messages;
|
|
||||||
using Game.State;
|
using Game.State;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using KeyValue.Runtime;
|
|
||||||
using Model;
|
using Model;
|
||||||
using Model.AI;
|
using Model.AI;
|
||||||
using Model.Ops;
|
using Model.Ops;
|
||||||
using Model.Ops.Timetable;
|
using Model.Ops.Timetable;
|
||||||
using Model.Physics;
|
|
||||||
using Network;
|
using Network;
|
||||||
using Network.Messages;
|
using Network.Messages;
|
||||||
using Railloader;
|
using Railloader;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Track;
|
using Track;
|
||||||
using Track.Search;
|
using Track.Search;
|
||||||
using UI;
|
using UI;
|
||||||
using UI.EngineControls;
|
using UI.EngineControls;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
using static Track.Search.RouteSearch;
|
using static Track.Search.RouteSearch;
|
||||||
using Location = Track.Location;
|
using Location = Track.Location;
|
||||||
|
|
||||||
namespace RMROC451.TweaksAndThings.Patches;
|
namespace RMROC451.TweaksAndThings.Patches;
|
||||||
|
|
||||||
[HarmonyPatch(typeof(AutoEngineerWaypointControls))]
|
[HarmonyPatch(typeof(LocomotiveControlsUIAdapter))]
|
||||||
[HarmonyPatch(nameof(AutoEngineerWaypointControls.ConfigureOptionsDropdown))]
|
[HarmonyPatch(nameof(LocomotiveControlsUIAdapter.UpdateCarText))]
|
||||||
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
|
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
|
||||||
internal class AutoEngineerWaypointControls_ConfigureOptionsDropdown_Patch
|
internal class LocomotiveControlsUIAdapter_UpdateCarText_Postfix()
|
||||||
{
|
{
|
||||||
private static Serilog.ILogger _log => Log.ForContext<AutoEngineerWaypointControls_ConfigureOptionsDropdown_Patch>();
|
private static Serilog.ILogger _log => Log.ForContext<LocomotiveControlsUIAdapter_UpdateCarText_Postfix>();
|
||||||
private static readonly HashSet<IDisposable> _keyChangeObservers = [];
|
private static int lastSeenIntegrationSetCount = default;
|
||||||
|
private static string? lastLocoSeenCarId = default;
|
||||||
|
private static Coroutine? watchyWatchy = null;
|
||||||
private static HashSet<OpsCarPosition?> locoConsistDestinations = [];
|
private static HashSet<OpsCarPosition?> locoConsistDestinations = [];
|
||||||
private static Game.GameDateTime? timetableSaveTime = null;
|
private static Game.GameDateTime? timetableSaveTime = null;
|
||||||
static string getDictKey(Car car) => car.DisplayName;
|
static string getDictKey(Car car) => car.DisplayName;
|
||||||
static Car placeholder = new();
|
|
||||||
|
|
||||||
static void Postfix(AutoEngineerWaypointControls __instance, ref OptionsDropdownConfiguration __result)
|
static void Postfix(LocomotiveControlsUIAdapter __instance)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PrepLocoUsage(__instance, out BaseLocomotive selectedLoco, out int numberOfCars);
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.Error(ex, "I have a very unique set of skills; I will find you and I will squash you.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerator UpdateCogCoroutine(LocomotiveControlsUIAdapter __instance)
|
||||||
|
{
|
||||||
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
|
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
|
||||||
if (!tweaksAndThings.IsEnabled() || !ShouldRecalc(selectedLoco)) return;
|
WaitForSecondsRealtime wait = new WaitForSecondsRealtime(3f);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (__instance._persistence.Orders.Mode != AutoEngineerMode.Waypoint) yield return wait;
|
||||||
|
|
||||||
|
PrepLocoUsage((AutoEngineerWaypointControls)__instance.aiWaypointControls, out BaseLocomotive selectedLoco, out int numberOfCars);
|
||||||
|
HashSet<OpsCarPosition?> destinations = [];
|
||||||
|
if (!tweaksAndThings.IsEnabled() || !ShouldRecalc(__instance, selectedLoco, out destinations)) yield return wait;
|
||||||
timetableSaveTime = TimetableController.Shared.CurrentDocument.Modified;
|
timetableSaveTime = TimetableController.Shared.CurrentDocument.Modified;
|
||||||
Messenger.Default.Unregister(placeholder);
|
lastSeenIntegrationSetCount = selectedLoco.set.NumberOfCars;
|
||||||
|
|
||||||
Messenger.Default.Register(placeholder, delegate (TimetableDidChange evt)
|
|
||||||
{
|
|
||||||
_log.Debug("Received {evt}, rebuilding.", evt);
|
|
||||||
Rebuild(__instance, selectedLoco, evt.GetType().Name);
|
|
||||||
});
|
|
||||||
Messenger.Default.Register(placeholder, delegate (CarTrainCrewChanged evt)
|
|
||||||
{
|
|
||||||
_log.Debug("Received {evt}, rebuilding {1} - {2}.", evt, selectedLoco.id, evt.CarId);
|
|
||||||
Rebuild(__instance, selectedLoco, evt.GetType().Name);
|
|
||||||
});
|
|
||||||
Messenger.Default.Register(placeholder, delegate (TrainCrewsDidChange evt)
|
|
||||||
{
|
|
||||||
_log.Debug("Received {evt}, rebuilding.", evt);
|
|
||||||
Rebuild(__instance, selectedLoco, evt.GetType().Name);
|
|
||||||
});
|
|
||||||
Messenger.Default.Register(placeholder, delegate (UpdateTrainCrews evt)
|
|
||||||
{
|
|
||||||
_log.Debug("Received {evt}, rebuilding.", evt);
|
|
||||||
Rebuild(__instance, selectedLoco, evt.GetType().Name);
|
|
||||||
});
|
|
||||||
|
|
||||||
IterateCarsDetectDestinations(
|
IterateCarsDetectDestinations(
|
||||||
__instance,
|
(AutoEngineerWaypointControls)__instance.aiWaypointControls,
|
||||||
__result,
|
((AutoEngineerWaypointControls)__instance.aiWaypointControls).ConfigureOptionsDropdown(),
|
||||||
selectedLoco,
|
selectedLoco,
|
||||||
numberOfCars,
|
numberOfCars,
|
||||||
|
destinations: destinations,
|
||||||
out List<DropdownMenu.RowData> rowDatas,
|
out List<DropdownMenu.RowData> rowDatas,
|
||||||
out Action<int> func,
|
out Action<int> func,
|
||||||
out int origCount,
|
out int origCount,
|
||||||
@@ -81,10 +82,11 @@ internal class AutoEngineerWaypointControls_ConfigureOptionsDropdown_Patch
|
|||||||
out AutoEngineerOrdersHelper aeoh
|
out AutoEngineerOrdersHelper aeoh
|
||||||
);
|
);
|
||||||
|
|
||||||
List<(string destinationId, string destination, float? distance, float sortDistance, Location? location)> jumpTos = BuildJumpToOptions(__instance, selectedLoco);
|
List<(string destinationId, string destination, float? distance, float sortDistance, Location? location)> jumpTos =
|
||||||
|
BuildJumpToOptions((AutoEngineerWaypointControls)__instance.aiWaypointControls, selectedLoco);
|
||||||
|
|
||||||
__result = WireUpJumpTosToSettingMenu(
|
var config = WireUpJumpTosToSettingMenu(
|
||||||
__instance,
|
(AutoEngineerWaypointControls)__instance.aiWaypointControls,
|
||||||
selectedLoco,
|
selectedLoco,
|
||||||
rowDatas,
|
rowDatas,
|
||||||
func,
|
func,
|
||||||
@@ -93,23 +95,36 @@ internal class AutoEngineerWaypointControls_ConfigureOptionsDropdown_Patch
|
|||||||
aeoh,
|
aeoh,
|
||||||
ref jumpTos
|
ref jumpTos
|
||||||
);
|
);
|
||||||
} catch(Exception ex)
|
|
||||||
{
|
List<DropdownMenu.RowData> list = config.Rows;
|
||||||
_log.Error(ex, "I have a very unique set of skills; I will find you and I will squash you.");
|
Action<int> action = config.OnRowSelected;
|
||||||
|
|
||||||
|
__instance.optionsDropdown.Configure(list, action);
|
||||||
|
((Selectable)__instance.optionsDropdown).interactable = list.Count > 0;
|
||||||
|
yield return wait;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool ShouldRecalc(BaseLocomotive selectedLoco)
|
private static bool ShouldRecalc(LocomotiveControlsUIAdapter __instance, BaseLocomotive selectedLoco, out HashSet<OpsCarPosition?> destinations)
|
||||||
{
|
{
|
||||||
bool output = false;
|
bool output = false;
|
||||||
string locoKey = getDictKey(selectedLoco);
|
string locoKey = getDictKey(selectedLoco);
|
||||||
List<Car> consist = new List<Car>();
|
List<Car> consist = new List<Car>();
|
||||||
consist = selectedLoco.EnumerateCoupled().ToList();
|
consist = selectedLoco.EnumerateCoupled().ToList();
|
||||||
HashSet<OpsCarPosition?> destinations = consist.Where(c => GetCarDestinationIdentifier(c).HasValue).Select(GetCarDestinationIdentifier).ToHashSet();
|
destinations = consist.Where(c => GetCarDestinationIdentifier(c).HasValue).Select(GetCarDestinationIdentifier).ToHashSet();
|
||||||
|
|
||||||
output |= !locoConsistDestinations.Equals(destinations);
|
//_log.Information($"{locoKey} --> [{destinations.Count}] -> Seen -> {string.Join(Environment.NewLine, destinations.Select(k => k.Value.DisplayName))}");
|
||||||
output |= !(_keyChangeObservers?.Any() ?? false);
|
//_log.Information($"{locoKey} --> [{locoConsistDestinations.Count}] -> Cache -> {string.Join(Environment.NewLine, locoConsistDestinations.Select(k => $"{locoKey}:{k.Value.DisplayName}"))}");
|
||||||
|
|
||||||
|
output |= !locoConsistDestinations.SetEquals(destinations);
|
||||||
|
_log.Information($"{locoKey} 1-> {output}");
|
||||||
|
if (output) lastSeenIntegrationSetCount = default;
|
||||||
|
output |= lastSeenIntegrationSetCount != selectedLoco.set.NumberOfCars;
|
||||||
|
_log.Information($"{locoKey} 2-> {output}");
|
||||||
|
//output |= __instance.optionsDropdown.scrollRect.content.childCount != (destinations.Count + timetableDestinations.Count + 1); //+1 for the default "JumpTo" entry)
|
||||||
|
//_log.Information($"{locoKey} 2.5-> {output} {__instance.optionsDropdown.scrollRect.content.childCount} {(destinations.Count)} {timetableDestinations.Count}");
|
||||||
output |= selectedLoco.TryGetTimetableTrain(out _) && TimetableController.Shared.CurrentDocument.Modified != timetableSaveTime;
|
output |= selectedLoco.TryGetTimetableTrain(out _) && TimetableController.Shared.CurrentDocument.Modified != timetableSaveTime;
|
||||||
|
_log.Information($"{locoKey} 3-> {output}");
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
@@ -198,7 +213,8 @@ internal class AutoEngineerWaypointControls_ConfigureOptionsDropdown_Patch
|
|||||||
sortdistance = Graph.Shared.FindRoute(start, destLoc, autoEngineer, list, out metrics, checkForCars: false, 0f, trainMomentum)
|
sortdistance = Graph.Shared.FindRoute(start, destLoc, autoEngineer, list, out metrics, checkForCars: false, 0f, trainMomentum)
|
||||||
? metrics.Distance
|
? metrics.Distance
|
||||||
: float.MaxValue;
|
: float.MaxValue;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
_log.Debug($"{getDictKey(selectedLoco)} -> {destName} {destId} {distance?.ToString()}");
|
_log.Debug($"{getDictKey(selectedLoco)} -> {destName} {destId} {distance?.ToString()}");
|
||||||
jumpTos.Add((
|
jumpTos.Add((
|
||||||
destinationId: destId,
|
destinationId: destId,
|
||||||
@@ -244,7 +260,8 @@ internal class AutoEngineerWaypointControls_ConfigureOptionsDropdown_Patch
|
|||||||
sortdistance = Graph.Shared.FindRoute(start, destLoc, autoEngineer, list, out metrics, checkForCars: false, 0f, trainMomentum)
|
sortdistance = Graph.Shared.FindRoute(start, destLoc, autoEngineer, list, out metrics, checkForCars: false, 0f, trainMomentum)
|
||||||
? metrics.Distance
|
? metrics.Distance
|
||||||
: float.MaxValue;
|
: float.MaxValue;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
_log.Debug($"{getDictKey(selectedLoco)} -> {destName} {destId} {distance?.ToString()}");
|
_log.Debug($"{getDictKey(selectedLoco)} -> {destName} {destId} {distance?.ToString()}");
|
||||||
jumpTos.Add((
|
jumpTos.Add((
|
||||||
destinationId: destId,
|
destinationId: destId,
|
||||||
@@ -253,7 +270,8 @@ internal class AutoEngineerWaypointControls_ConfigureOptionsDropdown_Patch
|
|||||||
, sortdistance: sortdistance
|
, sortdistance: sortdistance
|
||||||
, location: (Location?)destLoc
|
, location: (Location?)destLoc
|
||||||
));
|
));
|
||||||
} catch (Exception ex)
|
}
|
||||||
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_log.Warning(ex, $"Timetable entry not added to AE gear cog options {stp}");
|
_log.Warning(ex, $"Timetable entry not added to AE gear cog options {stp}");
|
||||||
}
|
}
|
||||||
@@ -264,42 +282,33 @@ internal class AutoEngineerWaypointControls_ConfigureOptionsDropdown_Patch
|
|||||||
return jumpTos;
|
return jumpTos;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void IterateCarsDetectDestinations(AutoEngineerWaypointControls __instance, OptionsDropdownConfiguration __result, BaseLocomotive selectedLoco, int numberOfCars, out List<DropdownMenu.RowData> rowDatas, out Action<int> func, out int origCount, out int maxRowOrig, out AutoEngineerOrdersHelper aeoh)
|
private static void IterateCarsDetectDestinations(
|
||||||
|
AutoEngineerWaypointControls __instance,
|
||||||
|
OptionsDropdownConfiguration __result,
|
||||||
|
BaseLocomotive selectedLoco,
|
||||||
|
int numberOfCars,
|
||||||
|
HashSet<OpsCarPosition?> destinations,
|
||||||
|
out List<DropdownMenu.RowData> rowDatas,
|
||||||
|
out Action<int> func,
|
||||||
|
out int origCount,
|
||||||
|
out int maxRowOrig,
|
||||||
|
out AutoEngineerOrdersHelper aeoh
|
||||||
|
)
|
||||||
{
|
{
|
||||||
rowDatas = __result.Rows.ToList();
|
rowDatas = __result.Rows.ToList();
|
||||||
func = __result.OnRowSelected;
|
func = __result.OnRowSelected;
|
||||||
origCount = rowDatas.Count;
|
origCount = rowDatas.Count;
|
||||||
maxRowOrig = origCount - 1;
|
maxRowOrig = origCount - 1;
|
||||||
locoConsistDestinations = [];
|
|
||||||
HashSet<OpsCarPosition?> seen = [];
|
|
||||||
aeoh = new AutoEngineerOrdersHelper(persistence: new AutoEngineerPersistence(selectedLoco.KeyValueObject), locomotive: selectedLoco);
|
aeoh = new AutoEngineerOrdersHelper(persistence: new AutoEngineerPersistence(selectedLoco.KeyValueObject), locomotive: selectedLoco);
|
||||||
Car.LogicalEnd logicalEnd = ((selectedLoco.set.IndexOfCar(selectedLoco).GetValueOrDefault(0) >= numberOfCars / 2) ? Car.LogicalEnd.B : Car.LogicalEnd.A);
|
|
||||||
Car.LogicalEnd end = ((logicalEnd == Car.LogicalEnd.A) ? Car.LogicalEnd.B : Car.LogicalEnd.A);
|
|
||||||
bool stop = false;
|
|
||||||
int carIndex = selectedLoco.set.StartIndexForConnected(selectedLoco, logicalEnd, IntegrationSet.EnumerationCondition.Coupled);
|
|
||||||
Car car;
|
|
||||||
string locoKey = getDictKey(selectedLoco);
|
string locoKey = getDictKey(selectedLoco);
|
||||||
while (!stop && (car = selectedLoco.set.NextCarConnected(ref carIndex, logicalEnd, IntegrationSet.EnumerationCondition.Coupled, out stop)) != null)
|
|
||||||
{
|
|
||||||
AddObserversToCar(__instance, car);
|
|
||||||
var ocp = GetCarDestinationIdentifier(car);
|
|
||||||
_log.Debug($"{locoKey} --> {getDictKey(car)} -> {ocp.HasValue} {ocp?.DisplayName}");
|
|
||||||
|
|
||||||
if (ocp.HasValue)
|
|
||||||
{
|
|
||||||
seen.Add(ocp.Value);
|
|
||||||
locoConsistDestinations.Add(ocp.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var dropped =
|
var dropped =
|
||||||
locoConsistDestinations.Except(seen).ToHashSet(); //are no longer here
|
locoConsistDestinations.Except(destinations).ToHashSet(); //are no longer here
|
||||||
|
|
||||||
_log.Debug($"{locoKey} --> [{seen.Count}] -> Seen -> {string.Join(Environment.NewLine, seen.Select(k => k.Value.DisplayName))}");
|
_log.Debug($"{locoKey} --> [{destinations.Count}] -> Seen -> {string.Join(Environment.NewLine, destinations.Select(k => k.Value.DisplayName))}");
|
||||||
_log.Debug($"{locoKey} --> [{locoConsistDestinations.Count}] -> Cache -> {string.Join(Environment.NewLine, locoConsistDestinations.Select(k => $"{locoKey}:{k.Value.DisplayName}"))}");
|
_log.Debug($"{locoKey} --> [{locoConsistDestinations.Count}] -> Cache -> {string.Join(Environment.NewLine, locoConsistDestinations.Select(k => $"{locoKey}:{k.Value.DisplayName}"))}");
|
||||||
_log.Debug($"{locoKey} --> [{dropped.Count}] -> removed -> {string.Join(Environment.NewLine, dropped.Select(k => k.Value.DisplayName))}");
|
_log.Debug($"{locoKey} --> [{dropped.Count}] -> removed -> {string.Join(Environment.NewLine, dropped.Select(k => k.Value.DisplayName))}");
|
||||||
locoConsistDestinations = locoConsistDestinations.Intersect(seen).ToHashSet(); //remove ones that are no longer here
|
locoConsistDestinations = destinations.ToList().ToHashSet(); //remove ones that are no longer here
|
||||||
seen.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void PrepLocoUsage(AutoEngineerWaypointControls __instance, out BaseLocomotive selectedLoco, out int numberOfCars)
|
private static void PrepLocoUsage(AutoEngineerWaypointControls __instance, out BaseLocomotive selectedLoco, out int numberOfCars)
|
||||||
@@ -307,9 +316,7 @@ internal class AutoEngineerWaypointControls_ConfigureOptionsDropdown_Patch
|
|||||||
//wire up that loco
|
//wire up that loco
|
||||||
selectedLoco = __instance.Locomotive;
|
selectedLoco = __instance.Locomotive;
|
||||||
numberOfCars = selectedLoco.set.NumberOfCars;
|
numberOfCars = selectedLoco.set.NumberOfCars;
|
||||||
_log.Debug($"{getDictKey(selectedLoco)} --> HI BOB[{numberOfCars}]");
|
_log.Debug($"{selectedLoco.id} --> HI BOB[{numberOfCars}]");
|
||||||
foreach (var o in _keyChangeObservers) o.Dispose();
|
|
||||||
_keyChangeObservers.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OpsCarPosition? GetCarDestinationIdentifier(Car c)
|
private static OpsCarPosition? GetCarDestinationIdentifier(Car c)
|
||||||
@@ -323,7 +330,8 @@ internal class AutoEngineerWaypointControls_ConfigureOptionsDropdown_Patch
|
|||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Location RouteStartLocation(AutoEngineerWaypointControls __instance, BaseLocomotive _locomotive) {
|
private static Location RouteStartLocation(AutoEngineerWaypointControls __instance, BaseLocomotive _locomotive)
|
||||||
|
{
|
||||||
bool num = _locomotive.IsStopped();
|
bool num = _locomotive.IsStopped();
|
||||||
bool? flag = (num ? null : new bool?(_locomotive.velocity >= 0f));
|
bool? flag = (num ? null : new bool?(_locomotive.velocity >= 0f));
|
||||||
|
|
||||||
@@ -347,75 +355,15 @@ internal class AutoEngineerWaypointControls_ConfigureOptionsDropdown_Patch
|
|||||||
|
|
||||||
return num + 1.04f * (float)(coupledCarsCached.Count - 1);
|
return num + 1.04f * (float)(coupledCarsCached.Count - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddObserversToCar(AutoEngineerWaypointControls __instance, Car c)
|
|
||||||
{
|
|
||||||
AddObserver(__instance, c, Car.KeyOpsWaybill);
|
|
||||||
AddObserver(__instance, c, Car.KeyOpsRepairDestination);
|
|
||||||
AddObserver(__instance, c, nameof(Car.trainCrewId));
|
|
||||||
foreach (Car.LogicalEnd logicalEnd in CarInspector_PopulateCarPanel_Patch.ends)
|
|
||||||
{
|
|
||||||
AddObserver(__instance, c, Car.KeyValueKeyFor(Car.EndGearStateKey.IsCoupled, c.LogicalToEnd(logicalEnd)), true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddObserver(AutoEngineerWaypointControls __instance, Model.Car car, string key, bool clearCarCache = false)
|
[HarmonyPatch(typeof(LocomotiveControlsUIAdapter))]
|
||||||
|
[HarmonyPatch(nameof(LocomotiveControlsUIAdapter.UpdateOptionsDropdown))]
|
||||||
|
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
|
||||||
|
internal class LocomotiveControlsUIAdapter_UpdateOptionsDropdown_Prefix
|
||||||
{
|
{
|
||||||
_keyChangeObservers.Add(
|
static bool Prefix(LocomotiveControlsUIAdapter __instance)
|
||||||
car.KeyValueObject.Observe(
|
|
||||||
key,
|
|
||||||
delegate (Value value)
|
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
_log.Debug($"{getDictKey(car)} OBSV {key}: {value}");
|
|
||||||
|
|
||||||
if (!(locoConsistDestinations?.Any() ?? false)) return;
|
|
||||||
|
|
||||||
bool waybillChng = (new[] { Car.KeyOpsWaybill, Car.KeyOpsRepairDestination }).Contains(key);
|
|
||||||
string? destId =
|
|
||||||
waybillChng ?
|
|
||||||
GetCarDestinationIdentifier(car)?.Identifier ?? null :
|
|
||||||
null;
|
|
||||||
if (waybillChng)
|
|
||||||
{
|
|
||||||
if (locoConsistDestinations.Contains(GetCarDestinationIdentifier(car)))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_log.Debug($"{getDictKey(car)} OBSV {key}: destNew; {destId}; reload");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_log.Debug($"{getDictKey(car)} OBSV {key}: {value}");
|
|
||||||
}
|
|
||||||
|
|
||||||
Rebuild(__instance, car, key);
|
|
||||||
},
|
|
||||||
false
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Rebuild(AutoEngineerWaypointControls __instance, Car car, string key)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (var o in _keyChangeObservers)
|
|
||||||
{
|
|
||||||
o.Dispose();
|
|
||||||
}
|
|
||||||
var loco = __instance.Locomotive;
|
|
||||||
if (!TrainController.Shared.SelectRecall()) TrainController.Shared.SelectedCar = null;
|
|
||||||
_keyChangeObservers.Clear();
|
|
||||||
locoConsistDestinations = [];
|
|
||||||
TrainController.Shared.SelectedCar = loco;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_log.ForContext("car", car).Warning(ex, $"{nameof(AddObserver)} {car} Exception logged for {key}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ public class TweaksAndThingsPlugin : SingletonPluginBase<TweaksAndThingsPlugin>,
|
|||||||
|
|
||||||
static TweaksAndThingsPlugin()
|
static TweaksAndThingsPlugin()
|
||||||
{
|
{
|
||||||
Log.Debug("Hello! Static Constructor was called!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TweaksAndThingsPlugin(IModdingContext moddingContext, IModDefinition self)
|
public TweaksAndThingsPlugin(IModdingContext moddingContext, IModDefinition self)
|
||||||
@@ -58,7 +57,6 @@ public class TweaksAndThingsPlugin : SingletonPluginBase<TweaksAndThingsPlugin>,
|
|||||||
|
|
||||||
public override void OnEnable()
|
public override void OnEnable()
|
||||||
{
|
{
|
||||||
logger.Debug("OnEnable() was called!");
|
|
||||||
var harmony = new Harmony(modDefinition.Id);
|
var harmony = new Harmony(modDefinition.Id);
|
||||||
harmony.PatchCategory(modDefinition.Id.Replace(".", string.Empty));
|
harmony.PatchCategory(modDefinition.Id.Replace(".", string.Empty));
|
||||||
}
|
}
|
||||||
@@ -72,13 +70,10 @@ public class TweaksAndThingsPlugin : SingletonPluginBase<TweaksAndThingsPlugin>,
|
|||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
logger.Verbose("UPDATE()");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModTabDidOpen(UIPanelBuilder builder)
|
public void ModTabDidOpen(UIPanelBuilder builder)
|
||||||
{
|
{
|
||||||
logger.Debug("Daytime!");
|
|
||||||
|
|
||||||
if (settings == null) settings = new();
|
if (settings == null) settings = new();
|
||||||
if (!settings?.WebhookSettingsList?.Any() ?? true) settings.WebhookSettingsList = new[] { new WebhookSettings() }.ToList();
|
if (!settings?.WebhookSettingsList?.Any() ?? true) settings.WebhookSettingsList = new[] { new WebhookSettings() }.ToList();
|
||||||
if (settings?.EngineRosterFuelColumnSettings == null) settings.EngineRosterFuelColumnSettings = new();
|
if (settings?.EngineRosterFuelColumnSettings == null) settings.EngineRosterFuelColumnSettings = new();
|
||||||
@@ -347,7 +342,6 @@ AutoHotboxSpotter Update: decrease the random wait from 30 - 300 seconds to 15 -
|
|||||||
|
|
||||||
public void ModTabDidClose()
|
public void ModTabDidClose()
|
||||||
{
|
{
|
||||||
logger.Debug("Nighttime...");
|
|
||||||
this.moddingContext.SaveSettingsData(this.modDefinition.Id, settings ?? new());
|
this.moddingContext.SaveSettingsData(this.modDefinition.Id, settings ?? new());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user