diff --git a/LabOpt/LabOpt.cs b/LabOpt/LabOpt.cs index 5e40133..b4dd374 100644 --- a/LabOpt/LabOpt.cs +++ b/LabOpt/LabOpt.cs @@ -214,8 +214,7 @@ public class LabOptPatch : BaseUnityPlugin [HarmonyPatch(typeof(FactorySystem), nameof(FactorySystem.FindLabFunctionsForBuild))] [HarmonyPatch(typeof(FactorySystem), nameof(FactorySystem.GameTickLabResearchMode))] [HarmonyPatch(typeof(FactorySystem), nameof(FactorySystem.SyncLabFunctions))] - // no need to patch this function, it just set everything to empty - // [HarmonyPatch(typeof(FactorySystem), nameof(FactorySystem.TakeBackItems_Lab))] + [HarmonyPatch(typeof(FactorySystem), nameof(FactorySystem.TakeBackItems_Lab))] private static IEnumerable FactorySystem_ReplaceLabSetFunction_Transpiler(IEnumerable instructions, ILGenerator generator) { var matcher = new CodeMatcher(instructions, generator); diff --git a/PoolOpt/PoolOpt.cs b/PoolOpt/PoolOpt.cs index 01b72e3..8294716 100644 --- a/PoolOpt/PoolOpt.cs +++ b/PoolOpt/PoolOpt.cs @@ -1,4 +1,5 @@ -using BepInEx; +using System; +using BepInEx; using HarmonyLib; namespace PoolOpt; @@ -13,12 +14,54 @@ public class PoolOptPatch : BaseUnityPlugin { Harmony.CreateAndPatchAll(typeof(PoolOptPatch)); } - + [HarmonyPostfix] [HarmonyPatch(typeof(GameSave), nameof(GameSave.LoadCurrentGame))] private static void GameSave_LoadCurrentGame_Postfix() { DebugOutput(); + foreach (var planet in GameMain.data.factories) + { + if (planet == null) continue; + var factorySystem = planet.factorySystem; + if (factorySystem != null) + { + OptimizePool((in MinerComponent n) => n.id, 256, + ref factorySystem.minerPool, ref factorySystem.minerCursor, ref factorySystem.minerCapacity, + ref factorySystem.minerRecycle, ref factorySystem.minerRecycleCursor); + } + } + DebugOutput(); + } + + private delegate int GetId(in T s) where T : struct; + + private static bool OptimizePool(GetId getter, int initCapacity, ref T[] pool, ref int cursor, ref int capacity, ref int[] recycle, ref int recycleCursor) where T : struct + { + if (cursor <= 1) return false; + var pos = cursor; + while (pos > 0) + { + if (getter(pool[pos]) == pos) break; + pos--; + } + + if (pos == cursor) return false; + if (pos == 0) + { + cursor = 1; + capacity = initCapacity; + pool = new T[initCapacity]; + recycle = new int[initCapacity]; + recycleCursor = 0; + return true; + } + + cursor = pos + 1; + Array.Sort(recycle); + var idx = Array.BinarySearch(recycle, 0, recycleCursor, pos); + recycleCursor = idx < 0 ? ~idx : idx + 1; + return true; } private static void DebugOutput() @@ -44,6 +87,7 @@ public class PoolOptPatch : BaseUnityPlugin Logger.LogDebug($" Storage: Storage=[{factoryStorage.storageCursor},{factoryStorage.storageCapacity},{factoryStorage.storageRecycleCursor}]"); Logger.LogDebug($" Tank=[{factoryStorage.tankCursor},{factoryStorage.tankCapacity},{factoryStorage.tankRecycleCursor}]"); } + var factorySystem = planet.factorySystem; if (factorySystem != null) { @@ -75,4 +119,4 @@ public class PoolOptPatch : BaseUnityPlugin } } } -} +} \ No newline at end of file