using System; using System.Collections.Generic; using System.Diagnostics; 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; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("PlanetwideCollector")] [assembly: AssemblyDescription("Dyson Sphere Program BepInEx mod.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("PlanetwideCollector")] [assembly: AssemblyCopyright("Copyright (c) 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("00000000-0000-0000-0000-000000000000")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")] [assembly: AssemblyVersion("1.0.0.0")] namespace PlanetwideCollector; internal static class PlanetwideCollectorLog { private const string Tag = "[PlanetwideCollector] "; private static ManualLogSource logger; private static ConfigEntry debugGate; public static void Init(ManualLogSource src, ConfigEntry debug) { logger = src; debugGate = debug; } public static bool IsDebugEnabled() { if (debugGate != null) { return debugGate.Value; } return false; } public static void Info(string msg) { if (logger != null && IsDebugEnabled()) { logger.LogInfo((object)("[PlanetwideCollector] " + msg)); } } public static void Warn(string msg) { if (logger != null) { logger.LogWarning((object)("[PlanetwideCollector] " + msg)); } } public static void Error(string msg) { if (logger != null) { logger.LogError((object)("[PlanetwideCollector] " + msg)); } } } internal static class MiningScan { private struct ScanTotals { public int total; public int collected; public int movedItems; public int noSlot; public int skippedInserter; public int skippedClaimed; } private const long LogThrottleTicks = 300L; private static long _lastScannedTick = -1L; private static long _lastLogTick = long.MinValue; private static float _lastErrorLogRealtime = float.NegativeInfinity; private static bool[] _inserterIndex; private static bool[] _claimedMinerIndex; internal static void Tick() { try { if (!Plugin.MiningEnabled.Value || GameMain.data == null || GameMain.data.factories == null) { return; } long gameTick = GameMain.gameTick; int num = Plugin.MiningCollectIntervalTicks.Value; if (num < 1) { num = 1; } if (gameTick < _lastScannedTick) { _lastScannedTick = gameTick - num; _lastLogTick = gameTick - 300; } if (gameTick - _lastScannedTick < num) { return; } _lastScannedTick = gameTick; float value = Plugin.MiningCollectRadius.Value; ScanTotals totals = default(ScanTotals); PlanetFactory[] factories = GameMain.data.factories; foreach (PlanetFactory val in factories) { if (val != null && val.factorySystem != null) { ScanFactory(val, value, ref totals); } } if (PlanetwideCollectorLog.IsDebugEnabled()) { bool value2 = Plugin.MiningVerboseScan.Value; bool flag = totals.movedItems > 0 || totals.noSlot > 0 || totals.skippedInserter > 0; if ((value2 || flag) && gameTick - _lastLogTick >= 300) { _lastLogTick = gameTick; PlanetwideCollectorLog.Info("[collect] mining{" + (value2 ? ("total=" + totals.total + " claimed=" + totals.skippedClaimed + " ") : "") + "collected=" + totals.collected + " items=" + totals.movedItems + ((totals.noSlot > 0) ? (" noSlot=" + totals.noSlot) : "") + ((totals.skippedInserter > 0) ? (" skippedInserter=" + totals.skippedInserter) : "") + "}"); } } } catch (Exception ex) { float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup - _lastErrorLogRealtime >= 5f) { _lastErrorLogRealtime = realtimeSinceStartup; PlanetwideCollectorLog.Error("[scan] MiningScan.Tick threw: " + ex); } } } private static void ScanFactory(PlanetFactory factory, float radius, ref ScanTotals totals) { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) FactorySystem factorySystem = factory.factorySystem; if (factorySystem.minerCursor <= 1) { return; } MinerComponent[] minerPool = factorySystem.minerPool; if (minerPool == null) { return; } MiningSourcing.BuildClaimedMinerIndex(factory, ref _claimedMinerIndex); bool value = Plugin.MiningSkipInserterFedMiners.Value; if (value) { ProductionSourcing.BuildInserterIndex(factory, ref _inserterIndex); } EntityData[] entityPool = factory.entityPool; int minerCursor = factorySystem.minerCursor; for (int i = 1; i < minerCursor; i++) { if (minerPool[i].id != i) { continue; } totals.total++; if (_claimedMinerIndex != null && i < _claimedMinerIndex.Length && _claimedMinerIndex[i]) { totals.skippedClaimed++; continue; } int entityId = minerPool[i].entityId; if (value && _inserterIndex != null && entityId > 0 && entityId < _inserterIndex.Length && _inserterIndex[entityId]) { totals.skippedInserter++; continue; } int productId = minerPool[i].productId; if (productId == 0) { continue; } int productCount = minerPool[i].productCount; if (productCount > 0) { Vector3 pos = Vector3.zero; if (entityPool != null && entityId > 0 && entityId < entityPool.Length) { pos = entityPool[entityId].pos; } int num = MiningSourcing.TryPushToPlanet(factory, productId, productCount, pos, radius); if (num <= 0) { totals.noSlot++; continue; } minerPool[i].productCount -= num; totals.collected++; totals.movedItems += num; } } } } internal static class MiningSourcing { private struct StationDist { public int index; public float distSqr; } private static List _scratch; private static readonly Comparison _byDist = (StationDist a, StationDist b) => a.distSqr.CompareTo(b.distSqr); internal static int TryPushToPlanet(PlanetFactory factory, int itemId, int want, Vector3 pos, float radius) { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) if (factory == null || itemId <= 0 || want <= 0) { return 0; } PlanetTransport transport = factory.transport; if (transport == null || transport.stationPool == null) { return 0; } bool value = Plugin.MiningRequireStationDemandFlag.Value; bool value2 = Plugin.MiningNearestStationFirst.Value; float num = ((radius > 0f) ? (radius * radius) : 0f); EntityData[] entityPool = factory.entityPool; int stationCursor = transport.stationCursor; int moved = 0; Vector3 val2; if (value2) { if (_scratch == null) { _scratch = new List(64); } _scratch.Clear(); for (int i = 1; i < stationCursor; i++) { StationComponent val = transport.stationPool[i]; if (val == null || val.id != i || val.storage == null) { continue; } float num2 = 0f; if (entityPool != null) { int entityId = val.entityId; if (entityId > 0 && entityId < entityPool.Length) { val2 = entityPool[entityId].pos - pos; num2 = ((Vector3)(ref val2)).sqrMagnitude; if (num > 0f && num2 > num) { continue; } } } if (StationHasAssignedSlot(val, itemId, value)) { _scratch.Add(new StationDist { index = i, distSqr = num2 }); } } _scratch.Sort(_byDist); for (int j = 0; j < _scratch.Count; j++) { if (moved >= want) { break; } CreditStation(transport.stationPool[_scratch[j].index], itemId, want, value, ref moved); } } else { for (int k = 1; k < stationCursor && moved < want; k++) { StationComponent val3 = transport.stationPool[k]; if (val3 == null || val3.id != k || val3.storage == null) { continue; } if (num > 0f && entityPool != null) { int entityId2 = val3.entityId; if (entityId2 > 0 && entityId2 < entityPool.Length) { val2 = entityPool[entityId2].pos - pos; if (((Vector3)(ref val2)).sqrMagnitude > num) { continue; } } } CreditStation(val3, itemId, want, value, ref moved); } } return moved; } private static bool StationHasAssignedSlot(StationComponent station, int itemId, bool requireDemand) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 StationStore[] storage = station.storage; for (int i = 0; i < storage.Length; i++) { if (storage[i].itemId == itemId && (!requireDemand || (int)storage[i].localLogic == 2 || (int)storage[i].remoteLogic == 2)) { return true; } } return false; } private static void CreditStation(StationComponent station, int itemId, int want, bool requireDemand, ref int moved) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 StationStore[] storage = station.storage; for (int i = 0; i < storage.Length; i++) { if (moved >= want) { break; } if (storage[i].itemId != itemId || (requireDemand && (int)storage[i].localLogic != 2 && (int)storage[i].remoteLogic != 2)) { continue; } int num = storage[i].max - storage[i].count; if (num > 0) { int num2 = want - moved; if (num2 > num) { num2 = num; } storage[i].count += num2; moved += num2; } } } internal static void BuildClaimedMinerIndex(PlanetFactory factory, ref bool[] buffer) { int num = factory.factorySystem?.minerCursor ?? 0; if (buffer == null || buffer.Length < num) { buffer = new bool[num]; } else { Array.Clear(buffer, 0, num); } PlanetTransport transport = factory.transport; if (transport == null || transport.stationPool == null) { return; } StationComponent[] stationPool = transport.stationPool; int stationCursor = transport.stationCursor; for (int i = 1; i < stationCursor; i++) { StationComponent val = stationPool[i]; if (val != null && val.id == i && val.isVeinCollector) { int minerId = val.minerId; if (minerId > 0 && minerId < buffer.Length) { buffer[minerId] = true; } } } } } [BepInPlugin("com.zicarius.PlanetwideCollector", "PlanetwideCollector", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.zicarius.PlanetwideCollector"; public const string PluginName = "PlanetwideCollector"; public const string PluginVersion = "1.0.0"; internal static ConfigEntry ProductionEnabled; internal static ConfigEntry ProductionCollectRadius; internal static ConfigEntry ProductionNearestStationFirst; internal static ConfigEntry ProductionCollectIntervalTicks; internal static ConfigEntry ProductionRequireStationDemandFlag; internal static ConfigEntry ProductionSkipInserterFedBuildings; internal static ConfigEntry ProductionVerboseScan; internal static ConfigEntry MiningEnabled; internal static ConfigEntry MiningCollectRadius; internal static ConfigEntry MiningNearestStationFirst; internal static ConfigEntry MiningCollectIntervalTicks; internal static ConfigEntry MiningRequireStationDemandFlag; internal static ConfigEntry MiningSkipInserterFedMiners; internal static ConfigEntry MiningVerboseScan; internal static ConfigEntry DebugLog; private Harmony harmony; private void Awake() { //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Expected O, but got Unknown DebugLog = ((BaseUnityPlugin)this).Config.Bind("Diagnostics", "DebugLog", false, "Enable verbose diagnostic logging to the BepInEx console."); ProductionEnabled = ((BaseUnityPlugin)this).Config.Bind("Production", "Enabled", true, "Master switch for crafting-building output collection (smelters, assemblers, chemical plants, refineries, produce-mode Matrix Labs). If false this module is fully inert."); ProductionCollectRadius = ((BaseUnityPlugin)this).Config.Bind("Production", "CollectRadius", 0f, "Max straight-line distance from a producer to an eligible station. 0 = planetwide."); ProductionNearestStationFirst = ((BaseUnityPlugin)this).Config.Bind("Production", "NearestStationFirst", true, "Credit the closest eligible station first (true) instead of station build order (false)."); ProductionCollectIntervalTicks = ((BaseUnityPlugin)this).Config.Bind("Production", "CollectIntervalTicks", 60, "Game ticks between collection scans. ~60 = 1s."); ProductionRequireStationDemandFlag = ((BaseUnityPlugin)this).Config.Bind("Production", "RequireStationDemandFlag", false, "If true, only credit station slots set to Demand."); ProductionSkipInserterFedBuildings = ((BaseUnityPlugin)this).Config.Bind("Production", "SkipInserterFedBuildings", true, "If true, never auto-collect from a producer whose output is already being picked up by a sorter/inserter - only collect from producers with no outbound inserter connection at all."); ProductionVerboseScan = ((BaseUnityPlugin)this).Config.Bind("Production", "VerboseScan", false, "Debug aid (needs DebugLog on): periodic scan heartbeat even when nothing moved."); MiningEnabled = ((BaseUnityPlugin)this).Config.Bind("Mining", "Enabled", true, "Master switch for standalone-miner output collection (Mining Machines, Oil Extractors not already claimed by a station's own vein-collector mode). If false this module is fully inert."); MiningCollectRadius = ((BaseUnityPlugin)this).Config.Bind("Mining", "CollectRadius", 0f, "Max straight-line distance from a miner to an eligible station. 0 = planetwide."); MiningNearestStationFirst = ((BaseUnityPlugin)this).Config.Bind("Mining", "NearestStationFirst", true, "Credit the closest eligible station first (true) instead of station build order (false)."); MiningCollectIntervalTicks = ((BaseUnityPlugin)this).Config.Bind("Mining", "CollectIntervalTicks", 60, "Game ticks between collection scans. ~60 = 1s."); MiningRequireStationDemandFlag = ((BaseUnityPlugin)this).Config.Bind("Mining", "RequireStationDemandFlag", false, "If true, only credit station slots set to Demand."); MiningSkipInserterFedMiners = ((BaseUnityPlugin)this).Config.Bind("Mining", "SkipInserterFedMiners", true, "If true, never auto-collect from a miner whose output is already being picked up by a sorter/inserter."); MiningVerboseScan = ((BaseUnityPlugin)this).Config.Bind("Mining", "VerboseScan", false, "Debug aid (needs DebugLog on): periodic scan heartbeat even when nothing moved."); PlanetwideCollectorLog.Init(((BaseUnityPlugin)this).Logger, DebugLog); PlanetwideCollectorLog.Info("[config] Production.Enabled=" + ProductionEnabled.Value + " CollectRadius=" + ProductionCollectRadius.Value + " CollectIntervalTicks=" + ProductionCollectIntervalTicks.Value + " NearestStationFirst=" + ProductionNearestStationFirst.Value + " RequireStationDemandFlag=" + ProductionRequireStationDemandFlag.Value + " SkipInserterFedBuildings=" + ProductionSkipInserterFedBuildings.Value + " VerboseScan=" + ProductionVerboseScan.Value); PlanetwideCollectorLog.Info("[config] Mining.Enabled=" + MiningEnabled.Value + " CollectRadius=" + MiningCollectRadius.Value + " CollectIntervalTicks=" + MiningCollectIntervalTicks.Value + " NearestStationFirst=" + MiningNearestStationFirst.Value + " RequireStationDemandFlag=" + MiningRequireStationDemandFlag.Value + " SkipInserterFedMiners=" + MiningSkipInserterFedMiners.Value + " VerboseScan=" + MiningVerboseScan.Value); harmony = new Harmony("com.zicarius.PlanetwideCollector"); try { harmony.PatchAll(); PlanetwideCollectorLog.Info("[patch] PatchAll complete."); } catch (Exception ex) { PlanetwideCollectorLog.Error("[patch] PatchAll failed: " + ex); } if (DebugLog.Value) { DumpTargetMethodSignatures(); } PlanetwideCollectorLog.Info("PlanetwideCollector 1.0.0 loaded."); } private void Update() { ProductionScan.Tick(); MiningScan.Tick(); } private void OnDestroy() { if (harmony != null) { harmony.UnpatchSelf(); harmony = null; } PlanetwideCollectorLog.Info("PlanetwideCollector unloaded."); } private static void DumpTargetMethodSignatures() { string[][] array = new string[22][] { new string[2] { "PlanetFactory", "transport" }, new string[2] { "PlanetTransport", "stationPool" }, new string[2] { "StationComponent", "storage" }, new string[2] { "FactorySystem", "assemblerPool" }, new string[2] { "FactorySystem", "assemblerCursor" }, new string[2] { "FactorySystem", "labPool" }, new string[2] { "FactorySystem", "labCursor" }, new string[2] { "AssemblerComponent", "produced" }, new string[2] { "AssemblerComponent", "recipeExecuteData" }, new string[2] { "LabComponent", "produced" }, new string[2] { "LabComponent", "researchMode" }, new string[2] { "FactorySystem", "inserterPool" }, new string[2] { "FactorySystem", "inserterCursor" }, new string[2] { "InserterComponent", "pickTarget" }, new string[2] { "InserterComponent", "insertTarget" }, new string[2] { "FactorySystem", "minerPool" }, new string[2] { "FactorySystem", "minerCursor" }, new string[2] { "MinerComponent", "productId" }, new string[2] { "MinerComponent", "productCount" }, new string[2] { "MinerComponent", "entityId" }, new string[2] { "StationComponent", "minerId" }, new string[2] { "StationComponent", "isVeinCollector" } }; foreach (string[] array2 in array) { try { Type type = AccessTools.TypeByName(array2[0]); if (type == null) { PlanetwideCollectorLog.Warn("[diag] Type not found: " + array2[0]); continue; } FieldInfo fieldInfo = AccessTools.Field(type, array2[1]); if (fieldInfo == null) { PlanetwideCollectorLog.Warn("[diag] Field not found: " + array2[0] + "." + array2[1]); continue; } PlanetwideCollectorLog.Info("[diag] field " + array2[0] + "." + array2[1] + " : " + fieldInfo.FieldType.Name); } catch (Exception ex) { PlanetwideCollectorLog.Error("[diag] Failed to inspect field " + array2[0] + "." + array2[1] + ": " + ex.Message); } } } } internal static class ProductionScan { private struct ScanTotals { public int total; public int collected; public int movedItems; public int noSlot; public int skippedInserter; } private const long LogThrottleTicks = 300L; private static long _lastScannedTick = -1L; private static long _lastLogTick = long.MinValue; private static float _lastErrorLogRealtime = float.NegativeInfinity; private static bool[] _inserterIndex; internal static void Tick() { try { if (!Plugin.ProductionEnabled.Value || GameMain.data == null || GameMain.data.factories == null) { return; } long gameTick = GameMain.gameTick; int num = Plugin.ProductionCollectIntervalTicks.Value; if (num < 1) { num = 1; } if (gameTick < _lastScannedTick) { _lastScannedTick = gameTick - num; _lastLogTick = gameTick - 300; } if (gameTick - _lastScannedTick < num) { return; } _lastScannedTick = gameTick; float value = Plugin.ProductionCollectRadius.Value; ScanTotals totals = default(ScanTotals); PlanetFactory[] factories = GameMain.data.factories; foreach (PlanetFactory val in factories) { if (val != null && val.factorySystem != null) { ScanFactory(val, value, ref totals); } } if (PlanetwideCollectorLog.IsDebugEnabled()) { bool value2 = Plugin.ProductionVerboseScan.Value; bool flag = totals.movedItems > 0 || totals.noSlot > 0 || totals.skippedInserter > 0; if ((value2 || flag) && gameTick - _lastLogTick >= 300) { _lastLogTick = gameTick; PlanetwideCollectorLog.Info("[collect] production{" + (value2 ? ("total=" + totals.total + " ") : "") + "collected=" + totals.collected + " items=" + totals.movedItems + ((totals.noSlot > 0) ? (" noSlot=" + totals.noSlot) : "") + ((totals.skippedInserter > 0) ? (" skippedInserter=" + totals.skippedInserter) : "") + "}"); } } } catch (Exception ex) { float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup - _lastErrorLogRealtime >= 5f) { _lastErrorLogRealtime = realtimeSinceStartup; PlanetwideCollectorLog.Error("[scan] ProductionScan.Tick threw: " + ex); } } } private static void ScanFactory(PlanetFactory factory, float radius, ref ScanTotals totals) { FactorySystem factorySystem = factory.factorySystem; if (factorySystem.assemblerCursor <= 1 && factorySystem.labCursor <= 1) { return; } bool value = Plugin.ProductionSkipInserterFedBuildings.Value; if (value) { ProductionSourcing.BuildInserterIndex(factory, ref _inserterIndex); } EntityData[] entityPool = factory.entityPool; AssemblerComponent[] assemblerPool = factorySystem.assemblerPool; if (assemblerPool != null) { int assemblerCursor = factorySystem.assemblerCursor; for (int i = 1; i < assemblerCursor; i++) { if (assemblerPool[i].id == i && assemblerPool[i].recipeId != 0) { ScanProduced(factory, entityPool, assemblerPool[i].entityId, assemblerPool[i].recipeExecuteData, assemblerPool[i].produced, radius, value, ref totals); } } } LabComponent[] labPool = factorySystem.labPool; if (labPool == null) { return; } int labCursor = factorySystem.labCursor; for (int j = 1; j < labCursor; j++) { if (labPool[j].id == j && !labPool[j].researchMode && labPool[j].recipeId != 0) { ScanProduced(factory, entityPool, labPool[j].entityId, labPool[j].recipeExecuteData, labPool[j].produced, radius, value, ref totals); } } } private static void ScanProduced(PlanetFactory factory, EntityData[] entityPool, int entityId, RecipeExecuteData recipeExecuteData, int[] produced, float radius, bool skipInserterFed, ref ScanTotals totals) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if (recipeExecuteData == null || produced == null) { return; } totals.total++; if (skipInserterFed && _inserterIndex != null && entityId > 0 && entityId < _inserterIndex.Length && _inserterIndex[entityId]) { totals.skippedInserter++; return; } int[] products = recipeExecuteData.products; if (products == null) { return; } Vector3 pos = Vector3.zero; if (entityPool != null && entityId > 0 && entityId < entityPool.Length) { pos = entityPool[entityId].pos; } for (int i = 0; i < products.Length && i < produced.Length; i++) { int num = products[i]; if (num == 0) { continue; } int num2 = produced[i]; if (num2 > 0) { int num3 = ProductionSourcing.TryPushToPlanet(factory, num, num2, pos, radius); if (num3 <= 0) { totals.noSlot++; continue; } produced[i] -= num3; totals.collected++; totals.movedItems += num3; } } } } internal static class ProductionSourcing { private struct StationDist { public int index; public float distSqr; } private static List _scratch; private static readonly Comparison _byDist = (StationDist a, StationDist b) => a.distSqr.CompareTo(b.distSqr); internal static int TryPushToPlanet(PlanetFactory factory, int itemId, int want, Vector3 pos, float radius) { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) if (factory == null || itemId <= 0 || want <= 0) { return 0; } PlanetTransport transport = factory.transport; if (transport == null || transport.stationPool == null) { return 0; } bool value = Plugin.ProductionRequireStationDemandFlag.Value; bool value2 = Plugin.ProductionNearestStationFirst.Value; float num = ((radius > 0f) ? (radius * radius) : 0f); EntityData[] entityPool = factory.entityPool; int stationCursor = transport.stationCursor; int moved = 0; Vector3 val2; if (value2) { if (_scratch == null) { _scratch = new List(64); } _scratch.Clear(); for (int i = 1; i < stationCursor; i++) { StationComponent val = transport.stationPool[i]; if (val == null || val.id != i || val.storage == null) { continue; } float num2 = 0f; if (entityPool != null) { int entityId = val.entityId; if (entityId > 0 && entityId < entityPool.Length) { val2 = entityPool[entityId].pos - pos; num2 = ((Vector3)(ref val2)).sqrMagnitude; if (num > 0f && num2 > num) { continue; } } } if (StationHasAssignedSlot(val, itemId, value)) { _scratch.Add(new StationDist { index = i, distSqr = num2 }); } } _scratch.Sort(_byDist); for (int j = 0; j < _scratch.Count; j++) { if (moved >= want) { break; } CreditStation(transport.stationPool[_scratch[j].index], itemId, want, value, ref moved); } } else { for (int k = 1; k < stationCursor && moved < want; k++) { StationComponent val3 = transport.stationPool[k]; if (val3 == null || val3.id != k || val3.storage == null) { continue; } if (num > 0f && entityPool != null) { int entityId2 = val3.entityId; if (entityId2 > 0 && entityId2 < entityPool.Length) { val2 = entityPool[entityId2].pos - pos; if (((Vector3)(ref val2)).sqrMagnitude > num) { continue; } } } CreditStation(val3, itemId, want, value, ref moved); } } return moved; } private static bool StationHasAssignedSlot(StationComponent station, int itemId, bool requireDemand) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 StationStore[] storage = station.storage; for (int i = 0; i < storage.Length; i++) { if (storage[i].itemId == itemId && (!requireDemand || (int)storage[i].localLogic == 2 || (int)storage[i].remoteLogic == 2)) { return true; } } return false; } private static void CreditStation(StationComponent station, int itemId, int want, bool requireDemand, ref int moved) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 StationStore[] storage = station.storage; for (int i = 0; i < storage.Length; i++) { if (moved >= want) { break; } if (storage[i].itemId != itemId || (requireDemand && (int)storage[i].localLogic != 2 && (int)storage[i].remoteLogic != 2)) { continue; } int num = storage[i].max - storage[i].count; if (num > 0) { int num2 = want - moved; if (num2 > num) { num2 = num; } storage[i].count += num2; moved += num2; } } } internal static void BuildInserterIndex(PlanetFactory factory, ref bool[] buffer) { int entityCursor = factory.entityCursor; if (buffer == null || buffer.Length < entityCursor) { buffer = new bool[entityCursor]; } else { Array.Clear(buffer, 0, entityCursor); } FactorySystem factorySystem = factory.factorySystem; if (factorySystem == null || factorySystem.inserterPool == null) { return; } InserterComponent[] inserterPool = factorySystem.inserterPool; int inserterCursor = factorySystem.inserterCursor; for (int i = 1; i < inserterCursor; i++) { if (inserterPool[i].id == i) { int pickTarget = inserterPool[i].pickTarget; if (pickTarget > 0 && pickTarget < buffer.Length) { buffer[pickTarget] = true; } } } } }