From a53bcc246eeae4896d523d06789a9f07895e58e3 Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Mon, 24 Feb 2025 00:06:04 +0100 Subject: [PATCH] Refactor the fuck out of ModuleShieldGeneratorManager with generic multiplier handling --- .../TerraTech/ModuleShieldGeneratorManager.cs | 171 ++++++++++-------- 1 file changed, 92 insertions(+), 79 deletions(-) diff --git a/Projects/TerraTech/TerraTech/ModuleShieldGeneratorManager.cs b/Projects/TerraTech/TerraTech/ModuleShieldGeneratorManager.cs index 090dd97..8e928d1 100644 --- a/Projects/TerraTech/TerraTech/ModuleShieldGeneratorManager.cs +++ b/Projects/TerraTech/TerraTech/ModuleShieldGeneratorManager.cs @@ -1,116 +1,129 @@ using System; using System.Collections.Generic; +using BepInEx.Configuration; using HarmonyLib; namespace TerraTech { [HarmonyPatch] public class ModuleShieldGeneratorManager { - private static Dictionary healingHeartbeatInterval = - new Dictionary(); - private static Dictionary radius = new Dictionary(); - private static Dictionary powerUpDelay = - new Dictionary(); + private class MultipliedField { + private readonly string fieldName; + private readonly ConfigEntry multiplier; + private readonly Traverse parentTraverse; + private TValue originalValue; + + public MultipliedField(string fieldName, ConfigEntry multiplier, Traverse parentTraverse) { + this.fieldName = fieldName; + this.multiplier = multiplier; + this.parentTraverse = parentTraverse; + } + + public TValue GetValue() { + return (TValue)parentTraverse.Field(fieldName).GetValue(); + } + + public void SetValue(TValue value) { + parentTraverse.Field(fieldName).SetValue(value); + } + + public void CaptureOriginal() { + originalValue = GetValue(); + } + + public void Apply() { + // This assumes TValue implements multiplication with multiplier.Value + // For float, this would be originalValue * multiplier.Value + dynamic originalDynamic = originalValue; + dynamic multiplierDynamic = multiplier.Value; + SetValue((TValue)(originalDynamic * multiplierDynamic)); + } + + public void Restore() { + SetValue(originalValue); + } + + public void LogValue(string prefix) { + if (!Main.debug.Value) + return; + Console.WriteLine("{0} {1}; {2}: {3}", prefix, parentTraverse.ToString(), fieldName, GetValue()); + } + } + + private class MultipliedObject { + private readonly Traverse objectTraverse; + private readonly List> fields = new List>(); + + public MultipliedObject(T instance) objectTraverse = Traverse.Create(instance); + public void AddField(string fieldName, ConfigEntry multiplier) fields.Add( + new MultipliedField(fieldName, multiplier, objectTraverse)); + public void CaptureFrom() foreach (var field in fields) field.CaptureOriginal(); + public void ApplyTo() foreach (var field in fields) field.Apply(); + public void RestoreTo() foreach (var field in fields) field.Restore(); + + public void LogValues(string prefix) { + if (!Main.debug.Value) + return; + foreach (var field in fields) field.LogValue(prefix); + } + } + + private static Dictionary> originalProperties = + new Dictionary>(); [HarmonyPrefix] [HarmonyPatch(typeof(ModuleShieldGenerator), "OnAttached")] static void PostfixCreate(ModuleShieldGenerator __instance) { - var trav = Traverse.Create(__instance); - var powerUpDelayField = trav.Field("m_PowerUpDelay"); - if (Main.debug.Value) Console.WriteLine("ModuleShieldGenerator.OnAttached"); - if (!healingHeartbeatInterval.ContainsKey(__instance)) { - healingHeartbeatInterval.Add(__instance, __instance.m_HealingHeartbeatInterval); - if (Main.debug.Value) - Console.WriteLine("Patching {0}; m_HealingHeartbeatInterval: {1}", __instance.ToString(), - __instance.m_HealingHeartbeatInterval); - } - if (!radius.ContainsKey(__instance)) { - radius.Add(__instance, __instance.m_Radius); - if (Main.debug.Value) - Console.WriteLine("Patching {0}; m_Radius: {1}", __instance.ToString(), __instance.m_Radius); - } - if (!powerUpDelay.ContainsKey(__instance)) { - powerUpDelay.Add(__instance, (float)powerUpDelayField.GetValue()); - if (Main.debug.Value) - Console.WriteLine("Patching {0}; m_PowerUpDelay: {1}", __instance.ToString(), - (float)powerUpDelayField.GetValue()); + + if (!originalProperties.ContainsKey(__instance)) { + var props = new MultipliedObject(__instance); + props.AddField("m_HealingHeartbeatInterval", Main.shieldHeartbeatIntervalMultiplier); + props.AddField("m_Radius", Main.shieldRadiusMultiplier); + props.AddField("m_PowerUpDelay", Main.powerUpDelayMultiplier); + + props.CaptureFrom(); + originalProperties.Add(__instance, props); + props.LogValues("Patching"); } DoPatchSingle(__instance); - if (Main.debug.Value) - Console.WriteLine("Patched {0}; m_HealingHeartbeatInterval: {1}", __instance.ToString(), - __instance.m_HealingHeartbeatInterval); - if (Main.debug.Value) - Console.WriteLine("Patched {0}; m_Radius: {1}", __instance.ToString(), __instance.m_Radius); - if (Main.debug.Value) - Console.WriteLine("Patched {0}; m_PowerUpDelay: {1}", __instance.ToString(), - (float)powerUpDelayField.GetValue()); + if (Main.debug.Value) { + originalProperties[__instance].LogValues("Patched"); + } } [HarmonyPrefix] [HarmonyPatch(typeof(ModuleShieldGenerator), "OnDetaching")] static void PostfixDestroy(ModuleShieldGenerator __instance) { - var trav = Traverse.Create(__instance); - var powerUpDelayField = trav.Field("m_PowerUpDelay"); - - if (Main.debug.Value) + if (Main.debug.Value) { Console.WriteLine("ModuleShieldGenerator.OnDetaching"); - if (Main.debug.Value) - Console.WriteLine("Restoring {0}; m_HealingHeartbeatInterval: {1}", __instance.ToString(), - __instance.m_HealingHeartbeatInterval); - if (Main.debug.Value) - Console.WriteLine("Restoring {0}; m_Radius: {1}", __instance.ToString(), __instance.m_Radius); - if (Main.debug.Value) - Console.WriteLine("Restoring {0}; m_PowerUpDelay: {1}", __instance.ToString(), - (float)powerUpDelayField.GetValue()); + originalProperties[__instance].LogValues("Restoring"); + } DoRestoreSingle(__instance); - if (Main.debug.Value) - Console.WriteLine("Restored {0}; m_HealingHeartbeatInterval: {1}", __instance.ToString(), - __instance.m_HealingHeartbeatInterval); - if (Main.debug.Value) - Console.WriteLine("Restored {0}; m_Radius: {1}", __instance.ToString(), __instance.m_Radius); - if (Main.debug.Value) - Console.WriteLine("Restored {0}; m_PowerUpDelay: {1}", __instance.ToString(), - (float)powerUpDelayField.GetValue()); + if (Main.debug.Value) { + originalProperties[__instance].LogValues("Restored"); + } - healingHeartbeatInterval.Remove(__instance); - radius.Remove(__instance); - powerUpDelay.Remove(__instance); + originalProperties.Remove(__instance); } public static void DoPatch() { if (Main.debug.Value) - Console.WriteLine("Modifying {0} ModuleShieldGenerator", healingHeartbeatInterval.Count); - foreach (KeyValuePair keyValuePair in healingHeartbeatInterval) { - DoRestoreSingle(keyValuePair.Key); - DoPatchSingle(keyValuePair.Key); + Console.WriteLine("Modifying {0} ModuleShieldGenerator", originalProperties.Count); + foreach (var kvp in originalProperties) { + DoRestoreSingle(kvp.Key); + DoPatchSingle(kvp.Key); } } - static void DoPatchSingle(ModuleShieldGenerator moduleShieldGenerator) { - var trav = Traverse.Create(moduleShieldGenerator); - var powerUpDelayField = trav.Field("m_PowerUpDelay"); + static void DoPatchSingle(ModuleShieldGenerator moduleShieldGenerator) if ( + originalProperties.TryGetValue(moduleShieldGenerator, out var props)) props.ApplyTo(); - moduleShieldGenerator.m_HealingHeartbeatInterval = - healingHeartbeatInterval[moduleShieldGenerator] * Main.shieldHeartbeatIntervalMultiplier.Value; - moduleShieldGenerator.m_Radius = radius[moduleShieldGenerator] * Main.shieldRadiusMultiplier.Value; - powerUpDelayField.SetValue(powerUpDelay[moduleShieldGenerator] * Main.powerUpDelayMultiplier.Value); - } - - static void DoRestoreSingle(ModuleShieldGenerator moduleShieldGenerator) { - var trav = Traverse.Create(moduleShieldGenerator); - var powerUpDelayField = trav.Field("m_PowerUpDelay"); - - if (healingHeartbeatInterval.ContainsKey(moduleShieldGenerator)) - moduleShieldGenerator.m_HealingHeartbeatInterval = healingHeartbeatInterval[moduleShieldGenerator]; - if (radius.ContainsKey(moduleShieldGenerator)) - moduleShieldGenerator.m_Radius = radius[moduleShieldGenerator]; - if (powerUpDelay.ContainsKey(moduleShieldGenerator)) - powerUpDelayField.SetValue(powerUpDelay[moduleShieldGenerator]); - } + static void DoRestoreSingle(ModuleShieldGenerator moduleShieldGenerator) if ( + originalProperties.TryGetValue(moduleShieldGenerator, out var props)) props.RestoreTo(); } }