mirror of
https://github.com/rmroc451/TweaksAndThings.git
synced 2025-12-17 01:39:38 -06:00
Compare commits
12 Commits
7-finance-
...
v1.2.6
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f2e3dee80 | |||
| ed44ea829e | |||
| bce1d8bd58 | |||
| c25271ee2d | |||
| 80f0847587 | |||
| 7552422b6e | |||
| 58dc7efac0 | |||
| 7ebd14db2a | |||
| ca0e78b971 | |||
| 9f210b0b8a | |||
| 840f35cf62 | |||
| 786db49b68 |
7
Assembly.version
Normal file
7
Assembly.version
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<MajorVersion>1</MajorVersion>
|
||||||
|
<MinorVersion>2</MinorVersion>
|
||||||
|
<PatchVersion>6</PatchVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<Import Project="Paths.user" Condition="Exists('Paths.user')" />
|
<Import Project="Paths.user" Condition="Exists('Paths.user')" />
|
||||||
|
<Import Project="Assembly.version" Condition="Exists('Assembly.version')" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net48</TargetFramework>
|
<TargetFramework>net48</TargetFramework>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
<!-- Replace the default version if something was set for it -->
|
<!-- Replace the default version if something was set for it -->
|
||||||
<PropertyGroup Condition="'$(AssemblyVersion)' == '' OR '$(MajorVersion)' != '' OR '$(MinorVersion)' != ''">
|
<PropertyGroup Condition="'$(AssemblyVersion)' == '' OR '$(MajorVersion)' != '' OR '$(MinorVersion)' != ''">
|
||||||
<MajorVersion Condition="'$(MajorVersion)' == ''">1</MajorVersion>
|
<MajorVersion Condition="'$(MajorVersion)' == ''">1</MajorVersion>
|
||||||
<MinorVersion Condition="'$(MinorVersion)' == ''">0</MinorVersion>
|
<MinorVersion Condition="'$(MinorVersion)' == ''">1</MinorVersion>
|
||||||
<PatchVersion Condition="'$(PatchVersion)' == ''">0</PatchVersion>
|
<PatchVersion Condition="'$(PatchVersion)' == ''">1</PatchVersion>
|
||||||
<AssemblyVersion>$(MajorVersion).$(MinorVersion).$(PatchVersion)</AssemblyVersion>
|
<AssemblyVersion>$(MajorVersion).$(MinorVersion).$(PatchVersion)</AssemblyVersion>
|
||||||
<FileVersion>$(AssemblyVersion)</FileVersion>
|
<FileVersion>$(AssemblyVersion)</FileVersion>
|
||||||
<ProductVersion>$(AssemblyVersion)</ProductVersion>
|
<ProductVersion>$(AssemblyVersion)</ProductVersion>
|
||||||
|
|||||||
6
Paths.user.example
Normal file
6
Paths.user.example
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<!-- Directory that the game (Railroader.exe) is in -->
|
||||||
|
<GameDir></GameDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -6,6 +6,7 @@ MinimumVisualStudioVersion = 10.0.40219.1
|
|||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{452A23A6-81C8-49C6-A7EE-95FD9377F896}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{452A23A6-81C8-49C6-A7EE-95FD9377F896}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.gitignore = .gitignore
|
.gitignore = .gitignore
|
||||||
|
Assembly.version = Assembly.version
|
||||||
Directory.Build.props = Directory.Build.props
|
Directory.Build.props = Directory.Build.props
|
||||||
Directory.Build.targets = Directory.Build.targets
|
Directory.Build.targets = Directory.Build.targets
|
||||||
Paths.user = Paths.user
|
Paths.user = Paths.user
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Game.State;
|
using Game.State;
|
||||||
using Helpers;
|
using Helpers;
|
||||||
using Model.OpsNew;
|
using Model.Ops;
|
||||||
using Network;
|
using Network;
|
||||||
using RMROC451.TweaksAndThings.Extensions;
|
using RMROC451.TweaksAndThings.Extensions;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|||||||
@@ -5,10 +5,17 @@
|
|||||||
"version": "$(AssemblyVersion)",
|
"version": "$(AssemblyVersion)",
|
||||||
"requires": [
|
"requires": [
|
||||||
{
|
{
|
||||||
"id": "railloader",
|
"id": "railroader",
|
||||||
"notBefore": "1.8.1"
|
"notBefore": "2024.6"
|
||||||
},
|
},
|
||||||
"Zamu.StrangeCustoms"
|
{
|
||||||
|
"id": "railloader",
|
||||||
|
"notBefore": "1.9.6.14"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Zamu.StrangeCustoms",
|
||||||
|
"notBefore": "1.10.25017.313"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"assemblies": [ "RMROC451.TweaksAndThings" ],
|
"assemblies": [ "RMROC451.TweaksAndThings" ],
|
||||||
"mixintos": {
|
"mixintos": {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using Game.State;
|
|||||||
using Helpers;
|
using Helpers;
|
||||||
using Model;
|
using Model;
|
||||||
using Model.Definition.Data;
|
using Model.Definition.Data;
|
||||||
using Model.OpsNew;
|
using Model.Ops;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -109,8 +109,7 @@ public static class Car_Extensions
|
|||||||
{
|
{
|
||||||
Vector3 position = car.GetMotionSnapshot().Position;
|
Vector3 position = car.GetMotionSnapshot().Position;
|
||||||
Vector3 center = WorldTransformer.WorldToGame(position);
|
Vector3 center = WorldTransformer.WorldToGame(position);
|
||||||
Rect rect = new Rect(new Vector2(center.x - 30f, center.z - 30f), Vector2.one * 30f * 2f);
|
var cars = tc.CarIdsInRadius(center, 60f);
|
||||||
var cars = tc.CarIdsInRect(rect);
|
|
||||||
Log.Information($"{nameof(HuntingForCabeeseNearCar)} => {cars.Count()}");
|
Log.Information($"{nameof(HuntingForCabeeseNearCar)} => {cars.Count()}");
|
||||||
List<(string carId, float distance)> source =
|
List<(string carId, float distance)> source =
|
||||||
cars
|
cars
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ internal class CarInspector_PopulateCarPanel_Patch
|
|||||||
bool buttonsHaveCost = tweaksAndThings.EndGearHelpersRequirePayment();
|
bool buttonsHaveCost = tweaksAndThings.EndGearHelpersRequirePayment();
|
||||||
|
|
||||||
var consist = __instance._car.EnumerateCoupled();
|
var consist = __instance._car.EnumerateCoupled();
|
||||||
builder = AddCarConsistRebuildObservers(builder, consist);
|
|
||||||
|
|
||||||
builder.HStack(delegate (UIPanelBuilder hstack)
|
builder.HStack(delegate (UIPanelBuilder hstack)
|
||||||
{
|
{
|
||||||
|
hstack = AddCarConsistRebuildObservers(hstack, consist);
|
||||||
var buttonName = $"{(consist.Any(c => c.HandbrakeApplied()) ? "Release " : "Set ")} {TextSprites.HandbrakeWheel}";
|
var buttonName = $"{(consist.Any(c => c.HandbrakeApplied()) ? "Release " : "Set ")} {TextSprites.HandbrakeWheel}";
|
||||||
hstack.AddButtonCompact(buttonName, delegate
|
hstack.AddButtonCompact(buttonName, delegate
|
||||||
{
|
{
|
||||||
@@ -122,7 +122,7 @@ internal class CarInspector_PopulateCarPanel_Patch
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
builder.RebuildOnInterval(.01f);
|
builder.Rebuild();
|
||||||
if (car.TagCallout != null) tagController.UpdateTags(CameraSelector.shared._currentCamera.GroundPosition, true);
|
if (car.TagCallout != null) tagController.UpdateTags(CameraSelector.shared._currentCamera.GroundPosition, true);
|
||||||
if (ContextMenu.IsShown && ContextMenu.Shared.centerLabel.text == car.DisplayName) CarPickable.HandleShowContextMenu(car);
|
if (ContextMenu.IsShown && ContextMenu.Shared.centerLabel.text == car.DisplayName) CarPickable.HandleShowContextMenu(car);
|
||||||
}
|
}
|
||||||
@@ -208,7 +208,7 @@ internal class CarInspector_PopulateCarPanel_Patch
|
|||||||
float originalTimeCost = consist.CalculateCostForAutoEngineerEndGearSetting();
|
float originalTimeCost = consist.CalculateCostForAutoEngineerEndGearSetting();
|
||||||
float timeCost = originalTimeCost;
|
float timeCost = originalTimeCost;
|
||||||
float crewCost = timeCost / 3600; //hours of time deducted from caboose.
|
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);
|
Car? cabooseWithAvailCrew = NearbyCabooseWithAvailableCrew(car, crewCost, buttonsHaveCost);
|
||||||
if (cabooseWithAvailCrew == null) timeCost *= 1.5f;
|
if (cabooseWithAvailCrew == null) timeCost *= 1.5f;
|
||||||
var cabooseFoundDisplay = cabooseWithAvailCrew?.DisplayName ?? "No caboose";
|
var cabooseFoundDisplay = cabooseWithAvailCrew?.DisplayName ?? "No caboose";
|
||||||
|
|||||||
@@ -22,20 +22,20 @@ internal class CarPickable_HandleShowContextMenu_Patch
|
|||||||
|
|
||||||
bool buttonsHaveCost = tweaksAndThings.EndGearHelpersRequirePayment();
|
bool buttonsHaveCost = tweaksAndThings.EndGearHelpersRequirePayment();
|
||||||
ContextMenu shared = ContextMenu.Shared;
|
ContextMenu shared = ContextMenu.Shared;
|
||||||
shared.AddButton(ContextMenuQuadrant.Unused2, $"{(car.EnumerateCoupled().Any(c => c.HandbrakeApplied()) ? "Release " : "Set ")} Consist", SpriteName.Handbrake, delegate
|
shared.AddButton(ContextMenuQuadrant.Unused1, $"{(car.EnumerateCoupled().Any(c => c.HandbrakeApplied()) ? "Release " : "Set ")} Consist", SpriteName.Handbrake, delegate
|
||||||
{
|
{
|
||||||
CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.Handbrake, buttonsHaveCost);
|
CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.Handbrake, buttonsHaveCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (car.EnumerateCoupled().Any(c => c.EndAirSystemIssue()))
|
if (car.EnumerateCoupled().Any(c => c.EndAirSystemIssue()))
|
||||||
{
|
{
|
||||||
shared.AddButton(ContextMenuQuadrant.Unused2, $"Air Up Consist", SpriteName.Select, delegate
|
shared.AddButton(ContextMenuQuadrant.Unused1, $"Air Up Consist", SpriteName.Select, delegate
|
||||||
{
|
{
|
||||||
CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.GladhandAndAnglecock, buttonsHaveCost);
|
CarInspector_PopulateCarPanel_Patch.MrocConsistHelper(car, MrocHelperType.GladhandAndAnglecock, buttonsHaveCost);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (car.EnumerateCoupled().Any(c => c.SupportsBleed()))
|
if (!car.EnumerateCoupled().Any(c => !c.SupportsBleed()))
|
||||||
{
|
{
|
||||||
shared.AddButton(ContextMenuQuadrant.Unused2, $"Bleed Consist", SpriteName.Bleed, delegate
|
shared.AddButton(ContextMenuQuadrant.Unused2, $"Bleed Consist", SpriteName.Bleed, delegate
|
||||||
{
|
{
|
||||||
@@ -43,11 +43,10 @@ internal class CarPickable_HandleShowContextMenu_Patch
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
shared.AddButton(ContextMenuQuadrant.Unused2, $"Follow", SpriteName.Inspect, delegate
|
shared.AddButton(ContextMenuQuadrant.General, $"Follow", SpriteName.Inspect, delegate
|
||||||
{
|
{
|
||||||
CameraSelector.shared.FollowCar(car);
|
CameraSelector.shared.FollowCar(car);
|
||||||
});
|
});
|
||||||
|
|
||||||
shared.BuildItemAngles();
|
shared.BuildItemAngles();
|
||||||
shared.StartCoroutine(shared.AnimateButtonsShown());
|
shared.StartCoroutine(shared.AnimateButtonsShown());
|
||||||
}
|
}
|
||||||
|
|||||||
25
TweaksAndThings/Patches/ContextMenu_PositionForItem_Patch.cs
Normal file
25
TweaksAndThings/Patches/ContextMenu_PositionForItem_Patch.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using Railloader;
|
||||||
|
using System;
|
||||||
|
using UI.ContextMenu;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
||||||
|
namespace RMROC451.TweaksAndThings.Patches;
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(UI.ContextMenu.ContextMenu))]
|
||||||
|
//ContextMenuQuadrant quadrant, int index, float normalizedRadius = 1f
|
||||||
|
[HarmonyPatch(nameof(UI.ContextMenu.ContextMenu.PositionForItem), typeof(ContextMenuQuadrant), typeof(int), typeof(float))]
|
||||||
|
[HarmonyPatchCategory("RMROC451TweaksAndThings")]
|
||||||
|
internal class ContextMenu_PositionForItem_Patch
|
||||||
|
{
|
||||||
|
static void Postfix(UI.ContextMenu.ContextMenu __instance, ref Vector2 __result, ContextMenuQuadrant quadrant, int index, float normalizedRadius = 1f)
|
||||||
|
{
|
||||||
|
TweaksAndThingsPlugin tweaksAndThings = SingletonPluginBase<TweaksAndThingsPlugin>.Shared;
|
||||||
|
if (!tweaksAndThings.IsEnabled) return;
|
||||||
|
|
||||||
|
float num = __instance._itemAngles[(quadrant, index)] * ((float)Math.PI / 180f);
|
||||||
|
float num2 = __instance.radius * normalizedRadius;
|
||||||
|
__result = new Vector2(1.3f * Mathf.Sin(num) * num2, Mathf.Cos(num) * num2);
|
||||||
|
}
|
||||||
|
}
|
||||||
128
TweaksAndThings/Patches/ContextMenu_Show_Patch.cs
Normal file
128
TweaksAndThings/Patches/ContextMenu_Show_Patch.cs
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using Model;
|
using Model;
|
||||||
using Model.Definition.Data;
|
using Model.Definition.Data;
|
||||||
using Model.OpsNew;
|
using Model.Ops;
|
||||||
using Railloader;
|
using Railloader;
|
||||||
using RMROC451.TweaksAndThings.Extensions;
|
using RMROC451.TweaksAndThings.Extensions;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|||||||
@@ -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,140 @@
|
|||||||
|
using Game;
|
||||||
|
using Game.State;
|
||||||
|
using HarmonyLib;
|
||||||
|
using Model;
|
||||||
|
using Model.Definition.Data;
|
||||||
|
using Model.Ops.Definition;
|
||||||
|
using Model.Ops;
|
||||||
|
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 = new();
|
||||||
|
|
||||||
|
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 =
|
||||||
|
new List<Type>() {
|
||||||
|
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) ?? Enumerable.Empty<Car>()).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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using Model;
|
using Model;
|
||||||
using Model.OpsNew;
|
using Model.Ops;
|
||||||
using Railloader;
|
using Railloader;
|
||||||
using RMROC451.TweaksAndThings.Extensions;
|
using RMROC451.TweaksAndThings.Extensions;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -34,8 +34,9 @@ internal class TagController_UpdateTag_Patch
|
|||||||
private static void ProceedWithPostFix(Car car, TagCallout tagCallout)
|
private static void ProceedWithPostFix(Car car, TagCallout tagCallout)
|
||||||
{
|
{
|
||||||
tagCallout.callout.Title = string.Format(tagTitleFormat, "{0}", car.DisplayName);
|
tagCallout.callout.Title = string.Format(tagTitleFormat, "{0}", car.DisplayName);
|
||||||
List<string> tags = [];
|
List<string> tags = new();
|
||||||
|
|
||||||
|
if (OpsController_AnnounceCoalescedPayments_Patch.CrewCarStatus(car).spotted) tags.Add("+");
|
||||||
if (car.HasHotbox) tags.Add(TextSprites.Hotbox);
|
if (car.HasHotbox) tags.Add(TextSprites.Hotbox);
|
||||||
if (car.EndAirSystemIssue()) tags.Add(TextSprites.CycleWaybills);
|
if (car.EndAirSystemIssue()) tags.Add(TextSprites.CycleWaybills);
|
||||||
if (car.HandbrakeApplied()) tags.Add(TextSprites.HandbrakeWheel);
|
if (car.HandbrakeApplied()) tags.Add(TextSprites.HandbrakeWheel);
|
||||||
|
|||||||
20
TweaksAndThings/Patches/WedgeImage_OnPopulateMesh.cs
Normal file
20
TweaksAndThings/Patches/WedgeImage_OnPopulateMesh.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
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.
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user