Refactor the fuck out of ModuleShieldGeneratorManager with generic multiplier handling
This commit is contained in:
@@ -1,116 +1,129 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using BepInEx.Configuration;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
|
||||||
namespace TerraTech {
|
namespace TerraTech {
|
||||||
[HarmonyPatch]
|
[HarmonyPatch]
|
||||||
public class ModuleShieldGeneratorManager {
|
public class ModuleShieldGeneratorManager {
|
||||||
private static Dictionary<ModuleShieldGenerator, float> healingHeartbeatInterval =
|
private class MultipliedField<TObject, TValue> {
|
||||||
new Dictionary<ModuleShieldGenerator, float>();
|
private readonly string fieldName;
|
||||||
private static Dictionary<ModuleShieldGenerator, float> radius = new Dictionary<ModuleShieldGenerator, float>();
|
private readonly ConfigEntry<TValue> multiplier;
|
||||||
private static Dictionary<ModuleShieldGenerator, float> powerUpDelay =
|
private readonly Traverse parentTraverse;
|
||||||
new Dictionary<ModuleShieldGenerator, float>();
|
private TValue originalValue;
|
||||||
|
|
||||||
|
public MultipliedField(string fieldName, ConfigEntry<TValue> 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<T> {
|
||||||
|
private readonly Traverse objectTraverse;
|
||||||
|
private readonly List<MultipliedField<T, float>> fields = new List<MultipliedField<T, float>>();
|
||||||
|
|
||||||
|
public MultipliedObject(T instance) objectTraverse = Traverse.Create(instance);
|
||||||
|
public void AddField(string fieldName, ConfigEntry<float> multiplier) fields.Add(
|
||||||
|
new MultipliedField<T, float>(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<ModuleShieldGenerator, MultipliedObject<ModuleShieldGenerator>> originalProperties =
|
||||||
|
new Dictionary<ModuleShieldGenerator, MultipliedObject<ModuleShieldGenerator>>();
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(ModuleShieldGenerator), "OnAttached")]
|
[HarmonyPatch(typeof(ModuleShieldGenerator), "OnAttached")]
|
||||||
static void PostfixCreate(ModuleShieldGenerator __instance) {
|
static void PostfixCreate(ModuleShieldGenerator __instance) {
|
||||||
var trav = Traverse.Create(__instance);
|
|
||||||
var powerUpDelayField = trav.Field("m_PowerUpDelay");
|
|
||||||
|
|
||||||
if (Main.debug.Value)
|
if (Main.debug.Value)
|
||||||
Console.WriteLine("ModuleShieldGenerator.OnAttached");
|
Console.WriteLine("ModuleShieldGenerator.OnAttached");
|
||||||
if (!healingHeartbeatInterval.ContainsKey(__instance)) {
|
|
||||||
healingHeartbeatInterval.Add(__instance, __instance.m_HealingHeartbeatInterval);
|
if (!originalProperties.ContainsKey(__instance)) {
|
||||||
if (Main.debug.Value)
|
var props = new MultipliedObject<ModuleShieldGenerator>(__instance);
|
||||||
Console.WriteLine("Patching {0}; m_HealingHeartbeatInterval: {1}", __instance.ToString(),
|
props.AddField("m_HealingHeartbeatInterval", Main.shieldHeartbeatIntervalMultiplier);
|
||||||
__instance.m_HealingHeartbeatInterval);
|
props.AddField("m_Radius", Main.shieldRadiusMultiplier);
|
||||||
}
|
props.AddField("m_PowerUpDelay", Main.powerUpDelayMultiplier);
|
||||||
if (!radius.ContainsKey(__instance)) {
|
|
||||||
radius.Add(__instance, __instance.m_Radius);
|
props.CaptureFrom();
|
||||||
if (Main.debug.Value)
|
originalProperties.Add(__instance, props);
|
||||||
Console.WriteLine("Patching {0}; m_Radius: {1}", __instance.ToString(), __instance.m_Radius);
|
props.LogValues("Patching");
|
||||||
}
|
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DoPatchSingle(__instance);
|
DoPatchSingle(__instance);
|
||||||
|
|
||||||
if (Main.debug.Value)
|
if (Main.debug.Value) {
|
||||||
Console.WriteLine("Patched {0}; m_HealingHeartbeatInterval: {1}", __instance.ToString(),
|
originalProperties[__instance].LogValues("Patched");
|
||||||
__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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(ModuleShieldGenerator), "OnDetaching")]
|
[HarmonyPatch(typeof(ModuleShieldGenerator), "OnDetaching")]
|
||||||
static void PostfixDestroy(ModuleShieldGenerator __instance) {
|
static void PostfixDestroy(ModuleShieldGenerator __instance) {
|
||||||
var trav = Traverse.Create(__instance);
|
if (Main.debug.Value) {
|
||||||
var powerUpDelayField = trav.Field("m_PowerUpDelay");
|
|
||||||
|
|
||||||
if (Main.debug.Value)
|
|
||||||
Console.WriteLine("ModuleShieldGenerator.OnDetaching");
|
Console.WriteLine("ModuleShieldGenerator.OnDetaching");
|
||||||
if (Main.debug.Value)
|
originalProperties[__instance].LogValues("Restoring");
|
||||||
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());
|
|
||||||
|
|
||||||
DoRestoreSingle(__instance);
|
DoRestoreSingle(__instance);
|
||||||
|
|
||||||
if (Main.debug.Value)
|
if (Main.debug.Value) {
|
||||||
Console.WriteLine("Restored {0}; m_HealingHeartbeatInterval: {1}", __instance.ToString(),
|
originalProperties[__instance].LogValues("Restored");
|
||||||
__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());
|
|
||||||
|
|
||||||
healingHeartbeatInterval.Remove(__instance);
|
originalProperties.Remove(__instance);
|
||||||
radius.Remove(__instance);
|
|
||||||
powerUpDelay.Remove(__instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DoPatch() {
|
public static void DoPatch() {
|
||||||
if (Main.debug.Value)
|
if (Main.debug.Value)
|
||||||
Console.WriteLine("Modifying {0} ModuleShieldGenerator", healingHeartbeatInterval.Count);
|
Console.WriteLine("Modifying {0} ModuleShieldGenerator", originalProperties.Count);
|
||||||
foreach (KeyValuePair<ModuleShieldGenerator, float> keyValuePair in healingHeartbeatInterval) {
|
foreach (var kvp in originalProperties) {
|
||||||
DoRestoreSingle(keyValuePair.Key);
|
DoRestoreSingle(kvp.Key);
|
||||||
DoPatchSingle(keyValuePair.Key);
|
DoPatchSingle(kvp.Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DoPatchSingle(ModuleShieldGenerator moduleShieldGenerator) {
|
static void DoPatchSingle(ModuleShieldGenerator moduleShieldGenerator) if (
|
||||||
var trav = Traverse.Create(moduleShieldGenerator);
|
originalProperties.TryGetValue(moduleShieldGenerator, out var props)) props.ApplyTo();
|
||||||
var powerUpDelayField = trav.Field("m_PowerUpDelay");
|
|
||||||
|
|
||||||
moduleShieldGenerator.m_HealingHeartbeatInterval =
|
static void DoRestoreSingle(ModuleShieldGenerator moduleShieldGenerator) if (
|
||||||
healingHeartbeatInterval[moduleShieldGenerator] * Main.shieldHeartbeatIntervalMultiplier.Value;
|
originalProperties.TryGetValue(moduleShieldGenerator, out var props)) props.RestoreTo();
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user