Decompiled source of TransmutationTable v1.0.0

TransmutationTable.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using ABN;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;
using crecheng.DSPModSave;
using xiaoye97;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("TransmutationTable")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TransmutationTable")]
[assembly: AssemblyTitle("TransmutationTable")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TransmutationTable
{
	[HarmonyPatch]
	public static class AbnormalityGuard
	{
		private static readonly HashSet<int> _reported = new HashSet<int>();

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ProtoSignature_0_10_30_3100), "CalculateSignature")]
		public static bool CalculateSignature_Prefix(ProtoTable protoSet, ref string __result)
		{
			try
			{
				__result = protoSet?.Signature ?? "";
			}
			catch
			{
				__result = "";
			}
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(GameAbnormalityData_0925), "TriggerAbnormality")]
		public static bool TriggerAbnormality_Prefix(int protoId, int minRecordVersion, long[] vals)
		{
			try
			{
				if (_reported.Add(protoId))
				{
					string arg = "";
					string arg2 = "";
					try
					{
						AbnormalityProto obj = ((ProtoSet<AbnormalityProto>)(object)LDB.abnormalities)?.Select(protoId);
						arg = obj?.DeterminatorName ?? "";
						arg2 = obj?.TipDesc ?? "";
					}
					catch
					{
					}
					TransmutationTablePlugin.Log.LogInfo((object)$"[数据异常] 原版判定触发 protoId={protoId} 检测器={arg} 说明={arg2}");
				}
			}
			catch
			{
			}
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameAbnormalityData_0925), "Import")]
		public static void Import_Postfix(GameAbnormalityData_0925 __instance)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				AbnormalityRuntimeData[] array = __instance?.runtimeDatas;
				if (array == null)
				{
					return;
				}
				int num = 0;
				for (int i = 0; i < array.Length; i++)
				{
					if (array[i].protoId > 0)
					{
						array[i] = default(AbnormalityRuntimeData);
						num++;
					}
				}
				if (num > 0)
				{
					TransmutationTablePlugin.Log.LogInfo((object)$"[数据异常] 已清除存档中的 {num} 条历史异常记录(签名恒等校验下不再产生)");
				}
			}
			catch (Exception e)
			{
				Diag.Error("异常记录清理", e);
			}
		}
	}
	internal static class BuildMenuInstaller
	{
		private static bool _installed;

		public static void TryInstall()
		{
			if (_installed)
			{
				return;
			}
			try
			{
				if (!((Object)(object)LDB.items == (Object)null) && ((ProtoSet<ItemProto>)(object)LDB.items).dataArray != null && TransmutationTablePlugin.TableProto != null && AccessTools.Field(typeof(UIBuildMenu), "protos")?.GetValue(null) is ItemProto[,] protos)
				{
					FieldInfo fieldInfo = AccessTools.Field(typeof(UIBuildMenu), "staticLoaded");
					if (!(fieldInfo == null) && (bool)fieldInfo.GetValue(null))
					{
						Install(protos);
						_installed = true;
					}
				}
			}
			catch (Exception ex)
			{
				TransmutationTablePlugin.Log.LogError((object)("建造菜单安装异常: " + ex));
				_installed = true;
			}
		}

		private static void Install(ItemProto[,] protos)
		{
			int length = protos.GetLength(0);
			int length2 = protos.GetLength(1);
			int num = Math.Min(11, length2 - 1);
			if (!SlotControlsUsable(num))
			{
				num = Math.Min(10, length2 - 1);
			}
			ItemProto[] array = (ItemProto[])(object)new ItemProto[3]
			{
				TransmutationTablePlugin.TableProto,
				TransmutationTablePlugin.BoxProto,
				TransmutationTablePlugin.StationProto
			};
			for (int i = 0; i < length; i++)
			{
				for (int j = 0; j < length2; j++)
				{
					if (protos[i, j] != null && Array.IndexOf(array, protos[i, j]) >= 0)
					{
						protos[i, j] = null;
					}
				}
			}
			int num2 = -1;
			int num3 = -1;
			for (int k = 1; k <= Math.Min(9, length - 1); k++)
			{
				if (num2 >= 0)
				{
					break;
				}
				for (int l = 1; l <= num; l++)
				{
					ItemProto val = protos[k, l];
					if (val == null)
					{
						continue;
					}
					try
					{
						if (val.prefabDesc != null && val.prefabDesc.isTank)
						{
							num2 = k;
							num3 = l;
							break;
						}
					}
					catch
					{
					}
				}
			}
			if (num2 < 0)
			{
				num2 = 4;
				TransmutationTablePlugin.Log.LogWarning((object)"[建造菜单] 未找到储液罐锚点,使用兜底分类 4");
			}
			int[] array2 = ((num3 <= 0 || num3 + 3 > num) ? new int[3]
			{
				num - 2,
				num - 1,
				num
			} : new int[3]
			{
				num3 + 1,
				num3 + 2,
				num3 + 3
			});
			int[] array3 = array2;
			foreach (int num4 in array3)
			{
				ItemProto val2 = protos[num2, num4];
				if (val2 == null || Array.IndexOf(array, val2) >= 0)
				{
					continue;
				}
				int num5 = -1;
				int num6 = -1;
				int num7 = 2;
				while (num7 <= 9 && num5 < 0 && num7 < length)
				{
					for (int n = 1; n <= num; n++)
					{
						if (protos[num7, n] == null)
						{
							num5 = num7;
							num6 = n;
							break;
						}
					}
					num7 = ((num7 == 2) ? 1 : (num7 + 1));
				}
				if (num5 < 0)
				{
					TransmutationTablePlugin.Log.LogWarning((object)$"[建造菜单] 无空格安置原版建筑 {((Proto)val2).Name}(原 仓储栏 {num4} 号位),其暂不显示");
					protos[num2, num4] = null;
					continue;
				}
				protos[num5, num6] = val2;
				val2.BuildIndex = num5 * 100 + num6;
				TransmutationTablePlugin.Log.LogInfo((object)string.Format("[建造菜单] 原版「{0}」从 仓储栏 {1} 号位 → {2} {3} 号位", ((Proto)val2).Name, num4, (num5 == 2) ? "物流栏" : ("分类" + num5), num6));
			}
			int num8 = 0;
			ItemProto[] array4 = array;
			foreach (ItemProto val3 in array4)
			{
				if (val3 != null)
				{
					if (num8 >= array2.Length)
					{
						break;
					}
					int num9 = array2[num8++];
					protos[num2, num9] = val3;
					val3.BuildIndex = num2 * 100 + num9;
					TransmutationTablePlugin.Log.LogInfo((object)$"[建造菜单] 「{((Proto)val3).Name}」→ 仓储栏 {num9} 号位 (BuildIndex={val3.BuildIndex})");
				}
			}
			DumpLayout(protos, "安装后", Math.Min(9, length - 1), num);
			TransmutationTablePlugin.Log.LogInfo((object)$"[建造菜单] 安装完成:仓储栏 {array2[0]}/{array2[1]}/{array2[2]} 三格为 转化桌/转化箱/转化站(悬停可看名字)");
		}

		private static bool SlotControlsUsable(int slot)
		{
			try
			{
				UIBuildMenu val = UIRoot.instance?.uiGame?.buildMenu;
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				if (val.childBgs == null || val.childBgs.Length <= slot || (Object)(object)val.childBgs[slot] == (Object)null)
				{
					return false;
				}
				if (val.childIcons == null || val.childIcons.Length <= slot || (Object)(object)val.childIcons[slot] == (Object)null)
				{
					return false;
				}
				if (val.childNumTexts == null || val.childNumTexts.Length <= slot || (Object)(object)val.childNumTexts[slot] == (Object)null)
				{
					return false;
				}
				if (val.childButtons == null || val.childButtons.Length <= slot || (Object)(object)val.childButtons[slot] == (Object)null)
				{
					return false;
				}
				if (val.childTips == null || val.childTips.Length <= slot || (Object)(object)val.childTips[slot] == (Object)null)
				{
					return false;
				}
				return true;
			}
			catch
			{
				return false;
			}
		}

		private static void DumpLayout(ItemProto[,] protos, string phase, int maxCat, int visibleMax)
		{
			try
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("===== 建造菜单布局(" + phase + ")=====");
				for (int i = 1; i <= maxCat; i++)
				{
					StringBuilder stringBuilder2 = new StringBuilder($"分类{i}: ");
					for (int j = 0; j <= visibleMax; j++)
					{
						ItemProto val = protos[i, j];
						stringBuilder2.Append('[').Append(j).Append(']')
							.Append((val == null) ? "—" : ((Proto)val).Name)
							.Append(' ');
					}
					stringBuilder.AppendLine(stringBuilder2.ToString());
				}
				string contents = stringBuilder.ToString();
				File.WriteAllText(Path.Combine(Paths.ConfigPath, "TransmutationTable.buildmenu.log"), contents);
			}
			catch (Exception ex)
			{
				TransmutationTablePlugin.Log.LogWarning((object)("布局转储失败: " + ex.Message));
			}
		}
	}
	internal static class EmcDefaults
	{
		internal static readonly (int id, int emc)[] Prices = new(int, int)[0];
	}
	internal static class Diag
	{
		private static readonly object _lock = new object();

		public static void Error(string where, Exception e)
		{
			TransmutationTablePlugin.Log.LogError((object)(where + ": " + e));
			Write(where, e.ToString() + "\n" + e.StackTrace);
		}

		public static void Warn(string where, string detail)
		{
			TransmutationTablePlugin.Log.LogWarning((object)(where + ": " + detail));
			Write(where, detail);
		}

		private static void Write(string where, string detail)
		{
			try
			{
				lock (_lock)
				{
					File.AppendAllText(Path.Combine(Paths.ConfigPath, "TransmutationTable.errors.log"), $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [{where}]\n{detail}\n\n");
				}
			}
			catch
			{
			}
		}
	}
	public static class EmcSystem
	{
		public class StationCfg
		{
			public bool AutoBuy = true;

			public bool AutoSupply;

			public bool InfiniteDrones = true;

			public List<int> Outputs = new List<int>();
		}

		public class BuildCfg
		{
			public int OutputSpeed = 60;

			public int SprayLevel;
		}

		private static readonly (int id, string[] fallbackNames, double emc)[] Anchors = new(int, string[], double)[30]
		{
			(1001, new string[2] { "iron ore", "铁矿" }, 10.0),
			(1002, new string[2] { "copper ore", "铜矿" }, 10.0),
			(1003, new string[3] { "silicon ore", "硅石", "硅矿" }, 10.0),
			(1004, new string[3] { "titanium ore", "钛石", "钛矿" }, 10.0),
			(1005, new string[3] { "stone", "石矿", "石头" }, 10.0),
			(1006, new string[2] { "coal", "煤" }, 10.0),
			(1007, new string[2] { "crude oil", "原油" }, 20.0),
			(1011, new string[2] { "combustible iceberg", "可燃冰" }, 20.0),
			(1012, new string[2] { "kimberlite", "金伯利" }, 20.0),
			(1013, new string[2] { "fractal silicon", "分形硅" }, 20.0),
			(1014, new string[2] { "grating crystal", "光栅石" }, 20.0),
			(1015, new string[2] { "bamboo crystal", "刺笋结晶" }, 20.0),
			(1016, new string[2] { "unipolar magnet", "单极磁石" }, 80.0),
			(1000, new string[2] { "water", "水" }, 5.0),
			(1099, new string[2] { "sand", "沙土" }, 1.0),
			(0, new string[3] { "wood", "木材", "木头" }, 10.0),
			(1031, new string[1] { "植物燃料" }, 30.0),
			(1122, new string[2] { "antimatter", "反物质" }, 300.0),
			(1208, new string[2] { "critical photon", "临界光子" }, 50.0),
			(1211, new string[1] { "引力透镜" }, 200.0),
			(1608, new string[1] { "反物质胶囊" }, 400.0),
			(1803, new string[1] { "反物质燃料棒" }, 800.0),
			(1804, new string[2] { "湮灭燃料棒", "金色燃料棒" }, 1000.0),
			(2207, new string[1] { "蓄电器(满)" }, 150.0),
			(5201, new string[2] { "黑雾矩阵", "存储单元" }, 400.0),
			(5202, new string[1] { "硅基神经元" }, 400.0),
			(5203, new string[1] { "物质重组器" }, 400.0),
			(5204, new string[1] { "负熵奇点" }, 400.0),
			(5205, new string[2] { "核心素", "虚粒子" }, 400.0),
			(5206, new string[1] { "能量碎片" }, 80.0)
		};

		private static Dictionary<int, double> _emc = new Dictionary<int, double>();

		private static HashSet<int> _locked = new HashSet<int>();

		private static List<ItemProto> _sortedItems;

		public static double Balance;

		private static Dictionary<long, int[]> _outputs = new Dictionary<long, int[]>();

		private static Dictionary<long, StationCfg> _stationCfgs = new Dictionary<long, StationCfg>();

		public const int StationSlotCount = 6;

		private static Dictionary<long, BuildCfg> _buildCfgs = new Dictionary<long, BuildCfg>();

		private static readonly int[] ProlifIds = new int[4] { 0, 1141, 1142, 1143 };

		private static bool _built;

		private static Dictionary<int, double> _importedEmc;

		private static readonly HashSet<int> _learned = new HashSet<int>();

		private static readonly (int id, string[] names)[] AlwaysLearned = new(int, string[])[1] { (1099, new string[2] { "sand", "沙土" }) };

		public static IReadOnlyList<ItemProto> SortedItems
		{
			get
			{
				EnsureBuilt();
				return _sortedItems;
			}
		}

		public static int LearnedCount => _learned.Count;

		private static int LoadPriceFile(string path)
		{
			int num = 0;
			string[] array = File.ReadAllLines(path);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length != 0 && !text.StartsWith("#") && !text.StartsWith("//"))
				{
					string[] array2 = text.Split(new char[3] { '\t', ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
					if (array2.Length >= 2 && int.TryParse(array2[0], out var result) && result > 0 && double.TryParse(array2[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2))
					{
						_emc[result] = Math.Max(0.0, result2);
						_locked.Add(result);
						num++;
					}
				}
			}
			return num;
		}

		public static long MakeKey(int planetId, int entityId)
		{
			return ((long)planetId << 32) | (uint)entityId;
		}

		private static int[] GetOutputArray(long key)
		{
			if (!_outputs.TryGetValue(key, out var value))
			{
				value = new int[4];
				_outputs[key] = value;
			}
			return value;
		}

		public static int GetOutput(long key, int slot)
		{
			return GetOutputArray(key)[slot];
		}

		public static void SetOutput(long key, int slot, int itemId)
		{
			GetOutputArray(key)[slot] = itemId;
		}

		public static int GetBoxOutput(long key)
		{
			return GetOutputArray(key)[3];
		}

		public static void SetBoxOutput(long key, int itemId)
		{
			GetOutputArray(key)[3] = itemId;
		}

		public static StationCfg GetStationCfg(long key)
		{
			if (!_stationCfgs.TryGetValue(key, out var value))
			{
				value = new StationCfg();
				_stationCfgs[key] = value;
			}
			return value;
		}

		public static BuildCfg GetBuildCfg(long key)
		{
			if (!_buildCfgs.TryGetValue(key, out var value))
			{
				value = new BuildCfg();
				_buildCfgs[key] = value;
			}
			return value;
		}

		public static int SprayInc(int level)
		{
			if (level <= 0 || level >= ProlifIds.Length)
			{
				return 0;
			}
			return ((ProtoSet<ItemProto>)(object)LDB.items).Select(ProlifIds[level])?.Ability ?? 0;
		}

		public static double SprayCostPerItem(int level)
		{
			if (level <= 0 || level >= ProlifIds.Length)
			{
				return 0.0;
			}
			ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(ProlifIds[level]);
			if (val == null)
			{
				return 0.0;
			}
			return EmcOf(ProlifIds[level]) / (double)Math.Max(1, val.HpMax);
		}

		public static double SprayCostPerIncPoint(int incPoints)
		{
			if (incPoints <= 0)
			{
				return 0.0;
			}
			for (int i = 1; i < ProlifIds.Length; i++)
			{
				ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(ProlifIds[i]);
				if (val != null && val.Ability == incPoints)
				{
					return EmcOf(ProlifIds[i]) / Math.Max(1.0, (double)val.HpMax * (double)val.Ability);
				}
			}
			ItemProto val2 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(ProlifIds[1]);
			if (val2 == null)
			{
				return 0.0;
			}
			return EmcOf(ProlifIds[1]) / Math.Max(1.0, (double)val2.HpMax * (double)val2.Ability);
		}

		public static double EmcOf(int itemId)
		{
			EnsureBuilt();
			if (!_emc.TryGetValue(itemId, out var value))
			{
				return 1.0;
			}
			return value;
		}

		public static bool HasEmc(int itemId)
		{
			EnsureBuilt();
			return _emc.ContainsKey(itemId);
		}

		private static void ApplyAlwaysLearned()
		{
			(int, string[])[] alwaysLearned = AlwaysLearned;
			for (int i = 0; i < alwaysLearned.Length; i++)
			{
				(int, string[]) tuple = alwaysLearned[i];
				int item = tuple.Item1;
				string[] item2 = tuple.Item2;
				ItemProto val = ((item <= 0) ? null : ((ProtoSet<ItemProto>)(object)LDB.items)?.Select(item));
				if (val == null)
				{
					val = FindItemAny(item2);
				}
				if (val != null)
				{
					_learned.Add(((Proto)val).ID);
				}
			}
		}

		public static bool IsLearned(int itemId)
		{
			if (itemId > 0)
			{
				return _learned.Contains(itemId);
			}
			return false;
		}

		public static bool Learn(int itemId)
		{
			if (itemId <= 0)
			{
				return false;
			}
			if (!_learned.Add(itemId))
			{
				return false;
			}
			if (_learned.Count == 1 || _learned.Count % 20 == 0)
			{
				ManualLogSource log = TransmutationTablePlugin.Log;
				ItemProto obj = ((ProtoSet<ItemProto>)(object)LDB.items).Select(itemId);
				log.LogInfo((object)$"[学习] 已解锁 {((obj != null) ? ((Proto)obj).name : null) ?? itemId.ToString()}(累计 {_learned.Count} 种)");
			}
			return true;
		}

		public static int LearnAll()
		{
			EnsureBuilt();
			int count = _learned.Count;
			foreach (KeyValuePair<int, double> item in _emc)
			{
				if (item.Key > 0)
				{
					_learned.Add(item.Key);
				}
			}
			ItemProto[] array = ((ProtoSet<ItemProto>)(object)LDB.items)?.dataArray ?? Array.Empty<ItemProto>();
			foreach (ItemProto val in array)
			{
				if (val != null && ((Proto)val).ID > 0)
				{
					_learned.Add(((Proto)val).ID);
				}
			}
			int num = _learned.Count - count;
			TransmutationTablePlugin.Log.LogInfo((object)$"[学习] 一键解锁完成:新增 {num} 种(累计 {_learned.Count} 种)");
			return num;
		}

		private static void MigrateLearnedFromPackage()
		{
			try
			{
				Player mainPlayer = GameMain.mainPlayer;
				StorageComponent val = ((mainPlayer != null) ? mainPlayer.package : null);
				if (val?.grids == null)
				{
					return;
				}
				for (int i = 0; i < val.size && i < val.grids.Length; i++)
				{
					if (val.grids[i].itemId > 0 && val.grids[i].count > 0)
					{
						_learned.Add(val.grids[i].itemId);
					}
				}
			}
			catch
			{
			}
		}

		public static void EnsureBuilt()
		{
			if (_built)
			{
				return;
			}
			try
			{
				Build();
				_built = true;
			}
			catch (Exception ex)
			{
				TransmutationTablePlugin.Log.LogError((object)("EMC 价值表构建失败: " + ex));
			}
		}

		private static void Build()
		{
			ItemProto[] dataArray = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray;
			if (dataArray == null)
			{
				throw new InvalidOperationException("LDB 未就绪");
			}
			_emc.Clear();
			_locked.Clear();
			string text = Path.Combine(Paths.ConfigPath, "TransmutationTable.prices.txt");
			try
			{
				if (File.Exists(text))
				{
					int num = LoadPriceFile(text);
					TransmutationTablePlugin.Log.LogInfo((object)$"已加载价格文件 {text}({num} 项,文件值锁定)");
				}
			}
			catch (Exception ex)
			{
				TransmutationTablePlugin.Log.LogWarning((object)("价格文件加载失败(改用内置默认): " + ex.Message));
			}
			(int, int)[] prices = EmcDefaults.Prices;
			for (int i = 0; i < prices.Length; i++)
			{
				var (num2, num3) = prices[i];
				if (!_locked.Contains(num2))
				{
					_emc[num2] = num3;
					_locked.Add(num2);
				}
			}
			int num4 = 0;
			(int, string[], double)[] anchors = Anchors;
			for (int i = 0; i < anchors.Length; i++)
			{
				var (num5, names, value) = anchors[i];
				if (!_emc.ContainsKey(num5) || !_locked.Contains(num5))
				{
					ItemProto val = ((num5 > 0) ? ((ProtoSet<ItemProto>)(object)LDB.items).Select(num5) : null);
					if (val == null)
					{
						val = FindItemAny(names);
					}
					if (val != null && !_emc.ContainsKey(((Proto)val).ID))
					{
						_emc[((Proto)val).ID] = value;
						_locked.Add(((Proto)val).ID);
					}
					else if (val == null)
					{
						num4++;
					}
				}
			}
			if (num4 > 0)
			{
				TransmutationTablePlugin.Log.LogWarning((object)$"EMC 锚点有 {num4}/{Anchors.Length} 个未匹配到物品(价值表仍可由配方推导)");
			}
			RecipeProto[] dataArray2 = ((ProtoSet<RecipeProto>)(object)LDB.recipes).dataArray;
			for (int j = 0; j < 300; j++)
			{
				bool flag = false;
				RecipeProto[] array = dataArray2;
				foreach (RecipeProto val2 in array)
				{
					if (val2?.Items == null || val2.Results == null || val2.Items.Length == 0)
					{
						continue;
					}
					double num6 = 0.0;
					bool flag2 = true;
					for (int k = 0; k < val2.Items.Length; k++)
					{
						int num7 = ((val2.ItemCounts == null || k >= val2.ItemCounts.Length || val2.ItemCounts[k] <= 0) ? 1 : val2.ItemCounts[k]);
						if (_emc.TryGetValue(val2.Items[k], out var value2))
						{
							num6 += value2 * (double)num7;
							continue;
						}
						flag2 = false;
						break;
					}
					if (!flag2)
					{
						continue;
					}
					int num8 = 0;
					int[] resultCounts = val2.ResultCounts;
					foreach (int num9 in resultCounts)
					{
						num8 += num9;
					}
					if (num8 <= 0)
					{
						continue;
					}
					double num10 = num6 / (double)num8;
					for (int m = 0; m < val2.Results.Length; m++)
					{
						int num11 = val2.Results[m];
						if (!_locked.Contains(num11))
						{
							double num12 = num10;
							if (!_emc.TryGetValue(num11, out var value3) || num12 > value3 + 1E-09)
							{
								_emc[num11] = Math.Round(num12, 4);
								flag = true;
							}
						}
					}
				}
				if (!flag)
				{
					break;
				}
			}
			for (int n = 0; n < 300; n++)
			{
				bool flag3 = false;
				RecipeProto[] array = dataArray2;
				foreach (RecipeProto val3 in array)
				{
					if (val3?.Items == null || val3.Results == null || val3.Items.Length == 0)
					{
						continue;
					}
					bool flag4 = true;
					double num13 = 0.0;
					for (int num14 = 0; num14 < val3.Items.Length; num14++)
					{
						int num15 = ((val3.ItemCounts == null || num14 >= val3.ItemCounts.Length || val3.ItemCounts[num14] <= 0) ? 1 : val3.ItemCounts[num14]);
						if (_emc.TryGetValue(val3.Items[num14], out var value4))
						{
							num13 += value4 * (double)num15;
							continue;
						}
						num13 += (double)num15;
						flag4 = false;
					}
					if (flag4)
					{
						continue;
					}
					int num16 = 0;
					int[] resultCounts = val3.ResultCounts;
					foreach (int num17 in resultCounts)
					{
						num16 += num17;
					}
					if (num16 <= 0)
					{
						continue;
					}
					double value5 = num13 / (double)num16;
					for (int num18 = 0; num18 < val3.Results.Length; num18++)
					{
						int num19 = val3.Results[num18];
						if (!_locked.Contains(num19) && !_emc.ContainsKey(num19))
						{
							_emc[num19] = Math.Round(value5, 4);
							flag3 = true;
						}
					}
				}
				if (!flag3)
				{
					break;
				}
			}
			EnsureOwnBuildingPrice(TransmutationTablePlugin.TableProto, TransmutationTablePlugin.TableRecipe);
			EnsureOwnBuildingPrice(TransmutationTablePlugin.BoxProto, TransmutationTablePlugin.BoxRecipe);
			EnsureOwnBuildingPrice(TransmutationTablePlugin.StationProto, TransmutationTablePlugin.StationRecipe);
			foreach (int item in new List<int>(_emc.Keys))
			{
				_emc[item] = Math.Max(1.0, Math.Round(_emc[item]));
			}
			if (!_locked.Contains(2207) && _emc.TryGetValue(2206, out var value6) && (!_emc.TryGetValue(2207, out var value7) || value7 < value6 + 100.0))
			{
				_emc[2207] = Math.Max(1.0, Math.Round(value6 + 100.0));
			}
			if (_importedEmc != null)
			{
				foreach (KeyValuePair<int, double> item2 in _importedEmc)
				{
					if (!_emc.ContainsKey(item2.Key))
					{
						_emc[item2.Key] = item2.Value;
					}
				}
				_importedEmc = null;
			}
			_sortedItems = new List<ItemProto>();
			ItemProto[] array2 = dataArray;
			foreach (ItemProto val4 in array2)
			{
				if (val4 != null && ((Proto)val4).ID > 0)
				{
					_sortedItems.Add(val4);
				}
			}
			_sortedItems.Sort(delegate(ItemProto a, ItemProto b)
			{
				int num20 = ((a.index > 0) ? a.index : int.MaxValue);
				int value8 = ((b.index > 0) ? b.index : int.MaxValue);
				int num21 = num20.CompareTo(value8);
				return (num21 == 0) ? ((Proto)a).ID.CompareTo(((Proto)b).ID) : num21;
			});
			ApplyAlwaysLearned();
			TransmutationTablePlugin.Log.LogInfo((object)$"EMC 价值表构建完成,共 {_emc.Count} 种物品有价");
			DumpItemList();
			DumpRecipeList();
		}

		private static void DumpRecipeList()
		{
			try
			{
				using StreamWriter streamWriter = new StreamWriter(Path.Combine(Paths.ConfigPath, "TransmutationTable.recipes.txt"), append: false);
				streamWriter.WriteLine("ID\t原料\t产物");
				RecipeProto[] dataArray = ((ProtoSet<RecipeProto>)(object)LDB.recipes).dataArray;
				foreach (RecipeProto val in dataArray)
				{
					if (val != null && val.Items != null && val.Results != null)
					{
						List<string> list = new List<string>();
						for (int j = 0; j < val.Items.Length; j++)
						{
							list.Add($"{val.Items[j]}x{((val.ItemCounts == null || j >= val.ItemCounts.Length) ? 1 : val.ItemCounts[j])}");
						}
						List<string> list2 = new List<string>();
						for (int k = 0; k < val.Results.Length; k++)
						{
							list2.Add($"{val.Results[k]}x{((val.ResultCounts == null || k >= val.ResultCounts.Length) ? 1 : val.ResultCounts[k])}");
						}
						streamWriter.WriteLine(string.Format("{0}\t{1}\t{2}", ((Proto)val).ID, string.Join("+", list), string.Join("+", list2)));
					}
				}
			}
			catch (Exception ex)
			{
				TransmutationTablePlugin.Log.LogWarning((object)("配方清单导出失败: " + ex.Message));
			}
		}

		private static void EnsureOwnBuildingPrice(ItemProto proto, RecipeProto recipe)
		{
			if (proto == null || ((Proto)proto).ID <= 0 || _locked.Contains(((Proto)proto).ID) || _emc.ContainsKey(((Proto)proto).ID))
			{
				return;
			}
			double num = 0.0;
			if (recipe?.Items != null)
			{
				for (int i = 0; i < recipe.Items.Length; i++)
				{
					int num2 = ((recipe.ItemCounts == null || i >= recipe.ItemCounts.Length || recipe.ItemCounts[i] <= 0) ? 1 : recipe.ItemCounts[i]);
					num += (_emc.TryGetValue(recipe.Items[i], out var value) ? (value * (double)num2) : ((double)num2));
				}
			}
			_emc[((Proto)proto).ID] = Math.Max(1.0, Math.Round((num > 0.0) ? num : 40.0));
		}

		private static ItemProto FindItemAny(string[] names)
		{
			ItemProto[] array = ((ProtoSet<ItemProto>)(object)LDB.items)?.dataArray;
			if (array == null)
			{
				return null;
			}
			ItemProto[] array2 = array;
			foreach (ItemProto val in array2)
			{
				if (val == null)
				{
					continue;
				}
				foreach (string value in names)
				{
					if ((((Proto)val).Name != null && ((Proto)val).Name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) || (((Proto)val).name != null && ((Proto)val).name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0))
					{
						return val;
					}
				}
			}
			return null;
		}

		private static void DumpItemList()
		{
			try
			{
				using StreamWriter streamWriter = new StreamWriter(Path.Combine(Paths.ConfigPath, "TransmutationTable.items.txt"), append: false);
				streamWriter.WriteLine("ID\t英文名Name\t本地化名name\tEMC");
				ItemProto[] dataArray = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray;
				foreach (ItemProto val in dataArray)
				{
					if (val != null)
					{
						streamWriter.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", ((Proto)val).ID, ((Proto)val).Name, ((Proto)val).name, (((Proto)val).ID > 0 && _emc.ContainsKey(((Proto)val).ID)) ? _emc[((Proto)val).ID].ToString("0.####") : "-"));
					}
				}
			}
			catch (Exception ex)
			{
				TransmutationTablePlugin.Log.LogWarning((object)("物品清单导出失败: " + ex.Message));
			}
		}

		public static void Export(BinaryWriter w)
		{
			EnsureBuilt();
			w.Write(9);
			w.Write(Balance);
			w.Write(_emc.Count);
			foreach (KeyValuePair<int, double> item in _emc)
			{
				w.Write(item.Key);
				w.Write(item.Value);
			}
			List<KeyValuePair<long, int[]>> list = new List<KeyValuePair<long, int[]>>();
			foreach (KeyValuePair<long, int[]> output in _outputs)
			{
				if (output.Value != null && (output.Value[0] != 0 || output.Value[1] != 0 || output.Value[2] != 0 || output.Value[3] != 0))
				{
					list.Add(output);
				}
			}
			w.Write(list.Count);
			foreach (KeyValuePair<long, int[]> item2 in list)
			{
				w.Write(item2.Key);
				for (int i = 0; i < 4; i++)
				{
					w.Write(item2.Value[i]);
				}
			}
			List<KeyValuePair<long, StationCfg>> list2 = new List<KeyValuePair<long, StationCfg>>();
			foreach (KeyValuePair<long, StationCfg> stationCfg in _stationCfgs)
			{
				if (stationCfg.Value != null && (stationCfg.Value.AutoBuy || stationCfg.Value.AutoSupply || stationCfg.Value.Outputs.Count > 0))
				{
					list2.Add(stationCfg);
				}
			}
			w.Write(list2.Count);
			foreach (KeyValuePair<long, StationCfg> item3 in list2)
			{
				StationCfg value = item3.Value;
				w.Write(item3.Key);
				w.Write(value.AutoBuy);
				w.Write(value.AutoSupply);
				w.Write(value.InfiniteDrones);
				w.Write(value.Outputs.Count);
				foreach (int output2 in value.Outputs)
				{
					w.Write(output2);
				}
			}
			List<KeyValuePair<long, BuildCfg>> list3 = new List<KeyValuePair<long, BuildCfg>>();
			foreach (KeyValuePair<long, BuildCfg> buildCfg in _buildCfgs)
			{
				if (buildCfg.Value != null && (buildCfg.Value.OutputSpeed != 60 || buildCfg.Value.SprayLevel != 0))
				{
					list3.Add(buildCfg);
				}
			}
			w.Write(list3.Count);
			foreach (KeyValuePair<long, BuildCfg> item4 in list3)
			{
				w.Write(item4.Key);
				w.Write(item4.Value.OutputSpeed);
				w.Write(item4.Value.SprayLevel);
			}
			w.Write(_learned.Count);
			foreach (int item5 in _learned)
			{
				w.Write(item5);
			}
		}

		public static void Import(BinaryReader r)
		{
			int num = r.ReadInt32();
			Balance = r.ReadDouble();
			int num2 = r.ReadInt32();
			Dictionary<int, double> dictionary = new Dictionary<int, double>();
			for (int i = 0; i < num2; i++)
			{
				int num3 = r.ReadInt32();
				double num4 = r.ReadDouble();
				if (num3 > 0 && num4 > 0.0)
				{
					dictionary[num3] = num4;
				}
			}
			_outputs.Clear();
			if (num >= 2)
			{
				int num5 = r.ReadInt32();
				int num6 = ((num >= 3) ? 4 : 3);
				for (int j = 0; j < num5; j++)
				{
					long key = r.ReadInt64();
					int[] array = new int[4];
					for (int k = 0; k < num6; k++)
					{
						array[k] = r.ReadInt32();
					}
					_outputs[key] = array;
				}
			}
			else
			{
				for (int l = 0; l < 3; l++)
				{
					r.ReadInt32();
				}
			}
			_stationCfgs.Clear();
			if (num >= 6)
			{
				int num7 = r.ReadInt32();
				for (int m = 0; m < num7; m++)
				{
					StationCfg stationCfg = GetStationCfg(r.ReadInt64());
					stationCfg.AutoBuy = r.ReadBoolean();
					stationCfg.AutoSupply = r.ReadBoolean();
					if (num >= 7)
					{
						stationCfg.InfiniteDrones = r.ReadBoolean();
					}
					int num8 = r.ReadInt32();
					stationCfg.Outputs.Clear();
					for (int n = 0; n < num8; n++)
					{
						int num9 = r.ReadInt32();
						if (num9 > 0)
						{
							stationCfg.Outputs.Add(num9);
						}
					}
				}
			}
			_buildCfgs.Clear();
			if (num >= 8)
			{
				int num10 = r.ReadInt32();
				for (int num11 = 0; num11 < num10; num11++)
				{
					BuildCfg buildCfg = GetBuildCfg(r.ReadInt64());
					buildCfg.OutputSpeed = r.ReadInt32();
					buildCfg.SprayLevel = r.ReadInt32();
				}
			}
			else if (num >= 4)
			{
				int num12 = r.ReadInt32();
				int num13 = ((num >= 5) ? 6 : 5);
				for (int num14 = 0; num14 < num12; num14++)
				{
					StationCfg stationCfg2 = GetStationCfg(r.ReadInt64());
					for (int num15 = 0; num15 < num13; num15++)
					{
						int num16 = r.ReadInt32();
						int num17 = r.ReadInt32();
						switch (num16)
						{
						case 1:
							stationCfg2.AutoBuy = true;
							break;
						case 2:
							if (num17 > 0 && !stationCfg2.Outputs.Contains(num17))
							{
								stationCfg2.Outputs.Add(num17);
							}
							break;
						}
					}
				}
			}
			_learned.Clear();
			if (num >= 9)
			{
				int num18 = r.ReadInt32();
				for (int num19 = 0; num19 < num18; num19++)
				{
					int num20 = r.ReadInt32();
					if (num20 > 0)
					{
						_learned.Add(num20);
					}
				}
			}
			if (num < 9)
			{
				MigrateLearnedFromPackage();
			}
			_importedEmc = dictionary;
			EnsureBuilt();
			ApplyAlwaysLearned();
			TransmutationTablePlugin.Log.LogInfo((object)$"EMC 数据读取完成,余额 {Balance:F1}");
		}

		public static void ResetPlayerData()
		{
			Balance = 0.0;
			_outputs.Clear();
			_stationCfgs.Clear();
			_buildCfgs.Clear();
			_learned.Clear();
			ApplyAlwaysLearned();
		}
	}
	public static class EmcWindow
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static WindowFunction <0>__DrawWindow;
		}

		private static bool _open;

		private static int _tableEntityId;

		private static Rect _rect = new Rect(60f, 40f, 1140f, 820f);

		private static Vector2 _scroll;

		private static Vector2 _pickerScroll;

		private static float _measuredScrollTop = 320f;

		private static int _pickingLane = -1;

		private static string _hoverText = "";

		private static bool _pendingClose;

		private static bool _dragging;

		private static bool _resizing;

		private static Vector2 _resizeStartMouse;

		private static Vector2 _resizeStartSize;

		private static readonly List<Action> _pending = new List<Action>();

		private static Color ColPanel = new Color(0.043f, 0.075f, 0.11f, 0.96f);

		private static Color ColPanelHeader = new Color(0.09f, 0.15f, 0.21f, 1f);

		private static Color ColBorder = new Color(0.275f, 0.415f, 0.545f, 1f);

		private static Color ColBorderDim = new Color(0.165f, 0.255f, 0.34f, 1f);

		private static Color ColSlot = new Color(0.024f, 0.043f, 0.063f, 1f);

		private static Color ColSlotBorder = new Color(0.22f, 0.33f, 0.43f, 1f);

		private static Color ColCyan = new Color(0.42f, 0.83f, 1f);

		private static Color ColText = new Color(0.87f, 0.92f, 0.95f);

		private static Color ColDim = new Color(0.545f, 0.655f, 0.73f);

		private static Color ColGold = new Color(1f, 0.85f, 0.38f);

		private static Color ColGreen = new Color(0.47f, 0.93f, 0.55f);

		private static Color ColRed = new Color(1f, 0.42f, 0.36f);

		private static Color ColBtn = new Color(0.098f, 0.165f, 0.235f, 1f);

		private static Color ColBtnHover = new Color(0.16f, 0.29f, 0.4f, 1f);

		private static Color ColSection = new Color(0.33f, 0.53f, 0.68f, 1f);

		private static GUIStyle _window;

		private static GUIStyle _title;

		private static GUIStyle _stat;

		private static GUIStyle _label;

		private static GUIStyle _labelDim;

		private static GUIStyle _btn;

		private static GUIStyle _btnSmall;

		private static GUIStyle _priceOk;

		private static GUIStyle _priceNo;

		private static GUIStyle _section;

		private static GUIStyle _cellText;

		private static Texture2D _texWin;

		private static Texture2D _texHeader;

		private static Texture2D _texBtn;

		private static Texture2D _texBtnHover;

		private static Texture2D _texSlot;

		private static Texture2D _texFlat;

		private static Texture2D _texDivider;

		private static Font _gameFont;

		private static bool _stylesReady;

		private const float CellSize = 76f;

		public static bool IsOpen => _open;

		private static void Defer(Action a)
		{
			_pending.Add(a);
		}

		public static void Open(int entityId)
		{
			_open = true;
			_tableEntityId = entityId;
			_pickingLane = -1;
		}

		public static void Close()
		{
			_open = false;
			_tableEntityId = 0;
			_pickingLane = -1;
		}

		public static void OnGUIWindow()
		{
			if (!_open)
			{
				return;
			}
			try
			{
				DrawOnGUI();
			}
			catch (Exception e)
			{
				Diag.Error("EMC窗口", e);
				Close();
			}
		}

		private static void DrawOnGUI()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Invalid comparison between Unknown and I4
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Invalid comparison between Unknown and I4
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Invalid comparison between Unknown and I4
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Invalid comparison between Unknown and I4
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Invalid comparison between Unknown and I4
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Expected O, but got Unknown
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Invalid comparison between Unknown and I4
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)GameMain.instance == (Object)null || GameMain.instance.isMenuDemo || GameMain.data == null || GameMain.data.localPlanet == null)
			{
				Close();
				return;
			}
			PlanetFactory factory = GameMain.data.localPlanet.factory;
			if (factory == null || _tableEntityId <= 0 || _tableEntityId >= factory.entityPool.Length || factory.entityPool[_tableEntityId].id != _tableEntityId)
			{
				Close();
				return;
			}
			int protoId = factory.entityPool[_tableEntityId].protoId;
			if (protoId != TransmutationTablePlugin.TableItemId && protoId != TransmutationTablePlugin.BoxItemId && protoId != TransmutationTablePlugin.StationItemId)
			{
				Close();
				return;
			}
			if (Event.current.isKey && (int)Event.current.keyCode == 27 && (int)Event.current.type == 4)
			{
				Close();
				Event.current.Use();
				return;
			}
			EnsureStyles();
			Event current = Event.current;
			if (_resizing)
			{
				if ((int)current.type == 3 && current.button == 0)
				{
					((Rect)(ref _rect)).width = Mathf.Clamp(_resizeStartSize.x + (current.mousePosition.x - _resizeStartMouse.x), 760f, (float)(Screen.width - 40));
					((Rect)(ref _rect)).height = Mathf.Clamp(_resizeStartSize.y + (current.mousePosition.y - _resizeStartMouse.y), 600f, (float)(Screen.height - 60));
					current.Use();
				}
				else if ((int)current.type == 1 && current.button == 0)
				{
					_resizing = false;
					current.Use();
				}
			}
			else if (_dragging)
			{
				if ((int)current.type == 3 && current.button == 0)
				{
					((Rect)(ref _rect)).x = ((Rect)(ref _rect)).x + current.delta.x;
					((Rect)(ref _rect)).y = ((Rect)(ref _rect)).y + current.delta.y;
					current.Use();
				}
				else if ((int)current.type == 1 && current.button == 0)
				{
					_dragging = false;
					current.Use();
				}
			}
			Rect rect = _rect;
			object obj = <>O.<0>__DrawWindow;
			if (obj == null)
			{
				WindowFunction val = DrawWindow;
				<>O.<0>__DrawWindow = val;
				obj = (object)val;
			}
			_rect = GUI.Window(32362, rect, (WindowFunction)obj, "", _window);
		}

		private static Texture2D MakeTex(int w, int h, Color fill, Color border, int borderPx)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h, (TextureFormat)4, false);
			((Object)val).hideFlags = (HideFlags)61;
			Color[] array = (Color[])(object)new Color[w * h];
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					bool flag = j < borderPx || i < borderPx || j >= w - borderPx || i >= h - borderPx;
					array[i * w + j] = (flag ? border : fill);
				}
			}
			val.SetPixels(array);
			val.Apply(false, false);
			return val;
		}

		private static Texture2D MakeFlat(Color c)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			((Object)val).hideFlags = (HideFlags)61;
			val.SetPixels((Color[])(object)new Color[4] { c, c, c, c });
			val.Apply(false, false);
			return val;
		}

		private static Font GameFont()
		{
			if ((Object)(object)_gameFont != (Object)null)
			{
				return _gameFont;
			}
			try
			{
				UIRoot instance = UIRoot.instance;
				object gameFont;
				if (instance == null)
				{
					gameFont = null;
				}
				else
				{
					UIGame uiGame = instance.uiGame;
					if (uiGame == null)
					{
						gameFont = null;
					}
					else
					{
						UIInventoryWindow inventoryWindow = uiGame.inventoryWindow;
						if (inventoryWindow == null)
						{
							gameFont = null;
						}
						else
						{
							Text titleText = inventoryWindow.titleText;
							gameFont = ((titleText != null) ? titleText.font : null);
						}
					}
				}
				_gameFont = (Font)gameFont;
			}
			catch
			{
			}
			if ((Object)(object)_gameFont == (Object)null)
			{
				_gameFont = Font.CreateDynamicFontFromOSFont("Microsoft YaHei", 14);
			}
			return _gameFont;
		}

		private static void EnsureStyles()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: 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_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected O, but got Unknown
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Expected O, but got Unknown
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Expected O, but got Unknown
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Expected O, but got Unknown
			//IL_026f: Expected O, but got Unknown
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Expected O, but got Unknown
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Expected O, but got Unknown
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Expected O, but got Unknown
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Expected O, but got Unknown
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Expected O, but got Unknown
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			if (!_stylesReady)
			{
				Font font = GameFont();
				_texWin = MakeTex(24, 24, ColPanel, ColBorder, 2);
				_texHeader = MakeFlat(ColPanelHeader);
				_texBtn = MakeTex(12, 12, ColBtn, ColBorderDim, 1);
				_texBtnHover = MakeTex(12, 12, ColBtnHover, ColCyan, 1);
				_texSlot = MakeTex(12, 12, ColSlot, ColSlotBorder, 1);
				_texFlat = MakeFlat(new Color(1f, 1f, 1f, 1f));
				_texDivider = MakeFlat(new Color(ColBorder.r, ColBorder.g, ColBorder.b, 0.55f));
				_window = new GUIStyle
				{
					border = new RectOffset(6, 6, 6, 6),
					padding = new RectOffset(24, 24, 16, 18),
					font = font
				};
				_window.normal.background = _texWin;
				_title = new GUIStyle
				{
					fontSize = 32,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)3,
					font = font
				};
				_title.normal.textColor = ColCyan;
				_stat = new GUIStyle
				{
					fontSize = 30,
					alignment = (TextAnchor)3,
					font = font
				};
				_stat.normal.textColor = ColGold;
				_label = new GUIStyle
				{
					fontSize = 24,
					alignment = (TextAnchor)3,
					font = font,
					wordWrap = true
				};
				_label.normal.textColor = ColText;
				_labelDim = new GUIStyle(_label);
				_labelDim.fontSize = 20;
				_labelDim.normal.textColor = ColDim;
				_section = new GUIStyle
				{
					fontSize = 26,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)3,
					font = font
				};
				_section.normal.textColor = ColSection;
				_btn = new GUIStyle
				{
					fontSize = 24,
					alignment = (TextAnchor)4,
					font = font,
					border = new RectOffset(3, 3, 3, 3),
					padding = new RectOffset(8, 8, 4, 4)
				};
				_btn.normal.background = _texBtn;
				_btn.normal.textColor = ColText;
				_btn.hover.background = _texBtnHover;
				_btn.hover.textColor = Color.white;
				_btn.active.background = _texBtnHover;
				_btn.active.textColor = ColCyan;
				_btnSmall = new GUIStyle(_btn);
				_btnSmall.fontSize = 22;
				_btnSmall.padding = new RectOffset(6, 6, 3, 3);
				_priceOk = new GUIStyle
				{
					fontSize = 17,
					alignment = (TextAnchor)8,
					font = font
				};
				_priceOk.normal.textColor = ColGreen;
				_priceNo = new GUIStyle(_priceOk);
				_priceNo.normal.textColor = ColRed;
				_cellText = new GUIStyle
				{
					fontSize = 22,
					alignment = (TextAnchor)3,
					font = font
				};
				_cellText.normal.textColor = ColText;
				_stylesReady = true;
			}
		}

		private static void DrawFlat(Rect r, Texture2D tex)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (((Rect)(ref r)).width > 0f && ((Rect)(ref r)).height > 0f)
			{
				GUI.DrawTexture(r, (Texture)(object)tex, (ScaleMode)0);
			}
		}

		private static void DrawDivider(float width)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			DrawFlat(GUILayoutUtility.GetRect(width, 2f), _texDivider);
		}

		private static void DrawSection(string text)
		{
			GUILayout.Space(6f);
			GUILayout.Label(text, _section, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) });
			DrawDivider(((Rect)(ref _rect)).width - 28f);
			GUILayout.Space(2f);
		}

		private static void Hover(string text)
		{
			if (!string.IsNullOrEmpty(text))
			{
				_hoverText = text;
			}
		}

		private static void DrawWindow(int id)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Expected O, but got Unknown
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Expected O, but got Unknown
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_0410: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0476: Expected O, but got Unknown
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			//IL_0513: Unknown result type (might be due to invalid IL or missing references)
			//IL_0481: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e76: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e6d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e64: Unknown result type (might be due to invalid IL or missing references)
			//IL_129e: Unknown result type (might be due to invalid IL or missing references)
			//IL_12a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_12a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_12ac: Invalid comparison between Unknown and I4
			//IL_0e9a: Unknown result type (might be due to invalid IL or missing references)
			//IL_12ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_1304: Unknown result type (might be due to invalid IL or missing references)
			//IL_1309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e91: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e88: Unknown result type (might be due to invalid IL or missing references)
			//IL_1388: Unknown result type (might be due to invalid IL or missing references)
			//IL_1237: Unknown result type (might be due to invalid IL or missing references)
			//IL_124f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1254: Unknown result type (might be due to invalid IL or missing references)
			//IL_139e: Unknown result type (might be due to invalid IL or missing references)
			//IL_13d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_13e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_13ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_13f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_1401: Expected O, but got Unknown
			//IL_1402: Unknown result type (might be due to invalid IL or missing references)
			//IL_140c: Unknown result type (might be due to invalid IL or missing references)
			//IL_1427: Unknown result type (might be due to invalid IL or missing references)
			//IL_142c: Unknown result type (might be due to invalid IL or missing references)
			//IL_1431: Unknown result type (might be due to invalid IL or missing references)
			//IL_144a: Unknown result type (might be due to invalid IL or missing references)
			//IL_144f: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ed: Invalid comparison between Unknown and I4
			//IL_0a86: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a8c: Invalid comparison between Unknown and I4
			_hoverText = "";
			Event current = Event.current;
			GUILayout.BeginArea(new Rect(0f, 0f, ((Rect)(ref _rect)).width, ((Rect)(ref _rect)).height));
			GameData data = GameMain.data;
			PlanetFactory val = ((data == null) ? null : data.localPlanet?.factory);
			string text = "转 化 桌";
			if (val != null && _tableEntityId > 0 && _tableEntityId < val.entityPool.Length)
			{
				int protoId = val.entityPool[_tableEntityId].protoId;
				if (protoId == TransmutationTablePlugin.BoxItemId)
				{
					text = "转 化 箱";
				}
				else if (protoId == TransmutationTablePlugin.StationItemId)
				{
					text = "转 化 站";
				}
			}
			Rect rect = GUILayoutUtility.GetRect(((Rect)(ref _rect)).width - 48f, 62f);
			DrawFlat(rect, _texHeader);
			ItemProto val2 = ((val != null && _tableEntityId > 0 && _tableEntityId < val.entityPool.Length) ? ((ProtoSet<ItemProto>)(object)LDB.items).Select((int)val.entityPool[_tableEntityId].protoId) : null);
			if (val2 != null)
			{
				DrawIcon(val2, ((Rect)(ref rect)).x, ((Rect)(ref rect)).y + 9f, 44f, 44f);
			}
			GUI.Label(new Rect(((Rect)(ref rect)).x + 58f, ((Rect)(ref rect)).y + 10f, ((Rect)(ref rect)).width - 140f, 44f), text, _title);
			Rect r = default(Rect);
			((Rect)(ref r))..ctor(((Rect)(ref rect)).x + ((Rect)(ref rect)).width - 54f, ((Rect)(ref rect)).y + 11f, 44f, 40f);
			bool flag = ((Rect)(ref r)).Contains(current.mousePosition);
			DrawFlat(r, flag ? _texBtnHover : _texBtn);
			GUI.Label(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 2f, ((Rect)(ref r)).width, ((Rect)(ref r)).height), "✕", new GUIStyle(_labelDim)
			{
				alignment = (TextAnchor)4,
				fontSize = 24
			});
			if ((int)current.type == 0 && ((Rect)(ref r)).Contains(current.mousePosition) && current.button == 0)
			{
				current.Use();
				_pendingClose = true;
			}
			else if ((int)current.type == 0 && current.button == 0 && current.mousePosition.y <= ((Rect)(ref rect)).y + ((Rect)(ref rect)).height)
			{
				_dragging = true;
				current.Use();
			}
			GUILayout.Space(8f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("EMC 储量", _labelDim, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
			GUILayout.Label(EmcSystem.Balance.ToString("N1"), _stat, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) });
			GUILayout.FlexibleSpace();
			GUILayout.Label("全宇宙共享", _labelDim, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			DrawDivider(((Rect)(ref _rect)).width - 28f);
			GUILayout.Space(6f);
			Rect rect2 = GUILayoutUtility.GetRect(((Rect)(ref _rect)).width - 48f, 54f);
			bool flag2 = ((Rect)(ref rect2)).Contains(current.mousePosition);
			DrawFlat(rect2, flag2 ? _texBtnHover : _texBtn);
			GUI.Label(new Rect(((Rect)(ref rect2)).x, ((Rect)(ref rect2)).y + 10f, ((Rect)(ref rect2)).width, 36f), "⇦  存入背包中全部物品(按 EMC 折算)", new GUIStyle(_cellText)
			{
				alignment = (TextAnchor)4
			});
			if ((int)current.type == 0 && ((Rect)(ref rect2)).Contains(current.mousePosition) && current.button == 0)
			{
				current.Use();
				StoreAllFromPackage();
			}
			GUILayout.Space(4f);
			if (GameMain.sandboxToolsEnabled)
			{
				Rect rect3 = GUILayoutUtility.GetRect(((Rect)(ref _rect)).width - 48f, 44f);
				bool flag3 = ((Rect)(ref rect3)).Contains(current.mousePosition);
				DrawFlat(rect3, flag3 ? _texBtnHover : _texBtn);
				GUI.Label(new Rect(((Rect)(ref rect3)).x, ((Rect)(ref rect3)).y + 6f, ((Rect)(ref rect3)).width, 32f), $"一键解锁全部物品(沙盒)\u3000当前已学习 {EmcSystem.LearnedCount} 种", new GUIStyle(_cellText)
				{
					alignment = (TextAnchor)4
				});
				if ((int)current.type == 0 && ((Rect)(ref rect3)).Contains(current.mousePosition) && current.button == 0)
				{
					current.Use();
					Defer(delegate
					{
						int num11 = EmcSystem.LearnAll();
						UIRealtimeTip.Popup((num11 > 0) ? $"已解锁 {num11} 种物品,现在全部可兑换" : "所有物品都已解锁", true, 0);
					});
				}
			}
			else
			{
				GUILayout.Label($"已学习 {EmcSystem.LearnedCount} 种物品:投入过一次的物品才能兑换(沙盒可一键解锁)", _labelDim, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) });
			}
			GameData data2 = GameMain.data;
			PlanetFactory val3 = ((data2 == null) ? null : data2.localPlanet?.factory);
			FractionatorComponent f = default(FractionatorComponent);
			bool flag4 = val3 != null && TablePatches.TryGetTableBinding(val3, _tableEntityId, out f);
			long configKey = ((val3 != null) ? EmcSystem.MakeKey(val3.planet.id, _tableEntityId) : 0);
			short num = val3?.entityPool[_tableEntityId].protoId ?? 0;
			bool flag5 = num == TransmutationTablePlugin.BoxItemId;
			bool flag6 = num == TransmutationTablePlugin.StationItemId;
			if (flag5)
			{
				DrawSection("箱体配置");
				GUILayout.Label("箱内物品自动收购为 EMC:用分拣器送入即可,无需配置。", _labelDim, Array.Empty<GUILayoutOption>());
				StorageComponent boxStorage = GetBoxStorage(val3);
				if (boxStorage != null)
				{
					int num2 = 0;
					for (int num3 = 0; num3 < boxStorage.size && num3 < boxStorage.grids.Length; num3++)
					{
						num2 += boxStorage.grids[num3].count;
					}
					GUILayout.Label($"箱内剩余:{num2} 个物品(分拣器送入的物品会被立即收购)", _label, Array.Empty<GUILayoutOption>());
				}
				int boxOutput = EmcSystem.GetBoxOutput(configKey);
				GUILayout.Space(2f);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("输出物品:", _label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
				if (boxOutput > 0)
				{
					ItemProto val4 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(boxOutput);
					Hover("箱内自动备货 1 组,分拣器取走即补");
					GUILayout.Label($"{((val4 != null) ? ((Proto)val4).name : null) ?? boxOutput.ToString()}\u3000{EmcSystem.EmcOf(boxOutput):N1}/个", _label, Array.Empty<GUILayoutOption>());
				}
				else
				{
					GUILayout.Label("<未配置>", _labelDim, Array.Empty<GUILayoutOption>());
				}
				GUILayout.FlexibleSpace();
				if (GUILayout.Button("选择", _btnSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }))
				{
					Defer(delegate
					{
						_pickingLane = ((_pickingLane == 200) ? (-1) : 200);
					});
				}
				if (boxOutput > 0 && GUILayout.Button("停止", _btnSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }))
				{
					Defer(delegate
					{
						EmcSystem.SetBoxOutput(configKey, 0);
					});
				}
				GUILayout.EndHorizontal();
				DrawBuildParams(configKey);
			}
			else if (flag6)
			{
				StationComponent[] array = val3?.transport?.stationPool;
				int num4 = val3?.entityPool[_tableEntityId].stationId ?? 0;
				StationComponent val5 = ((array != null && num4 > 0 && num4 < array.Length) ? array[num4] : null);
				if (val5 == null)
				{
					GUILayout.Label("<站点组件未就绪>", _labelDim, Array.Empty<GUILayoutOption>());
				}
				else
				{
					EmcSystem.StationCfg cfg = EmcSystem.GetStationCfg(configKey);
					DrawSection("输入端口(自动收购)");
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Label(cfg.AutoBuy ? "● 收购中" : "○ 已关闭", _label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(300f) });
					GUILayout.FlexibleSpace();
					if (GUILayout.Button(cfg.AutoBuy ? "关闭收购" : "开启收购", _btnSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(190f) }))
					{
						Defer(delegate
						{
							cfg.AutoBuy = !cfg.AutoBuy;
						});
					}
					GUILayout.EndHorizontal();
					if (cfg.AutoBuy && val5.storage != null)
					{
						StringBuilder stringBuilder = new StringBuilder();
						for (int num5 = 0; num5 < val5.storage.Length; num5++)
						{
							if (val5.storage[num5].itemId > 0 && (int)val5.storage[num5].localLogic == 2)
							{
								ItemProto obj = ((ProtoSet<ItemProto>)(object)LDB.items).Select(val5.storage[num5].itemId);
								stringBuilder.Append(((obj != null) ? ((Proto)obj).name : null) ?? val5.storage[num5].itemId.ToString()).Append("、");
							}
						}
						GUILayout.Label((stringBuilder.Length == 0) ? "\u3000等待星球上有塔供应物品…" : ("\u3000收购清单:" + stringBuilder.ToString(0, stringBuilder.Length - 1)), _labelDim, Array.Empty<GUILayoutOption>());
					}
					DrawSection("输出端口");
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Label(cfg.AutoSupply ? "● 自动满足需求" : "○ 手动供应", _label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(320f) });
					GUILayout.FlexibleSpace();
					if (GUILayout.Button(cfg.AutoSupply ? "切换为手动" : "切换为自动", _btnSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) }))
					{
						Defer(delegate
						{
							cfg.AutoSupply = !cfg.AutoSupply;
						});
					}
					GUILayout.EndHorizontal();
					if (cfg.AutoSupply && val5.storage != null)
					{
						StringBuilder stringBuilder2 = new StringBuilder();
						for (int num6 = 0; num6 < val5.storage.Length; num6++)
						{
							if (val5.storage[num6].itemId > 0 && (int)val5.storage[num6].localLogic == 1)
							{
								ItemProto obj2 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(val5.storage[num6].itemId);
								stringBuilder2.Append(((obj2 != null) ? ((Proto)obj2).name : null) ?? val5.storage[num6].itemId.ToString()).Append("、");
							}
						}
						GUILayout.Label((stringBuilder2.Length == 0) ? "\u3000等待星球上有塔发出需求…" : ("\u3000供应清单:" + stringBuilder2.ToString(0, stringBuilder2.Length - 1)), _labelDim, Array.Empty<GUILayoutOption>());
					}
					for (int num7 = 0; num7 < cfg.Outputs.Count; num7++)
					{
						ItemProto val6 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(cfg.Outputs[num7]);
						string text2 = (EmcSystem.HasEmc(cfg.Outputs[num7]) ? $"{EmcSystem.EmcOf(cfg.Outputs[num7]):N1}/个" : "(临时价1/个)");
						GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
						GUILayout.Label($"\u3000端口{num7 + 1}", _labelDim, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) });
						GUILayout.Label((((val6 != null) ? ((Proto)val6).name : null) ?? cfg.Outputs[num7].ToString()) ?? "", _label, Array.Empty<GUILayoutOption>());
						GUILayout.Label(text2, _priceOk, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) });
						int idx = num7;
						if (GUILayout.Button("移除", _btnSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }))
						{
							Defer(delegate
							{
								cfg.Outputs.RemoveAt(idx);
							});
						}
						GUILayout.EndHorizontal();
					}
					if (cfg.Outputs.Count < 6 && GUILayout.Button("+ 添加输出端口", _btn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(48f) }))
					{
						Defer(delegate
						{
							_pickingLane = ((_pickingLane == 300) ? (-1) : 300);
						});
					}
					DrawBuildParams(configKey);
					DrawSection("无人机");
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Label("无限小飞机:", _label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) });
					if (GUILayout.Button(cfg.InfiniteDrones ? "✓ 开(机队秒回满)" : "✗ 关(普通模式)", _btn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(330f) }))
					{
						cfg.InfiniteDrones = !cfg.InfiniteDrones;
					}
					object arg = val5.workDroneCount + val5.idleDroneCount;
					DroneData[] workDroneDatas = val5.workDroneDatas;
					GUILayout.Label($"当前 {arg}/{((workDroneDatas != null) ? workDroneDatas.Length : 0)} 架", _labelDim, Array.Empty<GUILayoutOption>());
					GUILayout.EndHorizontal();
					GUILayout.Label("\u3000开:无人机被打掉也立刻补满(无限)\u3000关:送完货自动回站,仅被摧毁才减少,拆除不返还", _labelDim, Array.Empty<GUILayoutOption>());
					GUILayout.Label($"本级流水:供应支出 {TablePatches.StationSupplySpent:N0} / 收购收入 {TablePatches.StationBuyEarned:N0} EMC(本次游戏累计)", _labelDim, Array.Empty<GUILayoutOption>());
				}
			}
			else
			{
				DrawSection("传送带端口");
				for (int num8 = 0; num8 < 3; num8++)
				{
					int num9 = num8 switch
					{
						1 => f.belt1, 
						0 => f.belt0, 
						_ => f.belt2, 
					};
					bool flag7 = num8 switch
					{
						1 => f.isOutput1, 
						0 => f.isOutput0, 
						_ => f.isOutput2, 
					};
					bool flag8 = flag4 && num9 > 0 && num9 < val3.cargoTraffic.beltPool.Length && val3.cargoTraffic.beltPool[num9].id == num9;
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Label($"端口{num8 + 1}", _label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) });
					if (!flag8)
					{
						GUILayout.Label("<未连接传送带>", _labelDim, Array.Empty<GUILayoutOption>());
					}
					else if (!flag7)
					{
						Hover("输入带:到达物品自动收购为 EMC");
						GUILayout.Label($"输入带 #{num9}(自动收购)", _labelDim, Array.Empty<GUILayoutOption>());
					}
					else
					{
						GUILayout.Label($"输出带 #{num9}", _label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) });
						int output = EmcSystem.GetOutput(configKey, num8);
						if (output > 0)
						{
							ItemProto val7 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(output);
							Hover($"{((val7 != null) ? ((Proto)val7).name : null)} — {EmcSystem.EmcOf(output):N1} EMC/个");
							GUILayout.Label((((val7 != null) ? ((Proto)val7).name : null) ?? output.ToString()) ?? "", _label, Array.Empty<GUILayoutOption>());
							GUILayout.Label($"{EmcSystem.EmcOf(output):N1}/个", _priceOk, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) });
						}
						else
						{
							GUILayout.Label("<未配置输出物品>", _labelDim, Array.Empty<GUILayoutOption>());
						}
						GUILayout.FlexibleSpace();
						int slotIdx = num8;
						if (GUILayout.Button("选择", _btnSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }))
						{
							Defer(delegate
							{
								_pickingLane = ((_pickingLane == slotIdx) ? (-1) : slotIdx);
							});
						}
						if (output > 0 && GUILayout.Button("停止", _btnSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }))
						{
							Defer(delegate
							{
								EmcSystem.SetOutput(configKey, slotIdx, 0);
							});
						}
					}
					GUILayout.EndHorizontal();
				}
				DrawBuildParams(configKey);
				GUILayout.Label("提示:输出带 = 从端口往外拉的带;输入带 = 甩头插进端口、箭头指向桌子的带。配置每栋建筑独立。", _labelDim, Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(4f);
			GUILayout.Label($"tick={TablePatches.TickCount}\u3000收购={TablePatches.PickedTotal}\u3000输出成功={TablePatches.InsertOkTotal}\u3000带满={TablePatches.InsertFailTotal}\u3000EMC不足={TablePatches.NoEmcSkipTotal}", _labelDim, Array.Empty<GUILayoutOption>());
			if (_pickingLane >= 0)
			{
				DrawSection("选择物品");
				string text3;
				Action<int> onPick;
				if (_pickingLane >= 300)
				{
					text3 = "为转化站添加输出端口(供应物品):";
					onPick = delegate(int item)
					{
						EmcSystem.StationCfg stationCfg = EmcSystem.GetStationCfg(configKey);
						if (!stationCfg.Outputs.Contains(item) && stationCfg.Outputs.Count < 6)
						{
							stationCfg.Outputs.Add(item);
						}
					};
				}
				else if (_pickingLane >= 200)
				{
					text3 = "为转化箱选择输出物品:";
					onPick = delegate(int itemId)
					{
						EmcSystem.SetBoxOutput(configKey, itemId);
					};
				}
				else
				{
					text3 = $"为端口{_pickingLane + 1}选择输出物品:";
					onPick = delegate(int itemId)
					{
						EmcSystem.SetOutput(configKey, _pickingLane, itemId);
					};
				}
				GUILayout.Label(text3, _label, Array.Empty<GUILayoutOption>());
				_pickerScroll = GUILayout.BeginScrollView(_pickerScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(260f) });
				DrawItemGrid(EmcSystem.SortedItems, delegate(int obj3)
				{
					Defer(delegate
					{
						onPick(obj3);
						_pickingLane = -1;
					});
				}, pickerMode: true);
				GUILayout.EndScrollView();
				GUILayout.Space(4f);
			}
			DrawSection("从 EMC 取出到背包");
			GUILayout.Label("左键 ×1\u3000Shift+左键 ×1组\u3000右键 ×10\u3000|\u3000未学习的物品需先投入一次", _labelDim, Array.Empty<GUILayoutOption>());
			Rect lastRect = GUILayoutUtility.GetLastRect();
			if ((int)current.type == 7 && ((Rect)(ref lastRect)).yMax > 1f)
			{
				_measuredScrollTop = ((Rect)(ref lastRect)).yMax;
			}
			float num10 = Mathf.Clamp(((Rect)(ref _rect)).height - _measuredScrollTop - 78f, 150f, 1400f);
			_scroll = GUILayout.BeginScrollView(_scroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num10) });
			DrawItemGrid(EmcSystem.SortedItems, null, pickerMode: false);
			GUILayout.EndScrollView();
			GUILayout.Space(2f);
			GUILayout.Label(_hoverText ?? "", _labelDim, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
			Rect r2 = default(Rect);
			((Rect)(ref r2))..ctor(((Rect)(ref _rect)).width - 40f, ((Rect)(ref _rect)).height - 40f, 40f, 40f);
			bool flag9 = ((Rect)(ref r2)).Contains(current.mousePosition) || _resizing;
			DrawFlat(r2, flag9 ? _texBtnHover : _texSlot);
			GUI.Label(new Rect(((Rect)(ref r2)).x + 4f, ((Rect)(ref r2)).y + 2f, 32f, 34f), "◢", new GUIStyle(_labelDim)
			{
				fontSize = 22,
				alignment = (TextAnchor)4
			});
			if ((int)current.type == 0 && ((Rect)(ref r2)).Contains(current.mousePosition) && current.button == 0)
			{
				_resizing = true;
				_resizeStartMouse = GUIUtility.GUIToScreenPoint(current.mousePosition);
				_resizeStartSize = new Vector2(((Rect)(ref _rect)).width, ((Rect)(ref _rect)).height);
				current.Use();
			}
			GUILayout.EndArea();
			if (_pending.Count > 0)
			{
				List<Action> list = new List<Action>(_pending);
				_pending.Clear();
				foreach (Action item in list)
				{
					item();
				}
			}
			if (_pendingClose)
			{
				_pendingClose = false;
				Close();
			}
		}

		private static StorageComponent GetBoxStorage(PlanetFactory factory)
		{
			if (factory == null || factory.entityPool[_tableEntityId].storageId <= 0)
			{
				return null;
			}
			return factory.factoryStorage.storagePool[factory.entityPool[_tableEntityId].storageId];
		}

		private static void DrawBuildParams(long configKey)
		{
			EmcSystem.BuildCfg bcfg = EmcSystem.GetBuildCfg(configKey);
			DrawSection("输出参数");
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("输出速度:", _label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
			if (GUILayout.Button(bcfg.OutputSpeed + " 个/秒", _btn, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(190f),
				GUILayout.Height(46f)
			}))
			{
				int[] array = new int[7] { 1, 2, 5, 10, 20, 30, 60 };
				int num = Array.IndexOf(array, bcfg.OutputSpeed);
				bcfg.OutputSpeed = array[(num + 1) % array.Length];
			}
			GUILayout.Space(20f);
			GUILayout.Label("喷涂:", _label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
			if (GUILayout.Button((new string[4] { "无", "MK.I", "MK.II", "MK.III" })[bcfg.SprayLevel], _btn, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(140f),
				GUILayout.Height(46f)
			}))
			{
				Defer(delegate
				{
					bcfg.SprayLevel = (bcfg.SprayLevel + 1) % 4;
				});
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			if (bcfg.SprayLevel > 0)
			{
				double num2 = EmcSystem.SprayCostPerItem(bcfg.SprayLevel);
				int hpMax = ((ProtoSet<ItemProto>)(object)LDB.items).Select((new int[3] { 1141, 1142, 1143 })[bcfg.SprayLevel - 1]).HpMax;
				Hover($"涂料价÷可喷{hpMax}次,带增产能效果");
				GUILayout.Label($"\u3000喷涂加价:每件 +{num2:N3} EMC(涂料价÷可喷{hpMax}次),带增产能效果", _labelDim, Array.Empty<GUILayoutOption>());
			}
		}

		private static void DrawItemGrid(IReadOnlyList<ItemProto> items, Action<int> onClick, bool pickerMode)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Expected O, but got Unknown
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			if (items == null || items.Count == 0)
			{
				GUILayout.Label("(价值表尚未构建完成)", _labelDim, Array.Empty<GUILayoutOption>());
				return;
			}
			IReadOnlyList<ItemProto> readOnlyList = items;
			if (pickerMode)
			{
				List<ItemProto> list = new List<ItemProto>(items.Count);
				for (int i = 0; i < items.Count; i++)
				{
					if (EmcSystem.IsLearned(((Proto)items[i]).ID))
					{
						list.Add(items[i]);
					}
				}
				if (list.Count == 0)
				{
					GUILayout.Label("尚无已学习物品:先把物品投入转化设施,学过的物品才能作为输出", _labelDim, Array.Empty<GUILayoutOption>());
					return;
				}
				readOnlyList = list;
			}
			Event current = Event.current;
			float num = ((Rect)(ref _rect)).width - 28f;
			int num2 = Mathf.Max(3, (int)(num / 80f));
			int num3 = Mathf.CeilToInt((float)readOnlyList.Count / (float)num2);
			Rect rect = GUILayoutUtility.GetRect(num, (float)num3 * 79f);
			Rect r = default(Rect);
			for (int j = 0; j < readOnlyList.Count; j++)
			{
				ItemProto val = readOnlyList[j];
				int num4 = j / num2;
				int num5 = j % num2;
				((Rect)(ref r))..ctor(((Rect)(ref rect)).x + (float)num5 * 79f, ((Rect)(ref rect)).y + (float)num4 * 79f, 76f, 76f);
				bool num6 = ((Rect)(ref r)).Contains(current.mousePosition);
				bool flag = EmcSystem.IsLearned(((Proto)val).ID);
				double num7 = EmcSystem.EmcOf(((Proto)val).ID);
				bool flag2 = EmcSystem.Balance + 1E-09 >= num7;
				DrawFlat(r, _texSlot);
				DrawIcon(val, ((Rect)(ref r)).x + 3f, ((Rect)(ref r)).y + 3f, 70f, 70f);
				if (!flag)
				{
					Color color = GUI.color;
					GUI.color = new Color(0.02f, 0.03f, 0.05f, 0.72f);
					GUI.DrawTexture(new Rect(((Rect)(ref r)).x + 1f, ((Rect)(ref r)).y + 1f, 74f, 74f), (Texture)(object)_texSlot, (ScaleMode)0);
					GUI.color = color;
					GUI.Label(new Rect(((Rect)(ref r)).x + 2f, ((Rect)(ref r)).y + 38f - 9f, 72f, 18f), "未学习", new GUIStyle(_labelDim)
					{
						alignment = (TextAnchor)4,
						fontSize = 15
					});
				}
				else if (!pickerMode)
				{
					GUI.Label(new Rect(((Rect)(ref r)).x + 2f, ((Rect)(ref r)).y + 76f - 15f, 72f, 13f), FormatEmc(num7), flag2 ? _priceOk : _priceNo);
				}
				if (num6)
				{
					DrawFlat(new Rect(((Rect)(ref r)).x - 1f, ((Rect)(ref r)).y - 1f, 78f, 1f), _texFlat.SetColor(flag ? ColCyan : ColBorderDim));
					DrawFlat(new Rect(((Rect)(ref r)).x - 1f, ((Rect)(ref r)).y + 76f, 78f, 1f), _texFlat.SetColor(flag ? ColCyan : ColBorderDim));
					DrawFlat(new Rect(((Rect)(ref r)).x - 1f, ((Rect)(ref r)).y, 1f, 76f), _texFlat.SetColor(flag ? ColCyan : ColBorderDim));
					DrawFlat(new Rect(((Rect)(ref r)).x + 76f, ((Rect)(ref r)).y, 1f, 76f), _texFlat.SetColor(flag ? ColCyan : ColBorderDim));
					if (!flag)
					{
						Hover(((Proto)val).name + "\u3000未学习 —— 把该物品投入一次转化设施即可解锁兑换");
					}
					else if (pickerMode)
					{
						Hover($"{((Proto)val).name}\u3000{num7:N1} EMC —— 点击选择");
					}
					else
					{
						Hover($"{((Proto)val).name}\u3000{num7:N1} EMC —— 左键×1 / Shift+左键×1组 / 右键×10" + (flag2 ? "" : "\u3000(EMC 不足)"));
					}
				}
				if ((int)current.type == 0 && ((Rect)(ref r)).Contains(current.mousePosition) && current.button >= 0 && current.button <= 1)
				{
					current.Use();
					if (!flag)
					{
						break;
					}
					if (pickerMode)
					{
						onClick?.Invoke(((Proto)val).ID);
					}
					else if (current.button == 0)
					{
						Withdraw(((Proto)val).ID, (!current.shift) ? 1 : GetStackSize(((Proto)val).ID));
					}
					else if (current.button == 1)
					{
						Withdraw(((Proto)val).ID, 10);
					}
				}
			}
		}

		private static void Withdraw(int itemId, int count)
		{
			if (count <= 0 || !EmcSystem.IsLearned(itemId))
			{
				return;
			}
			double num = EmcSystem.EmcOf(itemId);
			int val = (int)Math.Floor((EmcSystem.Balance + 1E-09) / num);
			int num2 = Math.Min(count, val);
			if (num2 > 0)
			{
				int num4 = default(int);
				int num3 = GameMain.mainPlayer.package.AddItem(itemId, num2, 0, ref num4, false);
				if (num3 > 0)
				{
					EmcSystem.Balance -= num * (double)num3;
				}
			}
		}

		private static int GetStackSize(int itemId)
		{
			return ((ProtoSet<ItemProto>)(object)LDB.items).Select(itemId)?.StackSize ?? 1;
		}

		private static void StoreAllFromPackage()
		{
			StorageComponent package = GameMain.mainPlayer.package;
			if (package == null || package.grids == null)
			{
				return;
			}
			double num = 0.0;
			int num4 = default(int);
			for (int i = 0; i < package.size && i < package.grids.Length; i++)
			{
				if (package.grids[i].itemId > 0 && package.grids[i].count > 0)
				{
					int itemId = package.grids[i].itemId;
					int num2 = 0;
					int num3 = 0;
					package.TakeItemFromGrid(i, ref num2, ref num3, ref num4);
					if (num2 == itemId && num3 > 0)
					{
						EmcSystem.Learn(itemId);
						num += EmcSystem.EmcOf(itemId) * (double)num3;
					}
				}
			}
			if (num > 0.0)
			{
				EmcSystem.Balance += num;
			}
		}

		private static void DrawIcon(ItemProto proto, float x, float y, float w, float h)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (proto != null)
			{
				Sprite iconSprite = proto.iconSprite;
				if (!((Object)(object)iconSprite == (Object)null))
				{
					Rect textureRect = iconSprite.textureRect;
					Rect val = default(Rect);
					((Rect)(ref val))..ctor(((Rect)(ref textureRect)).x / (float)((Texture)iconSprite.texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)iconSprite.texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)iconSprite.texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)iconSprite.texture).height);
					GUI.DrawTextureWithTexCoords(new Rect(x, y, w, h), (Texture)(object)iconSprite.texture, val, true);
				}
			}
		}

		private static string FormatEmc(double v)
		{
			if (v >= 10000.0)
			{
				return (v / 1000.0).ToString("0.#") + "k";
			}
			if (v >= 100.0)
			{
				return ((int)v).ToString();
			}
			return v.ToString("0.#");
		}
	}
	internal static class GuiTexExt
	{
		public static Texture2D SetColor(this Texture2D t, Color c)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			t.SetPixels((Color[])(object)new Color[4] { c, c, c, c });
			t.Apply(false, false);
			return t;
		}
	}
	[BepInPlugin("workbuddy.TransmutationTable", "TransmutationTable", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class TransmutationTablePlugin : BaseUnityPlugin, IModCanSave
	{
		public const string PluginGuid = "workbuddy.TransmutationTable";

		public const string PluginName = "TransmutationTable";

		public const string PluginVersion = "1.0.0";

		public static int TableItemId = 9701;

		internal static ItemProto TableProto;

		internal static RecipeProto TableRecipe;

		internal static ItemProto BoxProto;

		internal static RecipeProto BoxRecipe;

		internal static ItemProto StationProto;

		internal static RecipeProto StationRecipe;

		internal static ItemProto TableTemplate;

		internal static ItemProto BoxTemplate;

		internal static ItemProto StationTemplate;

		public static int BoxItemId = 9703;

		public static int StationItemId = 9705;

		internal static ManualLogSource Log;

		internal Harmony HarmonyInstance;

		private void Awake()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			LDBTool.PreAddDataAction = (Action)Delegate.Combine(LDBTool.PreAddDataAction, new Action(RegisterProtos));
			LDBTool.PostAddDataAction = (Action)Delegate.Combine(LDBTool.PostAddDataAction, new Action(AfterProtosAdded));
			HarmonyInstance = new Harmony("workbuddy.TransmutationTable");
			HarmonyInstance.PatchAll(typeof(AbnormalityGuard));
			HarmonyInstance.PatchAll(typeof(ProtoGuard));
			HarmonyInstance.PatchAll(typeof(TablePatches));
			HarmonyInstance.PatchAll(typeof(TechTreeSlotExtendPatch));
			TablePatches.RegisterManualPatches(HarmonyInstance);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"转化桌已加载 (EMC system ready)");
		}

		private void OnDestroy()
		{
			LDBTool.PreAddDataAction = (Action)Delegate.Remove(LDBTool.PreAddDataAction, new Action(RegisterProtos));
			LDBTool.PostAddDataAction = (Action)Delegate.Remove(LDBTool.PostAddDataAction, new Action(AfterProtosAdded));
			Harmony harmonyInstance = HarmonyInstance;
			if (harmonyInstance != null)
			{
				harmonyInstance.UnpatchSelf();
			}
		}

		private void Update()
		{
			try
			{
				BuildMenuInstaller.TryInstall();
			}
			catch (Exception e)
			{
				Diag.Error("建造菜单安装", e);
			}
			try
			{
				if (Input.GetKeyDown((KeyCode)290) && GameMain.data != null && GameMain.mainPlayer != null)
				{
					GiveItem(TableItemId, "转化桌");
					GiveItem(BoxItemId, "转化箱");
					GiveItem(StationItemId, "转化站");
				}
			}
			catch (Exception e2)
			{
				Diag.Error("F9 发放", e2);
			}
		}

		private static void GiveItem(int itemId, string label)
		{
			if (((ProtoSet<ItemProto>)(object)LDB.items).Select(itemId) == null)
			{
				UIRealtimeTip.Popup(label + " 物品尚未注册,请重启游戏", false, 0);
				return;
			}
			int num = default(int);
			GameMain.mainPlayer.package.AddItem(itemId, 1, 0, ref num, false);
			UIRealtimeTip.Popup("已获得 " + label + " ×1(F9 随时领取)", true, 0);
			Log.LogInfo((object)("F9 发放" + label + " ×1"));
		}

		private static void RegisterProtos()
		{
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Expected O, but got Unknown
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Expected O, but got Unknown
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04af: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0513: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: Expected O, but got Unknown
			//IL_0569: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Expected O, but got Unknown
			//IL_05a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0685: Unknown result type (might be due to invalid IL or missing references)
			//IL_068a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0692: Unknown result type (might be due to invalid IL or missing references)
			//IL_069d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0705: Unknown result type (might be due to invalid IL or missing references)
			//IL_0712: Unknown result type (might be due to invalid IL or missing references)
			//IL_071f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0727: Unknown result type (might be due to invalid IL or missing references)
			//IL_0734: Unknown result type (might be due to invalid IL or missing references)
			//IL_0740: Unknown result type (might be due to invalid IL or missing references)
			//IL_0748: Unknown result type (might be due to invalid IL or missing references)
			//IL_0751: Expected O, but got Unknown
			//IL_07cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d4: Expected O, but got Unknown
			//IL_0804: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ItemProto val = FindFractionator();
				if (val == null)
				{
					ItemProto[] array = ((ProtoSet<ItemProto>)(object)LDB.items)?.dataArray;
					StringBuilder stringBuilder = new StringBuilder("dataArray=");
					stringBuilder.Append((array != null) ? array.Length : (-1)).Append("; 样例: ");
					if (array != null)
					{
						for (int i = 0; i < Math.Min(30, array.Length); i++)
						{
							StringBuilder stringBuilder2 = stringBuilder.Append('[').Append(((Proto)(array[i]?)).Name).Append('|');
							ItemProto obj = array[i];
							stringBuilder2.Append((obj != null) ? ((Proto)obj).name : null).Append("] ");
						}
					}
					Log.LogError((object)("找不到分馏器原型,转化桌注册失败。" + stringBuilder));
					return;
				}
				Log.LogInfo((object)$"模板分馏器: ID={((Proto)val).ID} Name={((Proto)val).Name} ModelIndex={val.ModelIndex}");
				int num = FindFreeId(GetUsedItemIds(), 9701, 11899);
				int iD = FindFreeId(GetUsedRecipeIds(), num + 1, 11999);
				int num2 = FindFreeId(GetUsedItemIds(), num + 2, 11899);
				int iD2 = FindFreeId(GetUsedRecipeIds(), num2 + 1, 11999);
				int num3 = FindFreeId(GetUsedItemIds(), num + 4, 11899);
				int iD3 = FindFreeId(GetUsedRecipeIds(), num3 + 1, 11999);
				int buildIndex = 404;
				int buildIndex2 = 405;
				int buildIndex3 = 406;
				TechProto preTech = ((ProtoSet<TechProto>)(object)LDB.techs)?.Select(1603);
				TechProto preTech2 = ((ProtoSet<TechProto>)(object)LDB.techs)?.Select(1601);
				TechProto preTech3 = ((ProtoSet<TechProto>)(object)LDB.techs)?.Select(1605);
				int[] array2 = AllocateGridsBelow(FindGaussTurretGrid(), 3);
				int modelIndex = RegisterPurpleModel(val, "转化桌-紫", 0.35f);
				ItemProto val2 = new ItemProto
				{
					ID = num,
					Name = "转化桌",
					SID = "转化桌",
					Description = "向内投入任意物品即可转化为 EMC 存储,再从 EMC 中换取需要的物品。所有转化桌共享同一个 EMC 空间,销毁建筑不会损失数据。",
					IconPath = val.IconPath,
					ModelIndex = modelIndex,
					ModelCount = val.ModelCount,
					IsEntity = true,
					CanBuild = true,
					BuildInGas = val.BuildInGas,
					HpMax = val.HpMax,
					StackSize = 20,
					BuildMode = val.BuildMode,
					GridIndex = val.GridIndex,
					UnlockKey = num,
					DescFields = val.DescFields,
					Upgrades = new int[0],
					BuildIndex = buildIndex,
					handcraftProductCount = 1
				};
				(int[], int[], int, int) tuple = ScaleTemplateRecipe(val, new int[4]
				{
					ResolveIdOr("steel", "钢材", 1103),
					ResolveIdOr("stone brick", "石材", 1108),
					ResolveIdOr("glass", "玻璃", 1110),
					ResolveIdOr("processor", "处理器", 1303)
				}, new int[4] { 24, 12, 12, 3 });
				RecipeProto val3 = new RecipeProto();
				((Proto)val3).ID = iD;
				((Proto)val3).Name = "制作转化桌";
				((Proto)val3).SID = "制作转化桌";
				val3.Description = "制作一台转化桌。";
				val3.Type = (ERecipeType)4;
				val3.Handcraft = true;
				val3.Explicit = true;
				val3.GridIndex = array2[0];
				val3.TimeSpend = ((tuple.Item3 > 0) ? tuple.Item3 : 240);
				val3.Items = tuple.Item1;
				val3.ItemCounts = tuple.Item2;
				val3.Results = new int[1] { num };
				val3.ResultCounts = new int[1] { 1 };
				val3.IconPath = val.IconPath;
				val3.preTech = preTech;
				RecipeProto val4 = val3;
				CommitBuilding(val2, val4);
				TableProto = val2;
				TableRecipe = val4;
				TableTemplate = val;
				ItemProto val5 = FindSmallStorageBox();
				if (val5 == null)
				{
					Log.LogWarning((object)"找不到储物仓原型,转化箱未注册");
				}
				else
				{
					int modelIndex2 = RegisterPurpleModel(val5, "转化箱-紫");
					ItemProto val6 = new ItemProto
					{
						ID = num2,
						Name = "转化箱",
						SID = "转化箱",
						Description = "储物仓造型的转化设施:用分拣器把任意物品送进箱内即自动转化为 EMC,在界面中取出的物品会出现在箱内,再用分拣器取走即可。EMC 余额全宇宙共享。",
						IconPath = val5.IconPath,
						ModelIndex = modelIndex2,
						ModelCount = val5.ModelCount,
						IsEntity = true,
						CanBuild = true,
						BuildInG