using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; using crecheng.DSPModSave; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("AssemblerVerticalConstruction")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("AssemblerVerticalConstruction")] [assembly: AssemblyCopyright("Copyright lltcggie 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("5678B572-A4A6-488A-8229-BE42EB9AEFE3")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.1.0.0")] namespace AssemblerVerticalConstruction; public class AssemblerComponentEx { public int[][] assemblerNextIds = new int[384][]; public int assemblerCapacity = 384; public int transfarCount = 6; public void SetAssemblerCapacity(int newCapacity) { int[][] array = assemblerNextIds; assemblerNextIds = new int[newCapacity][]; if (array != null) { Array.Copy(array, assemblerNextIds, (newCapacity <= assemblerCapacity) ? newCapacity : assemblerCapacity); } assemblerCapacity = newCapacity; } public int GetNextId(int index, int assemblerId) { if (index >= assemblerNextIds.Length) { return 0; } if (assemblerNextIds[index] == null || assemblerId >= assemblerNextIds[index].Length) { return 0; } return assemblerNextIds[index][assemblerId]; } public static void FindRecipeIdForBuild(FactorySystem factorySystem, int assemblerId) { int entityId = factorySystem.assemblerPool[assemblerId].entityId; if (entityId == 0) { return; } int num = entityId; bool flag = default(bool); int num2 = default(int); int num3 = default(int); do { factorySystem.factory.ReadObjectConn(num, 14, ref flag, ref num2, ref num3); num = num2; if (num > 0) { int assemblerId2 = factorySystem.factory.entityPool[num].assemblerId; if (assemblerId2 > 0 && factorySystem.assemblerPool[assemblerId2].id == assemblerId2 && factorySystem.assemblerPool[assemblerId2].recipeId > 0) { ((AssemblerComponent)(ref factorySystem.assemblerPool[assemblerId])).SetRecipe(factorySystem.assemblerPool[assemblerId2].recipeId, factorySystem.factory.entitySignPool); SyncForceAccModeFromSource(factorySystem, assemblerId, assemblerId2); return; } } } while (num != 0); num = entityId; do { factorySystem.factory.ReadObjectConn(num, 15, ref flag, ref num2, ref num3); num = num2; if (num > 0) { int assemblerId3 = factorySystem.factory.entityPool[num].assemblerId; if (assemblerId3 > 0 && factorySystem.assemblerPool[assemblerId3].id == assemblerId3 && factorySystem.assemblerPool[assemblerId3].recipeId > 0) { ((AssemblerComponent)(ref factorySystem.assemblerPool[assemblerId])).SetRecipe(factorySystem.assemblerPool[assemblerId3].recipeId, factorySystem.factory.entitySignPool); SyncForceAccModeFromSource(factorySystem, assemblerId, assemblerId3); break; } } } while (num != 0); } private static void SyncForceAccModeFromSource(FactorySystem factorySystem, int targetAssemblerId, int sourceAssemblerId) { ref AssemblerComponent reference = ref factorySystem.assemblerPool[targetAssemblerId]; ref AssemblerComponent reference2 = ref factorySystem.assemblerPool[sourceAssemblerId]; if (reference.recipeExecuteData != null && reference.recipeExecuteData.productive) { reference.forceAccMode = reference2.forceAccMode; } } public void SetAssemblerInsertTarget(PlanetFactory __instance, int assemblerId, int nextEntityId) { int index = __instance.factorySystem.factory.index; if (index >= assemblerNextIds.Length) { SetAssemblerCapacity(assemblerCapacity * 2); } if (assemblerId != 0 && __instance.factorySystem.assemblerPool[assemblerId].id == assemblerId) { if (nextEntityId == 0) { assemblerNextIds[index][assemblerId] = 0; return; } int assemblerId2 = __instance.entityPool[nextEntityId].assemblerId; assemblerNextIds[index][assemblerId] = assemblerId2; FindRecipeIdForBuild(__instance.factorySystem, assemblerId); } } public void UnsetAssemblerInsertTarget(PlanetFactory __instance, int assemblerId, int assemblerRemoveId) { int index = __instance.factorySystem.factory.index; if (assemblerId != 0 && __instance.factorySystem.assemblerPool[assemblerId].id == assemblerId) { assemblerNextIds[index][assemblerId] = 0; } } public void SetAssemblerNext(int index, int assemblerId, int nextId) { if (index >= assemblerNextIds.Length) { SetAssemblerCapacity(assemblerCapacity * 2); } if (assemblerNextIds[index] == null || assemblerId >= assemblerNextIds[index].Length) { int[] array = assemblerNextIds[index]; int num = assemblerId * 2; num = ((num > 256) ? num : 256); assemblerNextIds[index] = new int[num]; if (array != null) { int num2 = array.Length; Array.Copy(array, assemblerNextIds[index], (num <= num2) ? num : num2); } } assemblerNextIds[index][assemblerId] = nextId; } public void UpdateOutputToNext(PlanetFactory factory, int planeIndex, int assemblerId, AssemblerComponent[] assemblerPool, int assemblerNextId, bool useMutex) { if (useMutex) { int entityId = assemblerPool[assemblerId].entityId; int entityId2 = assemblerPool[assemblerNextId].entityId; lock (factory.entityMutexs[entityId]) { lock (factory.entityMutexs[entityId2]) { UpdateOutputToNextInner(assemblerId, assemblerNextId, assemblerPool); return; } } } UpdateOutputToNextInner(assemblerId, assemblerNextId, assemblerPool); } private void UpdateOutputToNextInner(int assemblerId, int assemblerNextId, AssemblerComponent[] assemblerPool) { ref AssemblerComponent reference = ref assemblerPool[assemblerId]; if (reference.served == null) { return; } ref AssemblerComponent reference2 = ref assemblerPool[assemblerNextId]; if (reference2.served == null || reference2.recipeExecuteData == null) { return; } int timeSpend = reference2.recipeExecuteData.timeSpend; if (timeSpend <= 0) { return; } int num = reference2.speedOverride * 180 / timeSpend + 1; int num2 = reference.served.Length; for (int i = 0; i < num2; i++) { int num3 = reference.served[i]; int num4 = reference2.recipeExecuteData.requireCounts[i] * num - reference2.served[i]; if (num4 > 0 && num3 > 0) { ref int reference3 = ref reference.incServed[i]; int num5 = Math.Min(num3, num4); if (reference3 <= 0) { reference3 = 0; } int num6 = split_inc_level(ref reference.served[i], ref reference3, num5); if (reference.served[i] == 0) { reference3 = 0; } reference2.served[i] += num5; reference2.incServed[i] += num5 * num6; } } int num7 = reference.recipeExecuteData.productCounts.Length; for (int j = 0; j < num7; j++) { int num8 = reference.recipeExecuteData.productCounts[j] * 9 - reference.produced[j]; if (num8 > 0 && reference2.produced[j] > 0) { int num9 = Math.Min(num8, reference2.produced[j]); reference.produced[j] += num9; reference2.produced[j] -= num9; } } } private int split_inc_level(ref int n, ref int m, int p) { if (n <= 0) { return 0; } int num = m / n; int num2 = m - num * n; n -= p; int num3 = num2 - n; m -= ((num3 > 0) ? (num * p + num3) : (num * p)); return num; } } [BepInPlugin("lltcggie.DSP.plugin.AssemblerVerticalConstruction", "AssemblerVerticalConstruction", "1.1.10")] [BepInDependency(/*Could not decode attribute arguments.*/)] [ModSaveSettings(/*Could not decode attribute arguments.*/)] public class AssemblerVerticalConstruction : BaseUnityPlugin, IModCanSave { public static readonly int CurrentSavedataVersion = 3; public static ConfigEntry IsResetNextIds; private static ManualLogSource _logger; public static ManualLogSource Logger => _logger; private AssemblerVerticalConstruction() { _logger = ((BaseUnityPlugin)this).Logger; } ~AssemblerVerticalConstruction() { try { if (IsResetNextIds.Value) { IsResetNextIds.Value = false; ((BaseUnityPlugin)this).Config.Save(); } } finally { ((object)this).Finalize(); } } public void Awake() { Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); IsResetNextIds = ((BaseUnityPlugin)this).Config.Bind("config", "IsResetNextIds", false, "true if building overlay relationships must be recalculated when loading save data. This value is always reset to false when the game is closed."); } public void Import(BinaryReader binaryReader) { if ((Object)(object)DSPGame.Game == (Object)null) { return; } if (IsResetNextIds.Value) { Logger.LogInfo((object)"ResetNextIds"); AssemblerPatches.ResetNextIds(); return; } int num = binaryReader.ReadInt32() * -1; if (num < CurrentSavedataVersion) { Logger.LogInfo((object)$"Old save data version: read {num} current {CurrentSavedataVersion}"); Logger.LogInfo((object)"ResetNextIds"); AssemblerPatches.ResetNextIds(); return; } if (num != CurrentSavedataVersion) { Logger.LogWarning((object)$"Invalid save data version: read {num} current {CurrentSavedataVersion}"); Logger.LogInfo((object)"ResetNextIds"); AssemblerPatches.ResetNextIds(); return; } int num2 = binaryReader.ReadInt32(); if (num2 > AssemblerPatches.assemblerComponentEx.assemblerCapacity) { AssemblerPatches.assemblerComponentEx.SetAssemblerCapacity(num2); } for (int i = 0; i < num2; i++) { int num3 = binaryReader.ReadInt32(); for (int j = 0; j < num3; j++) { int nextId = binaryReader.ReadInt32(); AssemblerPatches.assemblerComponentEx.SetAssemblerNext(i, j, nextId); } } } public void Export(BinaryWriter binaryWriter) { if ((Object)(object)DSPGame.Game == (Object)null) { return; } binaryWriter.Write(CurrentSavedataVersion * -1); binaryWriter.Write(AssemblerPatches.assemblerComponentEx.assemblerCapacity); for (int i = 0; i < AssemblerPatches.assemblerComponentEx.assemblerCapacity; i++) { if (AssemblerPatches.assemblerComponentEx.assemblerNextIds[i] != null) { binaryWriter.Write(AssemblerPatches.assemblerComponentEx.assemblerNextIds[i].Length); for (int j = 0; j < AssemblerPatches.assemblerComponentEx.assemblerNextIds[i].Length; j++) { binaryWriter.Write(AssemblerPatches.assemblerComponentEx.assemblerNextIds[i][j]); } } else { binaryWriter.Write(0); } } } public void IntoOtherSave() { if (!((Object)(object)DSPGame.Game == (Object)null) && !DSPGame.IsMenuDemo) { Logger.LogInfo((object)"ResetNextIds"); AssemblerPatches.ResetNextIds(); } } } [HarmonyPatch] internal class AssemblerPatches { private class ModelSetting { public bool multiLevelAllowPortsOrSlots; public List multiLevelAlternativeIds; public List multiLevelAlternativeYawTransposes; public Vector3 lapJoint; public int[] multiLevelMaxBuildCount; public ModelSetting(bool multiLevelAllowPortsOrSlots, List multiLevelAlternativeIds, List multiLevelAlternativeYawTransposes, Vector3 lapJoint, int[] multiLevelMaxBuildCount) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) this.multiLevelAllowPortsOrSlots = multiLevelAllowPortsOrSlots; this.multiLevelAlternativeIds = multiLevelAlternativeIds; this.multiLevelAlternativeYawTransposes = multiLevelAlternativeYawTransposes; this.lapJoint = lapJoint; this.multiLevelMaxBuildCount = multiLevelMaxBuildCount; } } private static readonly ModelSetting AssemblerSetting = new ModelSetting(multiLevelAllowPortsOrSlots: false, new List { 2303, 2304, 2305, 2318 }, new List { false, false, false, false }, new Vector3(0f, 5.05f, 0f), new int[7] { 2, 4, 6, 8, 10, 11, 12 }); private static readonly ModelSetting SmelterSetting = new ModelSetting(multiLevelAllowPortsOrSlots: false, new List { 2302, 2315, 2319, 6230 }, new List { false, false, false, false }, new Vector3(0f, 4.3f, 0f), new int[7] { 2, 4, 6, 8, 10, 12, 14 }); private static readonly ModelSetting ChemicalPlantSetting = new ModelSetting(multiLevelAllowPortsOrSlots: false, new List { 2309, 2317 }, new List { false, false }, new Vector3(0f, 6.85f, 0f), new int[7] { 2, 4, 5, 6, 7, 8, 9 }); private static readonly ModelSetting OilRefinerySetting = new ModelSetting(multiLevelAllowPortsOrSlots: false, new List { 2308 }, new List { false }, new Vector3(0f, 11.8f, 0f), new int[7] { 1, 2, 2, 3, 3, 4, 5 }); private static readonly ModelSetting MiniatureParticleColliderSetting = new ModelSetting(multiLevelAllowPortsOrSlots: false, new List { 2310 }, new List { false }, new Vector3(0f, 15.2f, 0f), new int[7] { 1, 2, 2, 3, 3, 3, 4 }); private static readonly Dictionary ModelSettingDict = new Dictionary { { 2303, AssemblerSetting }, { 2304, AssemblerSetting }, { 2305, AssemblerSetting }, { 2318, AssemblerSetting }, { 2302, SmelterSetting }, { 2315, SmelterSetting }, { 2319, SmelterSetting }, { 6230, SmelterSetting }, { 2309, ChemicalPlantSetting }, { 2317, ChemicalPlantSetting }, { 2308, OilRefinerySetting }, { 2310, MiniatureParticleColliderSetting } }; public static AssemblerComponentEx assemblerComponentEx = new AssemblerComponentEx(); public static void ResetNextIds() { bool flag = default(bool); int num4 = default(int); int num5 = default(int); for (int i = 0; i < GameMain.data.factories.Length; i++) { if (GameMain.data.factories[i] == null) { continue; } FactorySystem factorySystem = GameMain.data.factories[i].factorySystem; if (factorySystem == null) { continue; } int index = factorySystem.factory.index; int[] array = new int[assemblerComponentEx.assemblerNextIds[index].Length]; int value = Traverse.Create((object)factorySystem).Field("assemblerCapacity").GetValue(); for (int j = 1; j < value; j++) { int num = j; int entityId = factorySystem.assemblerPool[num].entityId; if (entityId == 0) { continue; } int num2 = entityId; do { int num3 = num2; factorySystem.factory.ReadObjectConn(num2, 15, ref flag, ref num4, ref num5); num2 = num4; if (num2 > 0) { int assemblerId = factorySystem.factory.entityPool[num3].assemblerId; int assemblerId2 = factorySystem.factory.entityPool[num2].assemblerId; if (assemblerId2 > 0 && factorySystem.assemblerPool[assemblerId2].id == assemblerId2) { assemblerComponentEx.SetAssemblerNext(index, assemblerId, assemblerId2); array[assemblerId2] = assemblerId; } } } while (num2 != 0); } int num6 = array.Length; for (int k = 1; k < num6; k++) { int num7 = array[k]; if (array[k] == 0 && factorySystem.assemblerPool[num7].id == num7) { for (int nextId = assemblerComponentEx.GetNextId(index, k); nextId != 0; nextId = assemblerComponentEx.GetNextId(index, nextId)) { AssemblerComponentEx.FindRecipeIdForBuild(factorySystem, nextId); } } } } } [HarmonyPrefix] [HarmonyPatch(typeof(ItemProto), "Preload")] private static void PreloadPatch(ItemProto __instance, int _index) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) ModelProto val = LDB.models.modelArray[__instance.ModelIndex]; if (val == null || val.prefabDesc == null || !val.prefabDesc.isAssembler || !ModelSettingDict.TryGetValue(((Proto)__instance).ID, out var value)) { return; } LDB.models.modelArray[__instance.ModelIndex].prefabDesc.multiLevel = true; LDB.models.modelArray[__instance.ModelIndex].prefabDesc.multiLevelAllowPortsOrSlots = value.multiLevelAllowPortsOrSlots; LDB.models.modelArray[__instance.ModelIndex].prefabDesc.lapJoint = value.lapJoint; int num = value.multiLevelAlternativeIds.FindIndex((int item) => item == ((Proto)__instance).ID); if (num >= 0) { int[] array = new int[value.multiLevelAlternativeIds.Count - 1]; bool[] array2 = new bool[value.multiLevelAlternativeIds.Count - 1]; int num2 = 0; for (int num3 = 0; num3 < value.multiLevelAlternativeIds.Count; num3++) { if (num3 != num) { array[num2] = value.multiLevelAlternativeIds[num3]; array2[num2] = value.multiLevelAlternativeYawTransposes[num3]; num2++; } } LDB.models.modelArray[__instance.ModelIndex].prefabDesc.multiLevelAlternativeIds = array; LDB.models.modelArray[__instance.ModelIndex].prefabDesc.multiLevelAlternativeYawTransposes = array2; } else { LDB.models.modelArray[__instance.ModelIndex].prefabDesc.multiLevelAlternativeIds = value.multiLevelAlternativeIds.ToArray(); LDB.models.modelArray[__instance.ModelIndex].prefabDesc.multiLevelAlternativeYawTransposes = value.multiLevelAlternativeYawTransposes.ToArray(); } } [HarmonyPrefix] [HarmonyPatch(typeof(FactorySystem), "SetAssemblerCapacity")] private static bool SetAssemblerCapacityPatch(FactorySystem __instance, int newCapacity) { int index = __instance.factory.index; if (index > assemblerComponentEx.assemblerNextIds.Length) { assemblerComponentEx.SetAssemblerCapacity(assemblerComponentEx.assemblerCapacity * 2); } int value = Traverse.Create((object)__instance).Field("assemblerCapacity").GetValue(); int[] array = assemblerComponentEx.assemblerNextIds[index]; assemblerComponentEx.assemblerNextIds[index] = new int[newCapacity]; if (array != null) { Array.Copy(array, assemblerComponentEx.assemblerNextIds[index], (newCapacity <= value) ? newCapacity : value); } return true; } [HarmonyPrefix] [HarmonyPatch(typeof(PlanetFactory), "ApplyInsertTarget")] public static bool ApplyInsertTargetPatch(PlanetFactory __instance, int entityId, int insertTarget, int slotId, int offset) { if (entityId != 0) { if (insertTarget < 0) { Assert.CannotBeReached(); insertTarget = 0; } else { bool flag = default(bool); int num = default(int); int num2 = default(int); __instance.ReadObjectConn(entityId, 15, ref flag, ref num, ref num2); if (!flag || num != insertTarget) { int num3 = insertTarget; insertTarget = entityId; entityId = num3; } int assemblerId = __instance.entityPool[entityId].assemblerId; if (assemblerId > 0 && __instance.entityPool[insertTarget].assemblerId > 0) { assemblerComponentEx.SetAssemblerInsertTarget(__instance, assemblerId, insertTarget); } } } return true; } [HarmonyPrefix] [HarmonyPatch(typeof(PlanetFactory), "ApplyEntityDisconnection")] public static bool ApplyEntityDisconnectionPatch(PlanetFactory __instance, int otherEntityId, int removingEntityId, int otherSlotId, int removingSlotId) { if (otherEntityId == 0) { return true; } int assemblerId = __instance.entityPool[otherEntityId].assemblerId; if (assemblerId > 0) { int assemblerId2 = __instance.entityPool[removingEntityId].assemblerId; if (assemblerId2 > 0) { assemblerComponentEx.UnsetAssemblerInsertTarget(__instance, assemblerId, assemblerId2); } } return true; } [HarmonyPostfix] [HarmonyPatch(typeof(PlanetFactory), "CreateEntityLogicComponents")] public static void CreateEntityLogicComponentsPatch(PlanetFactory __instance, int entityId, PrefabDesc desc, int prebuildId) { if (entityId != 0 && desc.isAssembler) { int assemblerId = __instance.entityPool[entityId].assemblerId; AssemblerComponentEx.FindRecipeIdForBuild(__instance.factorySystem, assemblerId); } } [HarmonyPostfix] [HarmonyPatch(typeof(GameLogic), "_assembler_parallel")] public static void AssemblerParallelPatch(GameLogic __instance, int threadOrdinal) { ScatterTaskContext assembler = __instance.threadController.gameThreadContext.assembler; ref ScatterThreadContext reference = ref assembler.threadContexts[threadOrdinal]; PlanetFactory[] value = Traverse.Create((object)__instance).Field("factories").Value; int value2 = Traverse.Create((object)__instance).Field("factoryCount").Value; if (value2 <= 0) { return; } for (int i = reference.batchBegin; i <= reference.batchEnd; i++) { int num = (i + assembler.batchOffset) % value2; PlanetFactory val = value[num]; FactorySystem factorySystem = val.factorySystem; AssemblerComponent[] assemblerPool = factorySystem.assemblerPool; int assemblerCursor = factorySystem.assemblerCursor; int num2 = ((i != reference.batchBegin) ? 1 : reference.idBegin); int num3 = ((i == reference.batchEnd) ? reference.idEnd : assemblerCursor); for (int j = num2; j < num3; j++) { if (assemblerPool[j].id == j) { int nextId = assemblerComponentEx.GetNextId(num, j); if (nextId > 0) { assemblerComponentEx.UpdateOutputToNext(val, num, j, assemblerPool, nextId, useMutex: true); } } } } } public static void SyncAssemblerFunctions(FactorySystem factorySystem, Player player, int assemblerId) { int entityId = factorySystem.assemblerPool[assemblerId].entityId; if (entityId == 0) { return; } int num = entityId; bool flag = default(bool); int num2 = default(int); int num3 = default(int); do { factorySystem.factory.ReadObjectConn(num, 14, ref flag, ref num2, ref num3); num = num2; if (num <= 0) { continue; } int assemblerId2 = factorySystem.factory.entityPool[num].assemblerId; if (assemblerId2 <= 0 || factorySystem.assemblerPool[assemblerId2].id != assemblerId2) { continue; } if (factorySystem.assemblerPool[assemblerId].recipeId > 0) { if (factorySystem.assemblerPool[assemblerId2].recipeId != factorySystem.assemblerPool[assemblerId].recipeId) { factorySystem.TakeBackItems_Assembler(player, assemblerId2); ((AssemblerComponent)(ref factorySystem.assemblerPool[assemblerId2])).SetRecipe(factorySystem.assemblerPool[assemblerId].recipeId, factorySystem.factory.entitySignPool); } } else if (factorySystem.assemblerPool[assemblerId2].recipeId != 0) { factorySystem.TakeBackItems_Assembler(player, assemblerId2); ((AssemblerComponent)(ref factorySystem.assemblerPool[assemblerId2])).SetRecipe(0, factorySystem.factory.entitySignPool); } } while (num != 0); num = entityId; bool flag2 = default(bool); int num4 = default(int); int num5 = default(int); do { factorySystem.factory.ReadObjectConn(num, 15, ref flag2, ref num4, ref num5); num = num4; if (num <= 0) { continue; } int assemblerId3 = factorySystem.factory.entityPool[num].assemblerId; if (assemblerId3 <= 0 || factorySystem.assemblerPool[assemblerId3].id != assemblerId3) { continue; } if (factorySystem.assemblerPool[assemblerId].recipeId > 0) { if (factorySystem.assemblerPool[assemblerId3].recipeId != factorySystem.assemblerPool[assemblerId].recipeId) { factorySystem.TakeBackItems_Assembler(factorySystem.factory.gameData.mainPlayer, assemblerId3); ((AssemblerComponent)(ref factorySystem.assemblerPool[assemblerId3])).SetRecipe(factorySystem.assemblerPool[assemblerId].recipeId, factorySystem.factory.entitySignPool); } } else if (factorySystem.assemblerPool[assemblerId3].recipeId != 0) { factorySystem.TakeBackItems_Assembler(factorySystem.factory.gameData.mainPlayer, assemblerId3); ((AssemblerComponent)(ref factorySystem.assemblerPool[assemblerId3])).SetRecipe(0, factorySystem.factory.entitySignPool); } } while (num != 0); } [HarmonyPostfix] [HarmonyPatch(typeof(UIAssemblerWindow), "OnRecipeResetClick")] public static void OnRecipeResetClickPatch(UIAssemblerWindow __instance) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (__instance.assemblerId != 0 && __instance.factory != null && __instance.factorySystem.assemblerPool[__instance.assemblerId].id == __instance.assemblerId) { SyncAssemblerFunctions(__instance.factorySystem, __instance.player, __instance.assemblerId); } } [HarmonyPostfix] [HarmonyPatch(typeof(UIAssemblerWindow), "OnRecipePickerReturn")] public static void OnRecipePickerReturnPatch(UIAssemblerWindow __instance) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (__instance.assemblerId != 0 && __instance.factory != null && __instance.factorySystem.assemblerPool[__instance.assemblerId].id == __instance.assemblerId) { SyncAssemblerFunctions(__instance.factorySystem, __instance.player, __instance.assemblerId); } } [HarmonyPostfix] [HarmonyPatch(typeof(UIAssemblerWindow), "OnIncSwitchClick")] public static void OnIncSwitchClickPatch(UIAssemblerWindow __instance) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (__instance.assemblerId != 0 && __instance.factory != null && __instance.factorySystem.assemblerPool[__instance.assemblerId].id == __instance.assemblerId) { SyncForceAccMode(__instance.factorySystem, __instance.assemblerId); } } public static void SyncForceAccMode(FactorySystem factorySystem, int assemblerId) { int entityId = factorySystem.assemblerPool[assemblerId].entityId; if (entityId == 0) { return; } bool forceAccMode = factorySystem.assemblerPool[assemblerId].forceAccMode; int num = entityId; bool flag = default(bool); int num2 = default(int); int num3 = default(int); do { factorySystem.factory.ReadObjectConn(num, 14, ref flag, ref num2, ref num3); num = num2; if (num <= 0) { continue; } int assemblerId2 = factorySystem.factory.entityPool[num].assemblerId; if (assemblerId2 > 0 && factorySystem.assemblerPool[assemblerId2].id == assemblerId2) { RecipeExecuteData recipeExecuteData = factorySystem.assemblerPool[assemblerId2].recipeExecuteData; if (recipeExecuteData != null && recipeExecuteData.productive) { factorySystem.assemblerPool[assemblerId2].forceAccMode = forceAccMode; } } } while (num != 0); num = entityId; bool flag2 = default(bool); int num4 = default(int); int num5 = default(int); do { factorySystem.factory.ReadObjectConn(num, 15, ref flag2, ref num4, ref num5); num = num4; if (num <= 0) { continue; } int assemblerId3 = factorySystem.factory.entityPool[num].assemblerId; if (assemblerId3 > 0 && factorySystem.assemblerPool[assemblerId3].id == assemblerId3) { RecipeExecuteData recipeExecuteData2 = factorySystem.assemblerPool[assemblerId3].recipeExecuteData; if (recipeExecuteData2 != null && recipeExecuteData2.productive) { factorySystem.assemblerPool[assemblerId3].forceAccMode = forceAccMode; } } } while (num != 0); } [HarmonyPostfix] [HarmonyPatch(typeof(BuildingParameters), "PasteToFactoryObject")] public static void PasteToFactoryObjectPatch(BuildingParameters __instance, int objectId, PlanetFactory factory) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (objectId <= 0) { return; } int assemblerId = factory.entityPool[objectId].assemblerId; if (assemblerId != 0 && (int)__instance.type == 5 && factory.factorySystem.assemblerPool[assemblerId].recipeId == __instance.recipeId) { ItemProto val = ((ProtoSet)(object)LDB.items).Select((int)factory.entityPool[objectId].protoId); if (val != null && val.prefabDesc != null) { SyncAssemblerFunctions(factory.factorySystem, factory.gameData.mainPlayer, assemblerId); } } } [HarmonyPostfix] [HarmonyPatch(typeof(BuildTool_Click), "CheckBuildConditions")] public static void CheckBuildConditionsPatch(BuildTool_Click __instance, ref bool __result) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Invalid comparison between Unknown and I4 //IL_0108: Unknown result type (might be due to invalid IL or missing references) if (((BuildTool)__instance).buildPreviews.Count == 0) { return; } GameHistoryData history = ((BuildTool)__instance).actionBuild.history; bool flag = true; bool flag2 = default(bool); int num5 = default(int); int num6 = default(int); for (int i = 0; i < ((BuildTool)__instance).buildPreviews.Count; i++) { BuildPreview val = ((BuildTool)__instance).buildPreviews[i]; if ((int)val.condition != 0 || !val.desc.isAssembler || !val.desc.multiLevel) { continue; } int iD = ((Proto)val.item).ID; if (!ModelSettingDict.TryGetValue(iD, out var value)) { continue; } int num = history.storageLevel - 2; if (num >= value.multiLevelMaxBuildCount.Length) { continue; } int num2 = value.multiLevelMaxBuildCount[num]; int num3 = value.multiLevelMaxBuildCount[6]; int num4 = 0; if (val.inputObjId != 0) { ((BuildTool)__instance).factory.ReadObjectConn(val.inputObjId, 14, ref flag2, ref num5, ref num6); while (num5 != 0) { num4++; ((BuildTool)__instance).factory.ReadObjectConn(num5, 14, ref flag2, ref num5, ref num6); } } if (num2 >= 2 && num4 >= num2 - 1) { flag = num2 >= num3; val.condition = (EBuildCondition)40; } } for (int j = 0; j < ((BuildTool)__instance).buildPreviews.Count; j++) { BuildPreview val2 = ((BuildTool)__instance).buildPreviews[j]; if ((int)val2.condition == 40) { ((BuildTool)__instance).actionBuild.model.cursorState = -1; ((BuildTool)__instance).actionBuild.model.cursorText = val2.conditionText; if (!flag) { BuildModel model = ((BuildTool)__instance).actionBuild.model; model.cursorText += Localization.Translate("垂直建造可升级"); } if (!VFInput.onGUI) { UICursor.SetCursor((ECursor)6); } __result = false; break; } } } }