From 6877b8e9aca1ed864ee5263ff8cbefde15b827d8 Mon Sep 17 00:00:00 2001 From: Soar Qin Date: Sat, 26 Apr 2025 00:31:56 +0800 Subject: [PATCH] CheatEnabler: optimization --- CheatEnabler/CHANGELOG.md | 4 +- CheatEnabler/Patches/FactoryPatch.cs | 270 ++++++++++++++++----------- 2 files changed, 167 insertions(+), 107 deletions(-) diff --git a/CheatEnabler/CHANGELOG.md b/CheatEnabler/CHANGELOG.md index a2e8053..61840ce 100644 --- a/CheatEnabler/CHANGELOG.md +++ b/CheatEnabler/CHANGELOG.md @@ -5,7 +5,7 @@ * 2.3.30 + Fix a warning issue while `No condition build` or `No collision` is enabled. - + Optimized `Finish build immediately` for better performance. + + Increase performance for `Finish build immediately` greatly on pasting large blueprints. * 2.3.29 + Fix compatibility with game update 0.10.32.25779 * 2.3.28 @@ -155,7 +155,7 @@ * 2.3.30 + 修复了启用`无条件建造`或`无碰撞`时的警告问题 - + 优化了`立即完成建造`的性能表现 + + 粘贴大规模蓝图时大幅提升`立即完成建造`的性能表现 * 2.3.29 + 修复了与游戏更新0.10.32.25779的兼容性 * 2.3.28 diff --git a/CheatEnabler/Patches/FactoryPatch.cs b/CheatEnabler/Patches/FactoryPatch.cs index 685e8f6..b58b706 100644 --- a/CheatEnabler/Patches/FactoryPatch.cs +++ b/CheatEnabler/Patches/FactoryPatch.cs @@ -11,7 +11,7 @@ using UXAssist.Common; namespace CheatEnabler.Patches; -public class FactoryPatch: PatchImpl +public class FactoryPatch : PatchImpl { public static ConfigEntry ImmediateEnabled; public static ConfigEntry ArchitectModeEnabled; @@ -37,20 +37,20 @@ public class FactoryPatch: PatchImpl public static void Init() { _noConditionKey = KeyBindings.RegisterKeyBinding(new BuiltinKey - { - key = new CombineKey(0, 0, ECombineKeyAction.OnceClick, true), - conflictGroup = KeyBindConflict.MOVEMENT | KeyBindConflict.FLYING | KeyBindConflict.SAILING | KeyBindConflict.BUILD_MODE_1 | KeyBindConflict.KEYBOARD_KEYBIND, - name = "ToggleNoCondition", - canOverride = true - } + { + key = new CombineKey(0, 0, ECombineKeyAction.OnceClick, true), + conflictGroup = KeyBindConflict.MOVEMENT | KeyBindConflict.FLYING | KeyBindConflict.SAILING | KeyBindConflict.BUILD_MODE_1 | KeyBindConflict.KEYBOARD_KEYBIND, + name = "ToggleNoCondition", + canOverride = true + } ); _noCollisionKey = KeyBindings.RegisterKeyBinding(new BuiltinKey - { - key = new CombineKey(0, 0, ECombineKeyAction.OnceClick, true), - conflictGroup = KeyBindConflict.MOVEMENT | KeyBindConflict.FLYING | KeyBindConflict.SAILING | KeyBindConflict.BUILD_MODE_1 | KeyBindConflict.KEYBOARD_KEYBIND, - name = "ToggleNoCollision", - canOverride = true - } + { + key = new CombineKey(0, 0, ECombineKeyAction.OnceClick, true), + conflictGroup = KeyBindConflict.MOVEMENT | KeyBindConflict.FLYING | KeyBindConflict.SAILING | KeyBindConflict.BUILD_MODE_1 | KeyBindConflict.KEYBOARD_KEYBIND, + name = "ToggleNoCollision", + canOverride = true + } ); I18N.Add("KEYToggleNoCondition", "[CE] Toggle No Condition Build", "[CE] 切换无条件建造"); I18N.Add("KEYToggleNoCollision", "[CE] Toggle No Collision", "[CE] 切换无碰撞"); @@ -92,6 +92,7 @@ public class FactoryPatch: PatchImpl GreaterPowerUsageInLogistics.Enable(GreaterPowerUsageInLogisticsEnabled.Value); ControlPanelRemoteLogistics.Enable(ControlPanelRemoteLogisticsEnabled.Value); Enable(true); + CargoTrafficPatch.Enable(true); GameLogic.OnGameBegin += GameMain_Begin_Postfix_For_ImmBuild; GameLogic.OnDataLoaded += OnDataLoaded; } @@ -100,6 +101,7 @@ public class FactoryPatch: PatchImpl { GameLogic.OnDataLoaded -= OnDataLoaded; GameLogic.OnGameBegin -= GameMain_Begin_Postfix_For_ImmBuild; + CargoTrafficPatch.Enable(false); Enable(false); ImmediateBuild.Enable(false); ArchitectMode.Enable(false); @@ -116,10 +118,14 @@ public class FactoryPatch: PatchImpl } private static HashSet _beltIds = []; + private static HashSet _alterBeltRendererIds; + private static HashSet _alterPathRendererIds; + private static HashSet _refreshPathUVIds; + private static void OnDataLoaded() { WindTurbinesPowerGlobalCoverage.Enable(WindTurbinesPowerGlobalCoverageEnabled.Value); - _beltIds ??= [..LDB.items.dataArray.Where(i => i.prefabDesc.isBelt).Select(i => i.ID)]; + _beltIds ??= [.. LDB.items.dataArray.Where(i => i.prefabDesc.isBelt).Select(i => i.ID)]; } public static void OnInputUpdate() @@ -163,6 +169,10 @@ public class FactoryPatch: PatchImpl { var anyBelt = false; var anyBuilt = false; + _alterBeltRendererIds ??= []; + _alterPathRendererIds ??= []; + _refreshPathUVIds ??= []; + CargoTrafficPatch.IsBatchBuilding = true; factory.BeginFlattenTerrain(); factory.cargoTraffic._batch_buffer_no_refresh = true; PlanetFactory.batchBuild = true; @@ -187,6 +197,25 @@ public class FactoryPatch: PatchImpl } factory.cargoTraffic._batch_buffer_no_refresh = false; factory.EndFlattenTerrain(); + CargoTrafficPatch.IsBatchBuilding = false; + var cargoTraffic = factory.cargoTraffic; + var entityPool = factory.entityPool; + var colChunks = factory.planet.physics?.colChunks; + foreach (var beltId in _alterBeltRendererIds) + { + cargoTraffic.AlterBeltRenderer(beltId, entityPool, colChunks, false); + } + foreach (var pathId in _alterPathRendererIds) + { + cargoTraffic.AlterPathRenderer(pathId, false); + } + foreach (var pathId in _refreshPathUVIds) + { + cargoTraffic.RefreshPathUV(pathId); + } + _alterBeltRendererIds.Clear(); + _alterPathRendererIds.Clear(); + _refreshPathUVIds.Clear(); if (anyBuilt) { factory.planet.physics?.raycastLogic?.NotifyBatchObjectRemove(); @@ -205,6 +234,37 @@ public class FactoryPatch: PatchImpl } } + private class CargoTrafficPatch : PatchImpl + { + public static bool IsBatchBuilding; + [HarmonyPrefix] + [HarmonyPatch(typeof(CargoTraffic), nameof(CargoTraffic.AlterBeltRenderer))] + private static bool CargoTraffic_AlterBeltRenderer_Prefix(int beltId) + { + if (!IsBatchBuilding) return true; + _alterBeltRendererIds.Add(beltId); + return false; + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(CargoTraffic), nameof(CargoTraffic.AlterPathRenderer))] + private static bool CargoTraffic_AlterPathRenderer_Prefix(int pathId) + { + if (!IsBatchBuilding) return true; + _alterPathRendererIds.Add(pathId); + return false; + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(CargoTraffic), nameof(CargoTraffic.RefreshPathUV))] + private static bool CargoTraffic_RefreshPathUV_Prefix(int pathId) + { + if (!IsBatchBuilding) return true; + _refreshPathUVIds.Add(pathId); + return false; + } + } + [HarmonyPostfix] [HarmonyPatch(typeof(PlanetData), nameof(PlanetData.NotifyFactoryLoaded))] private static void PlanetData_NotifyFactoryLoaded_Postfix(PlanetData __instance) @@ -297,7 +357,7 @@ public class FactoryPatch: PatchImpl return matcher.InstructionEnumeration(); } - private class ImmediateBuild: PatchImpl + private class ImmediateBuild : PatchImpl { protected override void OnEnable() { @@ -355,7 +415,7 @@ public class FactoryPatch: PatchImpl } } - private class ArchitectMode: PatchImpl + private class ArchitectMode : PatchImpl { private static bool[] _canBuildItems; @@ -409,7 +469,7 @@ public class FactoryPatch: PatchImpl } } - private class NoConditionBuild: PatchImpl + private class NoConditionBuild : PatchImpl { protected override void OnEnable() { @@ -497,7 +557,7 @@ public class FactoryPatch: PatchImpl } } - public class BeltSignalGenerator: PatchImpl + public class BeltSignalGenerator : PatchImpl { private static Dictionary[] _signalBelts; private static Dictionary _portalFrom; @@ -882,7 +942,7 @@ public class FactoryPatch: PatchImpl public static void ProcessBeltSignals() { if (!_initialized) return; - var data = GameMain.data; + var data = GameMain.data; var factories = data?.factories; if (factories == null) return; PerformanceMonitor.BeginSample(ECpuWorkEntry.Belt); @@ -914,96 +974,96 @@ public class FactoryPatch: PatchImpl switch (signalId) { case 404: - { - var beltId = pair.Key; - ref var belt = ref cargoTraffic.beltPool[beltId]; - var cargoPath = cargoTraffic.GetCargoPath(belt.segPathId); - if (cargoPath == null) continue; - int itemId; - if ((itemId = cargoPath.TryPickItem(belt.segIndex + belt.segPivotOffset - 5, 12, out var stack, out _)) > 0) { - if (BeltSignalCountRemEnabled.Value) consumeRegister[itemId] += stack; - } - - continue; - } - case 600: - { - if (!_portalTo.TryGetValue(beltSignal.SpeedLimit, out var set)) continue; - var beltId = pair.Key; - ref var belt = ref cargoTraffic.beltPool[beltId]; - var cargoPath = cargoTraffic.GetCargoPath(belt.segPathId); - if (cargoPath == null) continue; - var segIndex = belt.segIndex + belt.segPivotOffset; - if (!cargoPath.GetCargoAtIndex(segIndex, out var cargo, out var cargoId, out var _)) break; - var itemId = cargo.item; - var cargoPool = cargoPath.cargoContainer.cargoPool; - var inc = cargoPool[cargoId].inc; - var stack = cargoPool[cargoId].stack; - foreach (var n in set) - { - var cargoTraffic1 = factories[(int)(n >> 32)].cargoTraffic; - ref var belt1 = ref cargoTraffic1.beltPool[(int)(n & 0x7FFFFFFF)]; - cargoPath = cargoTraffic1.GetCargoPath(belt1.segPathId); + var beltId = pair.Key; + ref var belt = ref cargoTraffic.beltPool[beltId]; + var cargoPath = cargoTraffic.GetCargoPath(belt.segPathId); if (cargoPath == null) continue; - if (!cargoPath.TryInsertItem(belt1.segIndex + belt1.segPivotOffset, itemId, stack, inc)) continue; - cargoPath.TryPickItem(segIndex - 5, 12, out var stack1, out var inc1); - if (inc1 != inc || stack1 != stack) - cargoPath.TryPickItem(segIndex - 5, 12, out _, out _); - break; - } + int itemId; + if ((itemId = cargoPath.TryPickItem(belt.segIndex + belt.segPivotOffset - 5, 12, out var stack, out _)) > 0) + { + if (BeltSignalCountRemEnabled.Value) consumeRegister[itemId] += stack; + } - continue; - } + continue; + } + case 600: + { + if (!_portalTo.TryGetValue(beltSignal.SpeedLimit, out var set)) continue; + var beltId = pair.Key; + ref var belt = ref cargoTraffic.beltPool[beltId]; + var cargoPath = cargoTraffic.GetCargoPath(belt.segPathId); + if (cargoPath == null) continue; + var segIndex = belt.segIndex + belt.segPivotOffset; + if (!cargoPath.GetCargoAtIndex(segIndex, out var cargo, out var cargoId, out var _)) break; + var itemId = cargo.item; + var cargoPool = cargoPath.cargoContainer.cargoPool; + var inc = cargoPool[cargoId].inc; + var stack = cargoPool[cargoId].stack; + foreach (var n in set) + { + var cargoTraffic1 = factories[(int)(n >> 32)].cargoTraffic; + ref var belt1 = ref cargoTraffic1.beltPool[(int)(n & 0x7FFFFFFF)]; + cargoPath = cargoTraffic1.GetCargoPath(belt1.segPathId); + if (cargoPath == null) continue; + if (!cargoPath.TryInsertItem(belt1.segIndex + belt1.segPivotOffset, itemId, stack, inc)) continue; + cargoPath.TryPickItem(segIndex - 5, 12, out var stack1, out var inc1); + if (inc1 != inc || stack1 != stack) + cargoPath.TryPickItem(segIndex - 5, 12, out _, out _); + break; + } + + continue; + } case >= 1000 and < 20000: - { - var hasSpeedLimit = beltSignal.SpeedLimit > 0; - if (hasSpeedLimit) { - beltSignal.Progress += beltSignal.SpeedLimit; - switch (beltSignal.Progress) + var hasSpeedLimit = beltSignal.SpeedLimit > 0; + if (hasSpeedLimit) { - case < 3600: - continue; - case > 18000: - beltSignal.Progress = 14400; - break; + beltSignal.Progress += beltSignal.SpeedLimit; + switch (beltSignal.Progress) + { + case < 3600: + continue; + case > 18000: + beltSignal.Progress = 14400; + break; + } } - } - var beltId = pair.Key; - ref var belt = ref cargoTraffic.beltPool[beltId]; - var cargoPath = cargoTraffic.GetCargoPath(belt.segPathId); - if (cargoPath == null) continue; - var stack = beltSignal.Stack; - var inc = beltSignal.Inc; - if (!cargoPath.TryInsertItem(belt.segIndex + belt.segPivotOffset, signalId, stack, inc)) continue; - if (hasSpeedLimit) beltSignal.Progress -= 3600; - if (BeltSignalCountGenEnabled.Value) productRegister[signalId] += stack; - if (!countRecipe) continue; - var sources = beltSignal.Sources; - if (sources == null) continue; - var progress = beltSignal.SourceProgress; - var stackf = (float)stack; - for (var i = sources.Length - 1; i >= 0; i--) - { - var newCnt = progress[i] + sources[i].Item2 * stackf; - if (newCnt > 0) + var beltId = pair.Key; + ref var belt = ref cargoTraffic.beltPool[beltId]; + var cargoPath = cargoTraffic.GetCargoPath(belt.segPathId); + if (cargoPath == null) continue; + var stack = beltSignal.Stack; + var inc = beltSignal.Inc; + if (!cargoPath.TryInsertItem(belt.segIndex + belt.segPivotOffset, signalId, stack, inc)) continue; + if (hasSpeedLimit) beltSignal.Progress -= 3600; + if (BeltSignalCountGenEnabled.Value) productRegister[signalId] += stack; + if (!countRecipe) continue; + var sources = beltSignal.Sources; + if (sources == null) continue; + var progress = beltSignal.SourceProgress; + var stackf = (float)stack; + for (var i = sources.Length - 1; i >= 0; i--) { - var itemId = sources[i].Item1; - var cnt = Mathf.CeilToInt(newCnt); - productRegister[itemId] += cnt; - consumeRegister[itemId] += cnt; - progress[i] = newCnt - cnt; + var newCnt = progress[i] + sources[i].Item2 * stackf; + if (newCnt > 0) + { + var itemId = sources[i].Item1; + var cnt = Mathf.CeilToInt(newCnt); + productRegister[itemId] += cnt; + consumeRegister[itemId] += cnt; + progress[i] = newCnt - cnt; + } + else + { + progress[i] = newCnt; + } } - else - { - progress[i] = newCnt; - } - } - continue; - } + continue; + } } } if (beltsToRemove == null) continue; @@ -1165,7 +1225,7 @@ public class FactoryPatch: PatchImpl /* END: Item sources calculation */ } - private class RemovePowerSpaceLimit: PatchImpl + private class RemovePowerSpaceLimit : PatchImpl { [HarmonyTranspiler] [HarmonyPatch(typeof(BuildTool_Click), nameof(BuildTool_Click.CheckBuildConditions))] @@ -1195,7 +1255,7 @@ public class FactoryPatch: PatchImpl } } - private class BoostWindPower: PatchImpl + private class BoostWindPower : PatchImpl { [HarmonyTranspiler] [HarmonyPatch(typeof(PowerGeneratorComponent), nameof(PowerGeneratorComponent.EnergyCap_Wind))] @@ -1220,7 +1280,7 @@ public class FactoryPatch: PatchImpl } } - private class BoostSolarPower: PatchImpl + private class BoostSolarPower : PatchImpl { [HarmonyTranspiler] [HarmonyPatch(typeof(PowerGeneratorComponent), nameof(PowerGeneratorComponent.EnergyCap_PV))] @@ -1244,7 +1304,7 @@ public class FactoryPatch: PatchImpl } } - private class BoostFuelPower: PatchImpl + private class BoostFuelPower : PatchImpl { [HarmonyTranspiler] [HarmonyPatch(typeof(PowerGeneratorComponent), nameof(PowerGeneratorComponent.EnergyCap_Fuel))] @@ -1285,7 +1345,7 @@ public class FactoryPatch: PatchImpl } } - private class BoostGeothermalPower: PatchImpl + private class BoostGeothermalPower : PatchImpl { [HarmonyTranspiler] [HarmonyPatch(typeof(PowerGeneratorComponent), nameof(PowerGeneratorComponent.EnergyCap_GTH))] @@ -1368,7 +1428,7 @@ public class FactoryPatch: PatchImpl } } - private class GreaterPowerUsageInLogistics: PatchImpl + private class GreaterPowerUsageInLogistics : PatchImpl { protected override void OnEnable() { @@ -1518,7 +1578,7 @@ public class FactoryPatch: PatchImpl } } - private class ControlPanelRemoteLogistics: PatchImpl + private class ControlPanelRemoteLogistics : PatchImpl { [HarmonyTranspiler] [HarmonyPatch(typeof(UIControlPanelDispenserInspector), nameof(UIControlPanelDispenserInspector.OnItemIconMouseDown))]