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<bool> debugGate;
public static void Init(ManualLogSource src, ConfigEntry<bool> 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<StationDist> _scratch;
private static readonly Comparison<StationDist> _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<StationDist>(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<bool> ProductionEnabled;
internal static ConfigEntry<float> ProductionCollectRadius;
internal static ConfigEntry<bool> ProductionNearestStationFirst;
internal static ConfigEntry<int> ProductionCollectIntervalTicks;
internal static ConfigEntry<bool> ProductionRequireStationDemandFlag;
internal static ConfigEntry<bool> ProductionSkipInserterFedBuildings;
internal static ConfigEntry<bool> ProductionVerboseScan;
internal static ConfigEntry<bool> MiningEnabled;
internal static ConfigEntry<float> MiningCollectRadius;
internal static ConfigEntry<bool> MiningNearestStationFirst;
internal static ConfigEntry<int> MiningCollectIntervalTicks;
internal static ConfigEntry<bool> MiningRequireStationDemandFlag;
internal static ConfigEntry<bool> MiningSkipInserterFedMiners;
internal static ConfigEntry<bool> MiningVerboseScan;
internal static ConfigEntry<bool> 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<bool>("Diagnostics", "DebugLog", false, "Enable verbose diagnostic logging to the BepInEx console.");
ProductionEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("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<float>("Production", "CollectRadius", 0f, "Max straight-line distance from a producer to an eligible station. 0 = planetwide.");
ProductionNearestStationFirst = ((BaseUnityPlugin)this).Config.Bind<bool>("Production", "NearestStationFirst", true, "Credit the closest eligible station first (true) instead of station build order (false).");
ProductionCollectIntervalTicks = ((BaseUnityPlugin)this).Config.Bind<int>("Production", "CollectIntervalTicks", 60, "Game ticks between collection scans. ~60 = 1s.");
ProductionRequireStationDemandFlag = ((BaseUnityPlugin)this).Config.Bind<bool>("Production", "RequireStationDemandFlag", false, "If true, only credit station slots set to Demand.");
ProductionSkipInserterFedBuildings = ((BaseUnityPlugin)this).Config.Bind<bool>("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<bool>("Production", "VerboseScan", false, "Debug aid (needs DebugLog on): periodic scan heartbeat even when nothing moved.");
MiningEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("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<float>("Mining", "CollectRadius", 0f, "Max straight-line distance from a miner to an eligible station. 0 = planetwide.");
MiningNearestStationFirst = ((BaseUnityPlugin)this).Config.Bind<bool>("Mining", "NearestStationFirst", true, "Credit the closest eligible station first (true) instead of station build order (false).");
MiningCollectIntervalTicks = ((BaseUnityPlugin)this).Config.Bind<int>("Mining", "CollectIntervalTicks", 60, "Game ticks between collection scans. ~60 = 1s.");
MiningRequireStationDemandFlag = ((BaseUnityPlugin)this).Config.Bind<bool>("Mining", "RequireStationDemandFlag", false, "If true, only credit station slots set to Demand.");
MiningSkipInserterFedMiners = ((BaseUnityPlugin)this).Config.Bind<bool>("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<bool>("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<StationDist> _scratch;
private static readonly Comparison<StationDist> _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<StationDist>(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;
}
}
}
}
}