using System; using System.Collections.Generic; using HarmonyLib; namespace TerraTech { [HarmonyPatch] public class MinerPropertiesManager { private static Dictionary area = new Dictionary(); private static Dictionary speed = new Dictionary(); [HarmonyPrefix] [HarmonyPatch(typeof(ModuleItemProducer), "GetClosestResourceReservoirInRange")] static void PostfixCreate(ModuleItemProducer __instance) { // Console.WriteLine("ModuleItemProducer.GetClosestResourceReservoirInRange"); if (!area.ContainsKey(__instance)) { area.Add(__instance, GetArea(__instance)); speed.Add(__instance, GetSpeed(__instance)); // Console.WriteLine("Patching {0}; m_ResourceGroundRadius: {1}; m_SecPerItemProduced: {2}", __instance.name, GetArea(__instance), // GetSpeed(__instance)); DoPatchSingle(__instance); // Console.WriteLine("Patched {0}; m_ResourceGroundRadius: {1}; m_SecPerItemProduced: {2}", __instance.name, GetArea(__instance), // GetSpeed(__instance)); } else { if (GetArea(__instance) == area[__instance]) { // Console.WriteLine("{0} area reset, patching again... m_ResourceGroundRadius: {1}; m_SecPerItemProduced: {2}", __instance.name, // GetArea(__instance), GetSpeed(__instance)); DoPatchSingle(__instance); // Console.WriteLine("Patched {0}; m_ResourceGroundRadius: {1}; m_SecPerItemProduced: {2}", __instance.name, GetArea(__instance), // GetSpeed(__instance)); } if (GetSpeed(__instance) == speed[__instance]) { // Console.WriteLine("{0} speed reset, patching again... m_ResourceGroundRadius: {1}; m_SecPerItemProduced: {2}", __instance.name, // GetArea(__instance), GetSpeed(__instance)); DoPatchSingle(__instance); // Console.WriteLine("Patched {0}; m_ResourceGroundRadius: {1}; m_SecPerItemProduced: {2}", __instance.name, GetArea(__instance), // GetSpeed(__instance)); } } } [HarmonyPostfix] [HarmonyPatch(typeof(ModuleItemProducer), "OnDetaching")] static void PostfixDestroy(ModuleItemProducer __instance) { // Console.WriteLine("ModuleItemProducer.OnRecycle"); DoRestoreSingle(__instance); area.Remove(__instance); speed.Remove(__instance); } public static void DoPatch() { // Console.WriteLine("Modifying {0} ModuleItemProducer", area.Count); foreach (KeyValuePair keyValuePair in area) { DoRestoreSingle(keyValuePair.Key); DoPatchSingle(keyValuePair.Key); } } static void DoPatchSingle(ModuleItemProducer moduleItemProducer) { SetArea(moduleItemProducer, area[moduleItemProducer] * Main.minerGroundArea.Value); SetSpeed(moduleItemProducer, speed[moduleItemProducer] / Main.minerMiningSpeed.Value); } static void DoRestoreSingle(ModuleItemProducer moduleItemProducer) { if (area.ContainsKey(moduleItemProducer)) { SetArea(moduleItemProducer, area[moduleItemProducer]); SetSpeed(moduleItemProducer, speed[moduleItemProducer]); } } private static float GetArea(ModuleItemProducer moduleItemProducer) { return Traverse.Create(moduleItemProducer).Field("m_ResourceGroundRadius").GetValue() as float? ?? 0f; } private static void SetArea(ModuleItemProducer moduleItemProducer, float value) { Traverse.Create(moduleItemProducer).Field("m_ResourceGroundRadius").SetValue(value); } private static float GetSpeed(ModuleItemProducer moduleItemProducer) { return Traverse.Create(moduleItemProducer).Field("m_SecPerItemProduced").GetValue() as float? ?? 0f; } private static void SetSpeed(ModuleItemProducer moduleItemProducer, float value) { Traverse.Create(moduleItemProducer).Field("m_SecPerItemProduced").SetValue(value); } } }