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 System.Text; 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("PlanetwideAmmoSupply")] [assembly: AssemblyDescription("Dyson Sphere Program BepInEx mod.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("PlanetwideAmmoSupply")] [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 PlanetwideAmmoSupply; internal static class AmmoSourcing { private struct StationDist { public int index; public float distSqr; } private static readonly List _scratch = new List(64); private static readonly Comparison _byDist = (StationDist a, StationDist b) => a.distSqr.CompareTo(b.distSqr); internal static int TryPullFromPlanet(PlanetFactory factory, int itemId, int want, Vector3 pos, float radius, out int incMoved) { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) incMoved = 0; if (factory == null || itemId <= 0 || want <= 0) { return 0; } PlanetTransport transport = factory.transport; if (transport == null || transport.stationPool == null) { return 0; } bool value = Plugin.RequireStationSupplyFlag.Value; bool value2 = Plugin.NearestStationFirst.Value; float num = ((radius > 0f) ? (radius * radius) : 0f); EntityData[] entityPool = factory.entityPool; int stationCursor = transport.stationCursor; int moved = 0; Vector3 val2; if (value2) { _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 (StationHasItem(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; } DrainStation(transport.stationPool[_scratch[j].index], itemId, want, value, ref moved, ref incMoved); } } 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; } } } DrainStation(val3, itemId, want, value, ref moved, ref incMoved); } } return moved; } private static bool StationHasItem(StationComponent station, int itemId, bool requireSupply) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 StationStore[] storage = station.storage; for (int i = 0; i < storage.Length; i++) { if (storage[i].itemId == itemId && storage[i].count > 0 && (!requireSupply || (int)storage[i].localLogic == 1 || (int)storage[i].remoteLogic == 1)) { return true; } } return false; } private static void DrainStation(StationComponent station, int itemId, int want, bool requireSupply, ref int moved, ref int incMoved) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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 || storage[i].count <= 0 || (requireSupply && (int)storage[i].localLogic != 1 && (int)storage[i].remoteLogic != 1)) { continue; } int num = want - moved; if (num > storage[i].count) { num = storage[i].count; } int num2 = 0; if (storage[i].inc > 0) { num2 = (int)((float)storage[i].inc * (float)num / (float)storage[i].count + 0.5f); if (num2 > storage[i].inc) { num2 = storage[i].inc; } } storage[i].count -= num; storage[i].inc -= num2; moved += num; incMoved += num2; } } internal static int FindAvailableAmmo(PlanetFactory factory, EAmmoType ammoType, Vector3 pos, float radius) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Expected I4, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) int num = (int)ammoType; if (num <= 0 || ItemProto.turretNeeds == null || num >= ItemProto.turretNeeds.Length) { return 0; } int[] array = ItemProto.turretNeeds[num]; if (array == null) { return 0; } if (Plugin.PreferHighestAmmoTier.Value) { for (int num2 = array.Length - 1; num2 >= 0; num2--) { int num3 = array[num2]; if (num3 > 0 && HasStock(factory, num3, pos, radius)) { return num3; } } } else { foreach (int num4 in array) { if (num4 > 0 && HasStock(factory, num4, pos, radius)) { return num4; } } } return 0; } internal static float NearestAmmoStationDistance(PlanetFactory factory, int itemId, EAmmoType ammoType, Vector3 pos) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected I4, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_0119: Unknown result type (might be due to invalid IL or missing references) PlanetTransport val = factory?.transport; if (val == null || val.stationPool == null) { return -1f; } bool value = Plugin.RequireStationSupplyFlag.Value; EntityData[] entityPool = factory.entityPool; int stationCursor = val.stationCursor; int[] array = null; if (itemId <= 0) { int num = (int)ammoType; if (num > 0 && ItemProto.turretNeeds != null && num < ItemProto.turretNeeds.Length) { array = ItemProto.turretNeeds[num]; } } float num2 = -1f; for (int i = 1; i < stationCursor; i++) { StationComponent val2 = val.stationPool[i]; if (val2 == null || val2.id != i || val2.storage == null) { continue; } bool flag = false; if (itemId > 0) { flag = StationHasItem(val2, itemId, value); } else if (array != null) { for (int j = 0; j < array.Length; j++) { if (flag) { break; } if (array[j] > 0) { flag = StationHasItem(val2, array[j], value); } } } if (!flag) { continue; } float num3 = 0f; if (entityPool != null) { int entityId = val2.entityId; if (entityId > 0 && entityId < entityPool.Length) { Vector3 val3 = entityPool[entityId].pos - pos; num3 = ((Vector3)(ref val3)).sqrMagnitude; } } if (num2 < 0f || num3 < num2) { num2 = num3; } } if (!(num2 < 0f)) { return Mathf.Sqrt(num2); } return -1f; } private static bool HasStock(PlanetFactory factory, int itemId, Vector3 pos, float radius) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) PlanetTransport transport = factory.transport; if (transport == null || transport.stationPool == null) { return false; } bool value = Plugin.RequireStationSupplyFlag.Value; float num = ((radius > 0f) ? (radius * radius) : 0f); EntityData[] entityPool = factory.entityPool; int stationCursor = transport.stationCursor; for (int i = 1; i < stationCursor; i++) { StationComponent val = transport.stationPool[i]; if (val == null || val.id != i || val.storage == null) { continue; } if (num > 0f && entityPool != null) { int entityId = val.entityId; if (entityId > 0 && entityId < entityPool.Length) { Vector3 val2 = entityPool[entityId].pos - pos; if (((Vector3)(ref val2)).sqrMagnitude > num) { continue; } } } if (StationHasItem(val, itemId, value)) { return true; } } return false; } } internal static class PlanetwideAmmoSupplyLog { private const string Tag = "[PlanetwideAmmoSupply] "; 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)("[PlanetwideAmmoSupply] " + msg)); } } public static void Warn(string msg) { if (logger != null) { logger.LogWarning((object)("[PlanetwideAmmoSupply] " + msg)); } } public static void Error(string msg) { if (logger != null) { logger.LogError((object)("[PlanetwideAmmoSupply] " + msg)); } } } [HarmonyPatch(typeof(DefenseSystem), "GameTick", new Type[] { typeof(long), typeof(bool) })] internal static class DefenseSystemSupplyPatch { private struct TurretScan { public int total; public int belowCap; public int refilled; public int movedItems; public int noStock; public float nearestSupply; } private struct BattleScan { public int bases; public int slotsRefilled; public int movedItems; } private const int TurretAmmoTarget = 5; private const long LogThrottleTicks = 300L; private static long _lastLogTick = long.MinValue; private static void Postfix(DefenseSystem __instance, long tick, bool isActive) { try { if (!Plugin.Enabled.Value || __instance == null) { return; } int num = Plugin.RefillIntervalTicks.Value; if (num < 1) { num = 1; } if (tick % num != 0L) { return; } PlanetFactory factory = __instance.factory; if (factory == null) { return; } float value = Plugin.SupplyRadius.Value; TurretScan turretScan = default(TurretScan); BattleScan battleScan = default(BattleScan); if (Plugin.SupplyTurrets.Value) { turretScan = RefillTurrets(__instance, factory, value); } if (Plugin.SupplyBattleBases.Value) { battleScan = RefillBattleBases(__instance, factory, value); } if (!isActive || !PlanetwideAmmoSupplyLog.IsDebugEnabled()) { return; } bool value2 = Plugin.VerboseScan.Value; bool flag = turretScan.movedItems > 0 || battleScan.movedItems > 0 || turretScan.noStock > 0; if (!(value2 || flag) || tick - _lastLogTick < 300) { return; } _lastLogTick = tick; string text = "[supply] planet=" + factory.planetId + " turrets{" + (value2 ? ("total=" + turretScan.total + " belowCap=" + turretScan.belowCap + " ") : "") + "refilled=" + turretScan.refilled + " items=" + turretScan.movedItems + ((turretScan.noStock > 0) ? (" noStock=" + turretScan.noStock) : "") + "}"; if (value2) { text = text + " radius=" + ((value <= 0f) ? "planetwide" : value.ToString("0")); if (turretScan.belowCap > 0) { text = text + " nearestStation=" + ((turretScan.nearestSupply < 0f) ? "none-on-planet" : turretScan.nearestSupply.ToString("0")); } } if (value2 || battleScan.movedItems > 0) { text = text + " battlebase{" + (value2 ? ("bases=" + battleScan.bases + " ") : "") + "items=" + battleScan.movedItems + "}"; } PlanetwideAmmoSupplyLog.Info(text); } catch (Exception ex) { PlanetwideAmmoSupplyLog.Error("[patch] DefenseSystem.GameTick postfix threw: " + ex); } } private static TurretScan RefillTurrets(DefenseSystem def, PlanetFactory factory, float radius) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) TurretScan result = default(TurretScan); DataPool turrets = def.turrets; if (turrets == null || turrets.buffer == null) { return result; } TurretComponent[] buffer = turrets.buffer; int cursor = turrets.cursor; EntityData[] entityPool = factory.entityPool; bool flag = Plugin.VerboseScan.Value && PlanetwideAmmoSupplyLog.IsDebugEnabled(); bool flag2 = false; result.nearestSupply = -1f; for (int i = 1; i < cursor; i++) { if (buffer[i].id != i) { continue; } result.total++; if (buffer[i].itemCount >= 5) { continue; } result.belowCap++; Vector3 pos = Vector3.zero; int entityId = buffer[i].entityId; if (entityPool != null && entityId > 0 && entityId < entityPool.Length) { pos = entityPool[entityId].pos; } if (flag && !flag2) { result.nearestSupply = AmmoSourcing.NearestAmmoStationDistance(factory, buffer[i].itemId, buffer[i].ammoType, pos); flag2 = true; } int num = buffer[i].itemId; if (num == 0) { num = AmmoSourcing.FindAvailableAmmo(factory, buffer[i].ammoType, pos, radius); if (num == 0) { result.noStock++; continue; } } int want = 5 - buffer[i].itemCount; int incMoved; int num2 = AmmoSourcing.TryPullFromPlanet(factory, num, want, pos, radius, out incMoved); if (num2 <= 0) { result.noStock++; continue; } if (buffer[i].itemId == 0) { ((TurretComponent)(ref buffer[i])).SetNewItem(num, (short)num2, (short)incMoved); } else { buffer[i].itemCount += (short)num2; buffer[i].itemInc += (short)incMoved; } result.refilled++; result.movedItems += num2; } return result; } private static BattleScan RefillBattleBases(DefenseSystem def, PlanetFactory factory, float radius) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) BattleScan result = default(BattleScan); ObjectPool battleBases = def.battleBases; if (battleBases == null || battleBases.buffer == null) { return result; } BattleBaseComponent[] buffer = battleBases.buffer; int cursor = battleBases.cursor; EntityData[] entityPool = factory.entityPool; string value = Plugin.FighterItemFilter.Value; bool flag = !string.IsNullOrEmpty(value); int num3 = default(int); for (int i = 1; i < cursor; i++) { BattleBaseComponent val = buffer[i]; if (val == null || val.id != i) { continue; } StorageComponent storage = val.storage; if (storage == null || storage.grids == null) { continue; } result.bases++; Vector3 pos = Vector3.zero; int entityId = val.entityId; if (entityPool != null && entityId > 0 && entityId < entityPool.Length) { pos = entityPool[entityId].pos; } GRID[] grids = storage.grids; for (int j = 0; j < grids.Length; j++) { int itemId = grids[j].itemId; if (itemId <= 0) { continue; } int stackSize = grids[j].stackSize; if (stackSize > 0 && grids[j].count < stackSize && (!flag || value.IndexOf(itemId.ToString(), StringComparison.Ordinal) >= 0)) { int want = stackSize - grids[j].count; int incMoved; int num = AmmoSourcing.TryPullFromPlanet(factory, itemId, want, pos, radius, out incMoved); if (num > 0) { int num2 = storage.AddItem(itemId, num, incMoved, ref num3, false); result.slotsRefilled++; result.movedItems += num2; } } } } return result; } } [BepInPlugin("com.zicarius.PlanetwideAmmoSupply", "PlanetwideAmmoSupply", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.zicarius.PlanetwideAmmoSupply"; public const string PluginName = "PlanetwideAmmoSupply"; public const string PluginVersion = "1.0.0"; internal static ConfigEntry Enabled; internal static ConfigEntry SupplyTurrets; internal static ConfigEntry SupplyBattleBases; internal static ConfigEntry PreferHighestAmmoTier; internal static ConfigEntry SupplyRadius; internal static ConfigEntry NearestStationFirst; internal static ConfigEntry RefillIntervalTicks; internal static ConfigEntry RequireStationSupplyFlag; internal static ConfigEntry FighterItemFilter; internal static ConfigEntry VerboseScan; internal static ConfigEntry DebugLog; private Harmony harmony; private void Awake() { //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Expected O, but got Unknown DebugLog = ((BaseUnityPlugin)this).Config.Bind("Diagnostics", "DebugLog", false, "Enable verbose diagnostic logging to the BepInEx console."); Enabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Master switch. If false the mod is fully inert (vanilla belt supply unchanged)."); SupplyTurrets = ((BaseUnityPlugin)this).Config.Bind("General", "SupplyTurrets", true, "Auto-refill turret ammo from the planet's logistics stations."); SupplyBattleBases = ((BaseUnityPlugin)this).Config.Bind("General", "SupplyBattleBases", true, "Auto-refill battle-base ammo and fighters from the planet's logistics stations."); PreferHighestAmmoTier = ((BaseUnityPlugin)this).Config.Bind("General", "PreferHighestAmmoTier", true, "When auto-filling an EMPTY turret, pick the highest available ammo tier (true) or the lowest/cheapest (false). A turret that already holds an ammo item keeps that item's tier - this only chooses the first fill."); SupplyRadius = ((BaseUnityPlugin)this).Config.Bind("General", "SupplyRadius", 0f, "Max straight-line distance (metres) from a structure to an eligible station. 0 = planetwide (recommended - matches how PLS/ILS serve a whole planet). Scale: a standard planet is ~200m radius, so distances reach ~400m (opposite side). Rough guide: ~50 = tight cluster, ~150 = large base, ~300 = most of the planet, ~400 = whole standard planet. Small values like 10 are basically 'touching' and will match nothing."); NearestStationFirst = ((BaseUnityPlugin)this).Config.Bind("General", "NearestStationFirst", true, "Pull from the closest eligible station first (true) instead of station build order (false). Pairs naturally with SupplyRadius."); RefillIntervalTicks = ((BaseUnityPlugin)this).Config.Bind("General", "RefillIntervalTicks", 60, "Game ticks between refill scans (throttle). ~60 = 1s. Higher = cheaper, lower = more responsive."); RequireStationSupplyFlag = ((BaseUnityPlugin)this).Config.Bind("Advanced", "RequireStationSupplyFlag", false, "If true, only pull from station slots set to 'Supply' (never 'Demand'/'Storage'). False = pull from any slot holding the ammo."); FighterItemFilter = ((BaseUnityPlugin)this).Config.Bind("Advanced", "FighterItemFilter", "", "Optional: restrict which fighter/ammo items battle bases pull (empty = everything the base already accepts)."); VerboseScan = ((BaseUnityPlugin)this).Config.Bind("Advanced", "VerboseScan", false, "Debug aid (needs DebugLog on): log a periodic scan heartbeat on the active planet (~1 per 5s) showing total/belowCap/refilled/noStock even when nothing moved - so you can see it working and why. Off = only log when ammo actually moves."); PlanetwideAmmoSupplyLog.Init(((BaseUnityPlugin)this).Logger, DebugLog); PlanetwideAmmoSupplyLog.Info("[config] Enabled=" + Enabled.Value + " SupplyTurrets=" + SupplyTurrets.Value + " SupplyBattleBases=" + SupplyBattleBases.Value + " SupplyRadius=" + SupplyRadius.Value + " RefillIntervalTicks=" + RefillIntervalTicks.Value + " RequireStationSupplyFlag=" + RequireStationSupplyFlag.Value + " PreferHighestAmmoTier=" + PreferHighestAmmoTier.Value + " NearestStationFirst=" + NearestStationFirst.Value + " VerboseScan=" + VerboseScan.Value); harmony = new Harmony("com.zicarius.PlanetwideAmmoSupply"); try { harmony.PatchAll(); PlanetwideAmmoSupplyLog.Info("[patch] PatchAll complete."); } catch (Exception ex) { PlanetwideAmmoSupplyLog.Error("[patch] PatchAll failed: " + ex); } if (DebugLog.Value) { DumpTargetMethodSignatures(); } PlanetwideAmmoSupplyLog.Info("PlanetwideAmmoSupply 1.0.0 loaded."); } private void Start() { } private void OnDestroy() { if (harmony != null) { harmony.UnpatchSelf(); harmony = null; } PlanetwideAmmoSupplyLog.Info("PlanetwideAmmoSupply unloaded."); } private static void DumpTargetMethodSignatures() { string[][] array = new string[2][] { new string[2] { "DefenseSystem", "GameTick" }, new string[2] { "StorageComponent", "AddItem" } }; foreach (string[] array2 in array) { try { Type type = AccessTools.TypeByName(array2[0]); if (type == null) { PlanetwideAmmoSupplyLog.Warn("[diag] Type not found: " + array2[0]); continue; } MethodInfo methodInfo = ((array2[0] == "StorageComponent" && array2[1] == "AddItem") ? AccessTools.Method(type, array2[1], new Type[5] { typeof(int), typeof(int), typeof(int), typeof(int).MakeByRefType(), typeof(bool) }, (Type[])null) : AccessTools.Method(type, array2[1], (Type[])null, (Type[])null)); if (methodInfo == null) { PlanetwideAmmoSupplyLog.Warn("[diag] Method not found: " + array2[0] + "." + array2[1]); continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("[diag] ").Append(array2[0]).Append('.') .Append(array2[1]) .Append('('); for (int j = 0; j < parameters.Length; j++) { if (j > 0) { stringBuilder.Append(", "); } stringBuilder.Append(parameters[j].ParameterType.Name).Append(' ').Append(parameters[j].Name); } stringBuilder.Append(')'); PlanetwideAmmoSupplyLog.Info(stringBuilder.ToString()); } catch (Exception ex) { PlanetwideAmmoSupplyLog.Error("[diag] Failed to inspect " + array2[0] + "." + array2[1] + ": " + ex.Message); } } array = new string[6][] { new string[2] { "DefenseSystem", "turrets" }, new string[2] { "DefenseSystem", "battleBases" }, new string[2] { "BattleBaseComponent", "storage" }, new string[2] { "PlanetFactory", "transport" }, new string[2] { "PlanetTransport", "stationPool" }, new string[2] { "StationComponent", "storage" } }; foreach (string[] array3 in array) { try { Type type2 = AccessTools.TypeByName(array3[0]); if (type2 == null) { PlanetwideAmmoSupplyLog.Warn("[diag] Type not found: " + array3[0]); continue; } FieldInfo fieldInfo = AccessTools.Field(type2, array3[1]); if (fieldInfo == null) { PlanetwideAmmoSupplyLog.Warn("[diag] Field not found: " + array3[0] + "." + array3[1]); continue; } PlanetwideAmmoSupplyLog.Info("[diag] field " + array3[0] + "." + array3[1] + " : " + fieldInfo.FieldType.Name); } catch (Exception ex2) { PlanetwideAmmoSupplyLog.Error("[diag] Failed to inspect field " + array3[0] + "." + array3[1] + ": " + ex2.Message); } } } }