Decompiled source of RateMonitor v0.4.0

RateMonitor.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CommonAPI;
using CommonAPI.Systems;
using CommonAPI.Systems.ModLocalization;
using HarmonyLib;
using RateMonitor.Model;
using RateMonitor.Model.Processor;
using RateMonitor.Patches;
using RateMonitor.UI;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("RateMonitor")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.4.0.0")]
[module: UnverifiableCode]
namespace RateMonitor
{
	public static class ModSettings
	{
		public static ConfigEntry<KeyboardShortcut> SelectionToolKey;

		public static ConfigEntry<int> RateUnit;

		public static ConfigEntry<int> FontSize;

		public static ConfigEntry<bool> ShowRealtimeRate;

		public static ConfigEntry<bool> ShowWorkingRateInPercentage;

		public static ConfigEntry<int> IncLevel;

		public static ConfigEntry<bool> ForceInc;

		public static ConfigEntry<bool> ForceLens;

		public static ConfigEntry<bool> EnableQuickBarButton;

		public static ConfigEntry<bool> EnableSingleBuildingClick;

		public static ConfigEntry<float> WindowWidth;

		public static ConfigEntry<float> WindowHeight;

		public static ConfigEntry<float> WindowRatePanelWidth;

		public static void LoadConfigs(ConfigFile config)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			SelectionToolKey = config.Bind<KeyboardShortcut>("KeyBinds", "SelectToolKey", new KeyboardShortcut((KeyCode)120, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Hotkey to toggle area selection tool\n启用框选工具的热键");
			RateUnit = config.Bind<int>("Display", "Rate Unit", 1, new ConfigDescription("Timescale unit (x item per minute)\n速率单位(每分钟x个物品)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 14400), Array.Empty<object>()));
			FontSize = config.Bind<int>("Display", "Font Size", 14, (ConfigDescription)null);
			ShowRealtimeRate = config.Bind<bool>("Display", "Show Realtime Rate", true, "Show Real-time Monitoring Rate\n显示即时监控速率");
			ShowWorkingRateInPercentage = config.Bind<bool>("Display", "Show Working Rate in percentage", true, "Show Real-time Working Rate in percentage\n以百分比显示工作效率");
			IncLevel = config.Bind<int>("General", "Proliferator Level", -1, new ConfigDescription("Level of proliferator [1,2,4]. Auto dectect: -1\n增产效果等级[1,2,4] 自动侦测:-1", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 10), Array.Empty<object>()));
			ForceInc = config.Bind<bool>("General", "Force Proliferator", false, "The theoretical max rate always apply proliferator, regardless the material.\n计算理论上限时是否强制套用增产设定(false=依照当下原料决定)");
			ForceLens = config.Bind<bool>("General", "Force Gravity Lens in Ray Receiver", false, "The theoretical max rate always apply gravity lens.\n计算射线接收站时总是套用透镜(false=依照当下决定)");
			EnableQuickBarButton = config.Bind<bool>("UI", "Enable Quick Bar Button", true, "Create a button in mecha energy bar\n在机甲能量条创建一个mod开关按钮");
			EnableQuickBarButton.SettingChanged += delegate
			{
				QuickBarButton.Enable(EnableQuickBarButton.Value);
			};
			EnableSingleBuildingClick = config.Bind<bool>("UI", "Enable Single Building Click", true, "When mod window is open, enable ctrl/shift + RMB to add/remove building\n在窗口打开时,Ctrl/Shift+右键可以添加/移除建筑");
			WindowWidth = config.Bind<float>("UI", "Window Width", 580f, (ConfigDescription)null);
			WindowHeight = config.Bind<float>("UI", "Window Height", 400f, (ConfigDescription)null);
			WindowRatePanelWidth = config.Bind<float>("UI", "Window Rate Panel Width", 190f, (ConfigDescription)null);
		}
	}
	[BepInPlugin("starfi5h.plugin.RateMonitor", "RateMonitor", "0.4.0")]
	public class Plugin : BaseUnityPlugin
	{
		public enum EOperation
		{
			Normal,
			Add,
			Sub
		}

		public const string GUID = "starfi5h.plugin.RateMonitor";

		public const string NAME = "RateMonitor";

		public const string VERSION = "0.4.0";

		public static ManualLogSource Log;

		public static Plugin instance;

		private static Harmony harmony;

		private static List<int> lastEntityIds = new List<int>();

		private static int lastPlanetId;

		public static StatTable MainTable { get; set; }

		public static EOperation Operation { get; set; }

		public static string LastStatInfo { get; private set; } = "";


		public void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			instance = this;
			harmony = new Harmony("starfi5h.plugin.RateMonitor");
			harmony.PatchAll(typeof(SelectionTool_Patches));
			harmony.PatchAll(typeof(MainPatches));
			ModSettings.LoadConfigs(((BaseUnityPlugin)this).Config);
			if (Chainloader.PluginInfos.TryGetValue("org.LoShin.GenesisBook", out var _))
			{
				Log.LogInfo((object)"Compat - GenesisBook");
				CalDB.CompatGB = true;
			}
			UIWindow.LoadUIWindowConfig();
			Localization.OnLanguageChange += SP.Init;
			if (ModSettings.EnableQuickBarButton.Value)
			{
				harmony.PatchAll(typeof(QuickBarButton));
			}
		}

		public void OnGUI()
		{
			UIWindow.OnGUI();
		}

		public void Update()
		{
			if (GameMain.localPlanet == null && SelectionTool_Patches.IsHotKey() && MainTable == null && !LoadLastTable())
			{
				CreateMainTable(null, new List<int>(0));
			}
		}

		public static void OnSelectionFinish(PlanetFactory factory, HashSet<int> entityIdSet)
		{
			switch (Operation)
			{
			case EOperation.Add:
			{
				Operation = EOperation.Normal;
				if (MainTable == null)
				{
					break;
				}
				PlanetFactory factory3;
				List<int> entityIds2 = MainTable.GetEntityIds(out factory3);
				if (factory3 == factory)
				{
					entityIdSet.UnionWith(entityIds2);
					if (entityIdSet.Count() > 0)
					{
						SaveCurrentTable();
						CreateMainTable(factory, entityIdSet.ToList());
					}
				}
				break;
			}
			case EOperation.Sub:
			{
				Operation = EOperation.Normal;
				if (MainTable == null)
				{
					break;
				}
				PlanetFactory factory2;
				List<int> entityIds = MainTable.GetEntityIds(out factory2);
				if (factory2 != factory)
				{
					break;
				}
				IEnumerable<int> enumerable = entityIdSet.Intersect(entityIds);
				foreach (int item in enumerable)
				{
					entityIds.Remove(item);
				}
				if (enumerable.Count() > 0)
				{
					SaveCurrentTable();
					CreateMainTable(factory, entityIds.ToList());
				}
				break;
			}
			default:
				SaveCurrentTable();
				CreateMainTable(factory, entityIdSet.ToList());
				break;
			}
		}

		public static void CreateMainTable(PlanetFactory factory, List<int> entityIds)
		{
			if (!SP.IsInit)
			{
				SP.Init();
			}
			MainTable = new StatTable();
			MainTable.Initialize(factory, entityIds);
			Log.LogDebug((object)("CreateMainTable: " + MainTable.GetEntityCount()));
		}

		public static bool SaveCurrentTable()
		{
			if (MainTable == null)
			{
				return false;
			}
			PlanetFactory factory;
			List<int> entityIds = MainTable.GetEntityIds(out factory);
			if (entityIds.Count == 0)
			{
				return false;
			}
			lastEntityIds = entityIds;
			lastPlanetId = factory.planetId;
			PlanetData obj = GameMain.galaxy.PlanetById(lastPlanetId);
			LastStatInfo = (((obj != null) ? obj.displayName : null) ?? " ") + ": " + lastEntityIds.Count;
			Log.LogDebug((object)("SaveCurrentTable: " + LastStatInfo));
			return true;
		}

		public static bool LoadLastTable()
		{
			PlanetFactory val = GameMain.galaxy.PlanetById(lastPlanetId)?.factory;
			if (val == null || lastEntityIds.Count == 0)
			{
				return false;
			}
			List<int> list = new List<int>();
			foreach (int lastEntityId in lastEntityIds)
			{
				if (SelectionTool.ShouldAddObject(val, lastEntityId))
				{
					list.Add(lastEntityId);
				}
			}
			if (list.Count == 0)
			{
				return false;
			}
			SaveCurrentTable();
			CreateMainTable(val, list);
			return true;
		}

		public void OnDestroy()
		{
			harmony.UnpatchSelf();
			harmony = null;
			Localization.OnLanguageChange -= SP.Init;
			Utils.OnDestroy();
			QuickBarButton.Destroy();
		}
	}
	[BepInPlugin("starfi5h.plugin.RateMonitor.CAPIcompat", "RateMonitorCAPIcompat", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[CommonAPISubmoduleDependency(new string[] { "LocalizationModule", "CustomKeyBindSystem" })]
	public class PluginCAPIcompat : BaseUnityPlugin
	{
		public const string GUID = "starfi5h.plugin.RateMonitor.CAPIcompat";

		public const string NAME = "RateMonitorCAPIcompat";

		public const string VERSION = "1.0.0";

		public static bool IsRegisiter;

		public void Awake()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			BuiltinKey val = default(BuiltinKey);
			val.key = new CombineKey(120, (byte)4, (ECombineKeyAction)0, false);
			val.conflictGroup = 2048;
			val.name = "RateMonitorSelectionToolKey";
			val.canOverride = true;
			CustomKeyBindSystem.RegisterKeyBind<PressKeyBind>(val);
			LocalizationModule.RegisterTranslation("KEYRateMonitorSelectionToolKey", "(RateMonitor) Enable Selection Tool", "(RateMonitor) 启用框选工具", "(RateMonitor) Selection Tool");
			IsRegisiter = true;
		}

		public static bool IsPressed()
		{
			return CustomKeyBindSystem.GetKeyBind("RateMonitorSelectionToolKey").keyValue;
		}
	}
	public static class SP
	{
		public static string displaySettingsText;

		public static string showRealTimeRateText;

		public static string showInPercentageText;

		public static string rateUnitText;

		public static string perMinuteText;

		public static string perSecondText;

		public static string[] perBeltTexts = new string[3];

		public static string fontSizeText;

		public static string calculateSettingsText;

		public static string incLevelText;

		public static string forceIncText;

		public static string forceText;

		public static string forceLens;

		public static string uiSettingsText;

		public static string enableQuickBarButtonText;

		public static string enableSingleBuildingText;

		public static string settingButtonText;

		public static string operationButtonText;

		public static string backButtonText;

		public static string entityCountText;

		public static string countMultiplierText;

		public static string recalculateText;

		public static string addActionText;

		public static string subActionText;

		public static string planetSelectDescriptionText;

		public static string wholeLocalPlanetText;

		public static string wholeRemotePlanetText;

		public static string loadLastText;

		public static string resetTimerText;

		public static string modGuideText;

		public static string itemIdProduceText;

		public static string itemIdConsumeText;

		public static string itemIdIntermediateText;

		public static string workingOnlyText;

		public static string expandedOnlyText;

		public static string proliferatorCostText;

		public static string powerCostText;

		public static string totalProductionText;

		public static string totalConsumptionText;

		public static string netMachineText;

		public static string expandRecordText;

		public static string naviToMachineText;

		public static bool IsInit { get; private set; }

		public static void Init()
		{
			bool isZHCN = Localization.isZHCN;
			displaySettingsText = (isZHCN ? "显示设定" : Localization.Translate("Display Settings"));
			showRealTimeRateText = (isZHCN ? "显示即时监控速率" : Localization.Translate("Show Real-time Monitoring Rate"));
			showInPercentageText = (isZHCN ? "以百分比显示" : Localization.Translate("Show In Percentage"));
			rateUnitText = (isZHCN ? "速率单位: " : Localization.Translate("RateUnit: "));
			perMinuteText = (isZHCN ? "每分钟" : Localization.Translate("Per Minute"));
			perSecondText = (isZHCN ? "每秒钟" : Localization.Translate("Per Second"));
			perBeltTexts[0] = (isZHCN ? "黄带" : Localization.Translate("Mk1 Belt"));
			perBeltTexts[1] = (isZHCN ? "绿带" : Localization.Translate("Mk2 Belt"));
			perBeltTexts[2] = (isZHCN ? "蓝带" : Localization.Translate("Mk3 Belt"));
			fontSizeText = (isZHCN ? "字体大小" : Localization.Translate("Font Size"));
			calculateSettingsText = (isZHCN ? "計算设定" : Localization.Translate("Calculate Settings"));
			incLevelText = (isZHCN ? "增产等级: " : Localization.Translate("ProliferatorLevel: "));
			forceIncText = (isZHCN ? "强制增产" : Localization.Translate("ForceProliferator"));
			forceLens = (isZHCN ? "强制透镜" : Localization.Translate("ForceGravitonLens"));
			forceText = (isZHCN ? "强制" : Localization.Translate("Force"));
			uiSettingsText = (isZHCN ? "UI设定" : Localization.Translate("UI Settings"));
			enableQuickBarButtonText = (isZHCN ? "在机甲能量条创建一个mod开关按钮" : Localization.Translate("Create a button in mecha energy bar"));
			enableSingleBuildingText = (isZHCN ? "在窗口打开时,Ctrl/Shift+右键可以添加/移除建筑" : Localization.Translate("enable ctrl/shift + RMB to add/remove building"));
			settingButtonText = (isZHCN ? "设置" : Localization.Translate("Config"));
			operationButtonText = (isZHCN ? "操作" : Localization.Translate("Operate"));
			backButtonText = (isZHCN ? "返回" : Localization.Translate("Back"));
			entityCountText = (isZHCN ? "建筑数量: " : Localization.Translate("EntityCount: "));
			countMultiplierText = (isZHCN ? "建筑数量倍数" : Localization.Translate("Count Multiplier"));
			recalculateText = (isZHCN ? "重新计算" : Localization.Translate("Recalculate"));
			addActionText = (isZHCN ? "添加选取" : Localization.Translate("Add Selection"));
			subActionText = (isZHCN ? "移除选取" : Localization.Translate("Sub Selection"));
			planetSelectDescriptionText = (isZHCN ? "可以在统计面板或总控面板选择星球来框选全建筑" : Localization.Translate("Select a planet in the statistics panel or control panel to select all buildings on it"));
			wholeLocalPlanetText = (isZHCN ? "选取本地全球机器" : Localization.Translate("Select Whole Local Planet"));
			wholeRemotePlanetText = (isZHCN ? "选取远端全球机器" : Localization.Translate("Select Whole Remote Planet"));
			loadLastText = (isZHCN ? "载入上一个选取" : Localization.Translate("Load Last Selection"));
			resetTimerText = (isZHCN ? "重置计时器" : Localization.Translate("Reset Timer"));
			modGuideText = (isZHCN ? "点击物品图示可以过滤该产物\n点击机器图示可以展开详细信息" : Localization.Translate("Click on the item icon to filter the product\nClick on the machine icon to expand the detailed information"));
			itemIdProduceText = (isZHCN ? "产物" : Localization.Translate("Product "));
			itemIdConsumeText = (isZHCN ? "原料" : Localization.Translate("Material"));
			itemIdIntermediateText = (isZHCN ? "中间产物" : Localization.Translate("Intermediate"));
			workingOnlyText = (isZHCN ? "工作中" : Localization.Translate("Working"));
			expandedOnlyText = (isZHCN ? "已展开" : Localization.Translate("Expanded"));
			proliferatorCostText = (isZHCN ? "增产剂需求: " : Localization.Translate("Proliferator Cost: "));
			powerCostText = (isZHCN ? "电力需求: " : Localization.Translate("Power Cost: "));
			totalProductionText = (isZHCN ? "总生产: " : Localization.Translate("Total Produce:   "));
			totalConsumptionText = (isZHCN ? "总消耗: " : Localization.Translate("Total Consume: "));
			netMachineText = (isZHCN ? "净机器: " : Localization.Translate("Net Machine: "));
			expandRecordText = (isZHCN ? "详情" : Localization.Translate("Detail"));
			naviToMachineText = (isZHCN ? "导航至机器" : Localization.Translate("Navigate to machine"));
			EntityRecord.InitStrings(isZHCN);
			IsInit = true;
		}
	}
}
namespace RateMonitor.UI
{
	public class OperactionPanel
	{
		private readonly StatTable statTable;

		private Vector2 scrollPosition;

		public bool IsActive { get; set; }

		public OperactionPanel(StatTable statTable)
		{
			this.statTable = statTable;
		}

		public void DrawPanel()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			scrollPosition = GUILayout.BeginScrollView(scrollPosition, Array.Empty<GUILayoutOption>());
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label(SP.planetSelectDescriptionText, Array.Empty<GUILayoutOption>());
			if (GameMain.localPlanet != null)
			{
				PlanetFactory factory = GameMain.localPlanet.factory;
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button(SP.wholeLocalPlanetText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth(Utils.LargeButtonWidth) }))
				{
					List<int> list = new List<int>();
					for (int i = 1; i < factory.entityCursor; i++)
					{
						if (SelectionTool.ShouldAddObject(factory, i))
						{
							list.Add(i);
						}
					}
					if (list.Count > 0)
					{
						Plugin.SaveCurrentTable();
						Plugin.CreateMainTable(factory, list);
					}
				}
				GUILayout.Label("entity count: " + (factory.entityCursor - factory.enemyRecycleCursor), Array.Empty<GUILayoutOption>());
				GUILayout.EndHorizontal();
			}
			int num = 0;
			if (((ManualBehaviour)UIRoot.instance.uiGame.statWindow).active)
			{
				num = UIRoot.instance.uiGame.statWindow.astroFilter;
			}
			if (((ManualBehaviour)UIRoot.instance.uiGame.controlPanelWindow).active)
			{
				num = UIRoot.instance.uiGame.controlPanelWindow.filter.astroFilter;
			}
			PlanetData val = GameMain.galaxy.PlanetById(num);
			if (val != null && val.factory != null)
			{
				PlanetFactory factory2 = val.factory;
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button(SP.wholeRemotePlanetText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth(Utils.LargeButtonWidth) }))
				{
					List<int> list2 = new List<int>();
					for (int j = 1; j < factory2.entityCursor; j++)
					{
						if (SelectionTool.ShouldAddObject(factory2, j))
						{
							list2.Add(j);
						}
					}
					if (list2.Count > 0)
					{
						Plugin.SaveCurrentTable();
						Plugin.CreateMainTable(factory2, list2);
					}
				}
				GUILayout.Label(val.displayName + ": " + (factory2.entityCursor - factory2.enemyRecycleCursor), Array.Empty<GUILayoutOption>());
				GUILayout.EndHorizontal();
			}
			GUILayout.EndVertical();
			GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button(SP.loadLastText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth(Utils.LargeButtonWidth) }))
			{
				Plugin.LoadLastTable();
			}
			GUILayout.Label(Plugin.LastStatInfo, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button(SP.resetTimerText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth(Utils.LargeButtonWidth) }))
			{
				statTable.ResetTimer();
			}
			GUILayout.Label(((float)statTable.TotalTick / 60f).ToString("F2") + "s", Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			GUILayout.Label(SP.modGuideText, Array.Empty<GUILayoutOption>());
			GUILayout.EndScrollView();
			GUILayout.EndVertical();
		}
	}
	public class ProfileEntry
	{
		public readonly ProductionProfile Profile;

		private static ushort entityCursor;

		public bool IsExpand { get; set; }

		public bool IsExpandRecords { get; set; }

		public ProfileEntry(ProductionProfile profile)
		{
			Profile = profile;
		}

		public void DrawProfileItem(int index)
		{
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			float num = UIWindow.Instance.ProfilePanelWidth - Utils.ShortButtonWidth;
			float num2 = Profile.TotalMachineCount;
			Utils.FocusItemIconButton(Profile.itemIds[index]);
			string text = Utils.RateKMG(Profile.itemRefSpeeds[index] * num2 * (float)CalDB.CountMultiplier);
			float num3 = Profile.WorkingMachineCount / num2;
			if (ModSettings.ShowRealtimeRate.Value)
			{
				text = ((!ModSettings.ShowWorkingRateInPercentage.Value) ? (text + " (" + Utils.RateKMG(Profile.itemRefSpeeds[index] * Profile.WorkingMachineCount) + ")") : (text + ((num3 > 1f) ? " (100%)" : (" (" + (int)(num3 * 100f) + "%)"))));
			}
			GUILayout.Label(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(num / 3f) });
			if (Utils.RecipeExpandButton(Profile.protoId))
			{
				IsExpand = !IsExpand;
			}
			string text2 = "  " + num2 * (float)CalDB.CountMultiplier;
			if (ModSettings.ShowRealtimeRate.Value)
			{
				text2 = text2 + " (" + Utils.KMG(Profile.WorkingMachineCount * (float)CalDB.CountMultiplier) + ")";
			}
			GUILayout.Label(text2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(num / 3f - 10f) });
			string text3 = Utils.RateKMG(Profile.itemRefSpeeds[index]);
			if (Profile.incUsed)
			{
				text3 += "*";
			}
			GUILayout.Label(" x " + text3, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			if (IsExpand)
			{
				DrawProfileItemDetail(Profile, index);
			}
			GUILayout.EndVertical();
		}

		private void DrawProfileItemDetail(ProductionProfile profile, int index)
		{
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			int num = profile.itemIds[index];
			RecipeProto val = ((ProtoSet<RecipeProto>)(object)LDB.recipes).Select(profile.recipeId);
			if (val != null)
			{
				GUILayout.Label(((Proto)val).name, Array.Empty<GUILayoutOption>());
			}
			if (profile.incLevel > 0)
			{
				GUILayout.Label("(" + (profile.accMode ? Localization.Translate("加速生产") : Localization.Translate("额外产出")) + ")", Array.Empty<GUILayoutOption>());
			}
			GUILayout.FlexibleSpace();
			if (ProfilePanel.FocusItmeId != 0 && ProfilePanel.FocusItmeId == num)
			{
				StatTable table = UIWindow.Instance.Table;
				float num2 = table.ItemRefRates[num] / profile.itemRefSpeeds[index] * (float)CalDB.CountMultiplier;
				float num3 = table.ItemEstRates[num] / profile.itemRefSpeeds[index] * (float)CalDB.CountMultiplier;
				string text = SP.netMachineText + num2.ToString("0.##");
				if (ModSettings.ShowRealtimeRate.Value)
				{
					text = text + " (" + num3.ToString("0.00") + ")";
				}
				GUILayout.Label(text, Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndHorizontal();
			if (profile.entityRecords.Count > 0)
			{
				GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(profile.GetRecordSummary(), Array.Empty<GUILayoutOption>());
				IsExpandRecords = GUILayout.Toggle(IsExpandRecords, SP.expandRecordText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.ShortButtonWidth) });
				GUILayout.EndHorizontal();
				if (IsExpandRecords)
				{
					foreach (EntityRecord entityRecord in profile.entityRecords)
					{
						if (entityRecord.worksate != EWorkingState.Inefficient)
						{
							Utils.EntityRecordButton(entityRecord);
						}
					}
				}
				GUILayout.EndVertical();
			}
			else if (profile.entityIds.Count > 0)
			{
				GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>());
				GUILayout.Label(SP.naviToMachineText, Array.Empty<GUILayoutOption>());
				bool flag = false;
				if (GUILayout.Button("<", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.BaseScale * 2f) }))
				{
					entityCursor = (ushort)((entityCursor + profile.entityIds.Count - 1) % profile.entityIds.Count);
					flag = true;
				}
				if (GUILayout.Button(">", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.BaseScale * 2f) }))
				{
					entityCursor = (ushort)((entityCursor + 1) % profile.entityIds.Count);
					flag = true;
				}
				if (flag)
				{
					int entityId = profile.entityIds[entityCursor];
					Utils.NavigateToEntity(Plugin.MainTable.GetFactory(), entityId);
				}
				GUILayout.FlexibleSpace();
				GUILayout.EndHorizontal();
			}
			if (profile.materialCount > 0)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(SP.itemIdConsumeText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.RateWidth + 2f) });
				for (int i = 0; i < profile.itemRefSpeeds.Count; i++)
				{
					float num4 = profile.itemRefSpeeds[i];
					if (num4 <= 0f)
					{
						Utils.FocusItemIconButton(profile.itemIds[i]);
						string text2 = " " + Utils.RateKMG(num4 * (float)profile.TotalMachineCount * (float)CalDB.CountMultiplier);
						if (ModSettings.ShowRealtimeRate.Value)
						{
							text2 = text2 + "\n(" + Utils.RateKMG(num4 * profile.WorkingMachineCount * (float)CalDB.CountMultiplier) + ")";
						}
						GUILayout.Label(text2, Array.Empty<GUILayoutOption>());
					}
				}
				GUILayout.FlexibleSpace();
				GUILayout.EndHorizontal();
			}
			if (profile.productCount > 0)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(SP.itemIdProduceText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.RateWidth + 2f) });
				for (int j = 0; j < profile.itemRefSpeeds.Count; j++)
				{
					float num5 = profile.itemRefSpeeds[j];
					if (num5 >= 0f)
					{
						Utils.FocusItemIconButton(profile.itemIds[j]);
						string text3 = " " + Utils.RateKMG(num5 * (float)profile.TotalMachineCount * (float)CalDB.CountMultiplier);
						if (ModSettings.ShowRealtimeRate.Value)
						{
							text3 = text3 + "\n(" + Utils.RateKMG(num5 * profile.WorkingMachineCount * (float)CalDB.CountMultiplier) + ")";
						}
						GUILayout.Label(text3, Array.Empty<GUILayoutOption>());
					}
				}
				GUILayout.FlexibleSpace();
				GUILayout.EndHorizontal();
			}
			GUILayout.EndVertical();
		}
	}
	public class ProfilePanel
	{
		private readonly List<ProfileEntry> profileEntries = new List<ProfileEntry>();

		private Vector2 scrollPosition;

		private float totalMaxIncCost;

		private float workingIncCost;

		private float totalMaxPowerCost;

		private float workingPowerCost;

		private float totalProduction;

		private float workingProduction;

		private float totalConsumption;

		private float workingConsumption;

		public static int FocusItmeId { get; set; }

		public static bool ExpandOnly { get; set; }

		public static bool WorkingOnly { get; set; }

		public ProfilePanel(StatTable statTable)
		{
			foreach (ProductionProfile profile in statTable.Profiles)
			{
				profileEntries.Add(new ProfileEntry(profile));
			}
		}

		public void DrawPanel()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			scrollPosition = GUILayout.BeginScrollView(scrollPosition, Array.Empty<GUILayoutOption>());
			DrawHeader();
			if (FocusItmeId != 0)
			{
				DrawFocusProfileList();
			}
			else
			{
				DrawNormalProfileList();
			}
			GUILayout.EndScrollView();
			GUILayout.EndVertical();
		}

		private void DrawHeader()
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (FocusItmeId != 0)
			{
				Utils.FocusItemIconButton(FocusItmeId);
				string text = "";
				if (totalConsumption > float.Epsilon)
				{
					text = SP.totalConsumptionText + Utils.RateKMG(totalConsumption * (float)CalDB.CountMultiplier);
					if (ModSettings.ShowRealtimeRate.Value)
					{
						text = text + " (" + Utils.RateKMG(workingConsumption * (float)CalDB.CountMultiplier) + ")";
					}
				}
				if (totalProduction > float.Epsilon)
				{
					if (text != "")
					{
						text += "\n";
					}
					text = text + SP.totalProductionText + Utils.RateKMG(totalProduction * (float)CalDB.CountMultiplier);
					if (ModSettings.ShowRealtimeRate.Value)
					{
						text = text + " (" + Utils.RateKMG(workingProduction * (float)CalDB.CountMultiplier) + ")";
					}
				}
				GUILayout.Label(text, Array.Empty<GUILayoutOption>());
				totalProduction = (workingProduction = (totalConsumption = (workingConsumption = 0f)));
				GUILayout.FlexibleSpace();
				ExpandOnly = GUILayout.Toggle(ExpandOnly, SP.expandedOnlyText, Array.Empty<GUILayoutOption>());
			}
			else
			{
				string text2 = SP.proliferatorCostText + Utils.KMG((0f - totalMaxIncCost) * CalDB.IncToProliferatorRatio * (float)CalDB.CountMultiplier);
				if (ModSettings.ShowRealtimeRate.Value)
				{
					text2 = text2 + " (" + Utils.KMG((0f - workingIncCost) * CalDB.IncToProliferatorRatio * (float)CalDB.CountMultiplier) + ")";
				}
				GUILayout.Label(text2, Array.Empty<GUILayoutOption>());
				totalMaxIncCost = (workingIncCost = 0f);
				GUILayout.FlexibleSpace();
				ExpandOnly = GUILayout.Toggle(ExpandOnly, SP.expandedOnlyText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(Utils.IconHeight) });
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			string text3 = SP.powerCostText + Utils.KMG(totalMaxPowerCost * (float)CalDB.CountMultiplier);
			text3 += "W";
			if (ModSettings.ShowRealtimeRate.Value)
			{
				text3 = text3 + " (" + Utils.KMG(workingPowerCost) + "W)";
			}
			GUILayout.Label(text3, Array.Empty<GUILayoutOption>());
			totalMaxPowerCost = (workingPowerCost = 0f);
			GUILayout.FlexibleSpace();
			WorkingOnly = GUILayout.Toggle(WorkingOnly, SP.workingOnlyText, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
		}

		private void DrawNormalProfileList()
		{
			foreach (ProfileEntry profileEntry in profileEntries)
			{
				ProductionProfile profile = profileEntry.Profile;
				if ((ExpandOnly && !profileEntry.IsExpand) || (WorkingOnly && profile.WorkingMachineCount < float.Epsilon))
				{
					continue;
				}
				float num = profile.TotalMachineCount;
				float num2 = num - profile.WorkingMachineCount;
				totalMaxIncCost += profile.incCost * num;
				workingIncCost += profile.incCost * profile.WorkingMachineCount;
				totalMaxPowerCost += profile.workEnergyW * num;
				workingPowerCost += profile.workEnergyW * profile.WorkingMachineCount + profile.idleEnergyW * num2;
				bool flag = false;
				for (int i = 0; i < profile.itemIds.Count; i++)
				{
					if (profile.itemRefSpeeds[i] > 0f)
					{
						profileEntry.DrawProfileItem(i);
						flag = true;
					}
				}
				if (flag)
				{
					continue;
				}
				for (int j = 0; j < profile.itemIds.Count; j++)
				{
					if (profile.itemRefSpeeds[j] < 0f)
					{
						profileEntry.DrawProfileItem(j);
					}
				}
			}
		}

		private void DrawFocusProfileList()
		{
			foreach (ProfileEntry profileEntry in profileEntries)
			{
				ProductionProfile profile = profileEntry.Profile;
				if ((ExpandOnly && !profileEntry.IsExpand) || (WorkingOnly && profile.WorkingMachineCount < float.Epsilon))
				{
					continue;
				}
				float num = profile.TotalMachineCount;
				float num2 = num - profile.WorkingMachineCount;
				bool flag = false;
				for (int i = 0; i < profile.itemIds.Count; i++)
				{
					if (profile.itemIds[i] == FocusItmeId)
					{
						if (profile.itemRefSpeeds[i] > float.Epsilon)
						{
							profileEntry.DrawProfileItem(i);
							totalProduction += profile.itemRefSpeeds[i] * num;
							workingProduction += profile.itemRefSpeeds[i] * profile.WorkingMachineCount;
						}
						else if (profile.itemRefSpeeds[i] < -1E-45f)
						{
							profileEntry.DrawProfileItem(i);
							totalConsumption += (0f - profile.itemRefSpeeds[i]) * num;
							workingConsumption += (0f - profile.itemRefSpeeds[i]) * profile.WorkingMachineCount;
						}
						flag = true;
					}
				}
				if (flag)
				{
					totalMaxIncCost += profile.incCost * num;
					workingIncCost += profile.incCost * profile.WorkingMachineCount;
					totalMaxPowerCost += profile.workEnergyW * num;
					workingPowerCost += profile.workEnergyW * profile.WorkingMachineCount + profile.idleEnergyW * num2;
				}
			}
		}
	}
	public class RatePanel
	{
		private Vector2 scrollPosition;

		private readonly StatTable statTable;

		private static bool itemIdProduceWorkingOnly;

		private static bool itemIdConsumeWorkingOnly;

		private static bool itemIdIntermediateWorkingOnly;

		public bool IsActive { get; set; }

		public RatePanel(StatTable statTable)
		{
			this.statTable = statTable;
		}

		public void DrawPanel(float ratePanelWidth)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(ratePanelWidth) });
			scrollPosition = GUILayout.BeginScrollView(scrollPosition, Array.Empty<GUILayoutOption>());
			if (statTable.ItemIdProduce.Count > 0)
			{
				DrawSectionWithToggle(SP.itemIdProduceText, statTable.ItemIdProduce, ref itemIdProduceWorkingOnly);
			}
			if (statTable.ItemIdConsume.Count > 0)
			{
				DrawSectionWithToggle(SP.itemIdConsumeText, statTable.ItemIdConsume, ref itemIdConsumeWorkingOnly);
			}
			if (statTable.ItemIdIntermediate.Count > 0)
			{
				DrawSectionWithToggle(SP.itemIdIntermediateText, statTable.ItemIdIntermediate, ref itemIdIntermediateWorkingOnly);
			}
			GUILayout.EndScrollView();
			GUILayout.EndVertical();
		}

		private void DrawSectionWithToggle(string sectionName, List<int> itemIds, ref bool workingOnly)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(sectionName, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			workingOnly = GUILayout.Toggle(workingOnly, SP.workingOnlyText, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			DrawList(itemIds, workingOnly);
			GUILayout.EndVertical();
		}

		private void DrawList(List<int> itemIds, bool workingOnly)
		{
			foreach (int itemId in itemIds)
			{
				if (!workingOnly || statTable.ItemEstRates[itemId] != 0f || statTable.WorkingItemIds.Contains(itemId))
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					Utils.FocusItemIconButton(itemId);
					GUILayout.Label(Utils.RateKMG(statTable.ItemRefRates[itemId] * (float)CalDB.CountMultiplier), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(Utils.RateWidth) });
					if (ModSettings.ShowRealtimeRate.Value)
					{
						GUILayout.Label(Utils.RateKMG(statTable.ItemEstRates[itemId] * (float)CalDB.CountMultiplier), Array.Empty<GUILayoutOption>());
					}
					GUILayout.EndHorizontal();
				}
			}
		}
	}
	public class SettingPanel
	{
		private Vector2 scrollPosition;

		private string rateUnitInput;

		private string incLevelInput;

		private bool use4stack;

		public bool IsActive { get; set; }

		public SettingPanel(StatTable _)
		{
		}

		public void RefreshInputs()
		{
			rateUnitInput = ModSettings.RateUnit.Value.ToString();
			incLevelInput = ModSettings.IncLevel.Value.ToString();
		}

		public void DrawPanel()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			scrollPosition = GUILayout.BeginScrollView(scrollPosition, Array.Empty<GUILayoutOption>());
			DisplaySettingsPanel();
			CalculateSettingsPanel();
			UISettingsPanel();
			GUILayout.EndScrollView();
			GUILayout.EndVertical();
		}

		public void RateUnitQuickBar()
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button(SP.perMinuteText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.InputWidth) }))
			{
				ModSettings.RateUnit.Value = 1;
				RefreshInputs();
				UIWindow.RefreshTitle();
			}
			if (GUILayout.Button(SP.perSecondText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.InputWidth) }))
			{
				ModSettings.RateUnit.Value = 60;
				RefreshInputs();
				UIWindow.RefreshTitle();
			}
			for (int i = 0; i < 3; i++)
			{
				if (GUILayout.Button(SP.perBeltTexts[i], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.MediumButtonWidth - 2f) }))
				{
					ModSettings.RateUnit.Value = (use4stack ? (CalDB.BeltSpeeds[i] * 4) : CalDB.BeltSpeeds[i]);
					RefreshInputs();
					UIWindow.RefreshTitle();
				}
			}
			use4stack = GUILayout.Toggle(use4stack, "4 stack", Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
		}

		public void CountMultiplierSetter()
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(SP.countMultiplierText + ": " + CalDB.CountMultiplier + " ", Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("-5", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.RateWidth) }))
			{
				CalDB.CountMultiplier -= 5;
			}
			if (GUILayout.Button("-1", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.RateWidth) }))
			{
				CalDB.CountMultiplier--;
			}
			if (GUILayout.Button("+1", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.RateWidth) }))
			{
				CalDB.CountMultiplier++;
			}
			if (GUILayout.Button("+5", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.RateWidth) }))
			{
				CalDB.CountMultiplier += 5;
			}
			if (GUILayout.Button(SP.recalculateText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.InputWidth) }))
			{
				PlanetFactory factory;
				List<int> entityIds = Plugin.MainTable.GetEntityIds(out factory);
				Plugin.CreateMainTable(factory, entityIds);
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			if (CalDB.CountMultiplier < 1)
			{
				CalDB.CountMultiplier = 1;
			}
		}

		private void DisplaySettingsPanel()
		{
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			MiddleLabel(SP.displaySettingsText);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			ConfigBoolField(SP.showRealTimeRateText, ModSettings.ShowRealtimeRate);
			ConfigBoolField(SP.showInPercentageText, ModSettings.ShowWorkingRateInPercentage);
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			ConfigIntField(SP.rateUnitText, ref rateUnitInput, ModSettings.RateUnit, 1, 14400);
			if (GUILayout.Button("x2", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.ShortButtonWidth) }))
			{
				ConfigEntry<int> rateUnit = ModSettings.RateUnit;
				rateUnit.Value *= 2;
				RefreshInputs();
				UIWindow.RefreshTitle();
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			RateUnitQuickBar();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			int num = (int)GUILayout.HorizontalSlider((float)ModSettings.FontSize.Value, 8f, 48f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.InputWidth * 4f) });
			if (num != ModSettings.FontSize.Value)
			{
				ModSettings.FontSize.Value = num;
				Utils.SetScale(num);
			}
			GUILayout.Label(SP.fontSizeText + ": " + ModSettings.FontSize.Value, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
		}

		private void CalculateSettingsPanel()
		{
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			MiddleLabel(SP.calculateSettingsText);
			bool flag = false;
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (ConfigBoolField(SP.forceIncText, ModSettings.ForceInc))
			{
				flag = true;
			}
			if (ConfigBoolField(SP.forceLens, ModSettings.ForceLens))
			{
				flag = true;
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (ConfigIntField(SP.incLevelText, ref incLevelInput, ModSettings.IncLevel, -1, 10))
			{
				flag = true;
			}
			if (GUILayout.Button("-1", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.ShortButtonWidth) }))
			{
				if (ModSettings.IncLevel.Value >= 0)
				{
					ConfigEntry<int> incLevel = ModSettings.IncLevel;
					int value = incLevel.Value;
					incLevel.Value = value - 1;
				}
				flag = true;
			}
			if (GUILayout.Button("+1", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.ShortButtonWidth) }))
			{
				if (ModSettings.IncLevel.Value < 10)
				{
					ConfigEntry<int> incLevel2 = ModSettings.IncLevel;
					int value = incLevel2.Value;
					incLevel2.Value = value + 1;
				}
				flag = true;
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			if (flag)
			{
				PlanetFactory factory;
				List<int> entityIds = Plugin.MainTable.GetEntityIds(out factory);
				Plugin.CreateMainTable(factory, entityIds);
			}
			GUILayout.EndVertical();
		}

		private void UISettingsPanel()
		{
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			MiddleLabel(SP.uiSettingsText);
			ConfigBoolField(SP.enableQuickBarButtonText, ModSettings.EnableQuickBarButton);
			ConfigBoolField(SP.enableSingleBuildingText, ModSettings.EnableSingleBuildingClick);
			GUILayout.EndVertical();
		}

		private void MiddleLabel(string label)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.Label(label, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
		}

		private bool ConfigIntField(string name, ref string fieldString, ConfigEntry<int> configEntry, int min, int max = int.MaxValue)
		{
			bool result = false;
			GUILayout.Label(name, Array.Empty<GUILayoutOption>());
			fieldString = GUILayout.TextField(fieldString, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.InputWidth) });
			if (GUILayout.Button(SP.settingButtonText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.ShortButtonWidth) }))
			{
				if (int.TryParse(fieldString, out var result2))
				{
					configEntry.Value = (int)Maths.Clamp((double)result2, (double)min, (double)max);
					result = true;
				}
				else
				{
					fieldString = configEntry.Value.ToString();
				}
			}
			return result;
		}

		private bool ConfigBoolField(string name, ConfigEntry<bool> configEntry)
		{
			bool value = configEntry.Value;
			bool flag = GUILayout.Toggle(value, name, Array.Empty<GUILayoutOption>());
			if (value != flag)
			{
				configEntry.Value = flag;
				return true;
			}
			return false;
		}
	}
	public class UIWindow
	{
		private const int windowId = 432145525;

		private Rect windowRect = new Rect(100f, 150f, 580f, 400f);

		private string windowName = "Rate Monitor";

		private bool isResizingWindow;

		private bool isResizingPanel;

		private RatePanel ratePanel;

		private ProfilePanel profilePanel;

		private OperactionPanel operactionPanel;

		private SettingPanel settingPanel;

		private string titleText = "";

		private bool isExpandTitleSettings;

		public static UIWindow Instance { get; private set; }

		public static bool InResizingArea { get; private set; }

		public static bool InWindow { get; private set; }

		public StatTable Table { get; private set; }

		public float RatePanelWidth { get; private set; } = 190f;


		public float ProfilePanelWidth { get; private set; } = 350f;


		public static void OnGUI()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			InWindow = false;
			if (Plugin.MainTable == null)
			{
				return;
			}
			if (Instance == null)
			{
				Instance = new UIWindow();
			}
			if (Instance.Table != Plugin.MainTable)
			{
				Instance.Init(Plugin.MainTable);
			}
			if (VFInput.escape)
			{
				VFInput.UseEscape();
				Plugin.SaveCurrentTable();
				Plugin.MainTable = null;
				return;
			}
			if (!Utils.IsInit)
			{
				Utils.Init();
				Utils.SetScale(ModSettings.FontSize.Value);
			}
			GUISkin skin = GUI.skin;
			Color backgroundColor = GUI.backgroundColor;
			GUI.skin = Utils.CustomSkin;
			GUI.backgroundColor = new Color(1f, 1f, 1f, 1f);
			Instance.windowRect = GUILayout.Window(432145525, Instance.windowRect, new WindowFunction(Instance.DrawWindow), Instance.windowName, Array.Empty<GUILayoutOption>());
			InResizingArea = false;
			if (Instance.ratePanel.IsActive)
			{
				Instance.HandlePanelResize(ref Instance.windowRect);
			}
			Instance.HandleWindowResize(ref Instance.windowRect);
			GUI.backgroundColor = backgroundColor;
			GUI.skin = skin;
		}

		public static void RefreshTitle()
		{
			if (Instance != null)
			{
				if (!SP.IsInit)
				{
					SP.Init();
				}
				Instance.titleText = SP.rateUnitText + ModSettings.RateUnit.Value + "/min  ";
				if (CalDB.ForceInc)
				{
					Instance.titleText += SP.forceText;
				}
				UIWindow instance = Instance;
				instance.titleText = instance.titleText + SP.incLevelText + CalDB.IncLevel + "  ";
				if (Instance.Table != null)
				{
					Instance.windowName = "Rate Monitor (" + Instance.Table.GetEntityCount() + ")";
				}
			}
		}

		public static void LoadUIWindowConfig()
		{
			if (Instance == null)
			{
				Instance = new UIWindow();
			}
			((Rect)(ref Instance.windowRect)).width = ModSettings.WindowWidth.Value;
			((Rect)(ref Instance.windowRect)).height = ModSettings.WindowHeight.Value;
			Instance.RatePanelWidth = ModSettings.WindowRatePanelWidth.Value;
			Instance.ProfilePanelWidth = ((Rect)(ref Instance.windowRect)).width - Instance.RatePanelWidth - 40f;
		}

		public static void SaveUIWindowConfig()
		{
			if (Instance != null)
			{
				ModSettings.WindowWidth.Value = ((Rect)(ref Instance.windowRect)).width;
				ModSettings.WindowHeight.Value = ((Rect)(ref Instance.windowRect)).height;
				ModSettings.WindowRatePanelWidth.Value = Instance.RatePanelWidth;
			}
		}

		private void Init(StatTable statTable)
		{
			Table = statTable;
			ratePanel = new RatePanel(statTable);
			profilePanel = new ProfilePanel(statTable);
			settingPanel = new SettingPanel(statTable);
			operactionPanel = new OperactionPanel(statTable);
			RefreshTitle();
		}

		private void DrawWindow(int windowID)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			if (GUI.Button(new Rect(((Rect)(ref windowRect)).width - 3f - (Utils.BaseScale + 4f), 3f, Utils.BaseScale + 4f, Utils.BaseScale + 4f), "X"))
			{
				Plugin.SaveCurrentTable();
				Plugin.MainTable = null;
				return;
			}
			GUILayout.Space(Utils.BaseScale - 14f);
			DrawTitle();
			GUILayout.Space(2f);
			if (settingPanel.IsActive)
			{
				settingPanel.DrawPanel();
			}
			else if (operactionPanel.IsActive)
			{
				operactionPanel.DrawPanel();
			}
			else
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				ratePanel.DrawPanel(RatePanelWidth);
				profilePanel.DrawPanel();
				GUILayout.EndHorizontal();
			}
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref windowRect)).width, 20f));
		}

		private void DrawTitle()
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button(isExpandTitleSettings ? "-" : "+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.BaseScale * 1.5f) }))
			{
				isExpandTitleSettings = !isExpandTitleSettings;
			}
			GUILayout.Label(titleText, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("<", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.BaseScale * 2f) }))
			{
				Plugin.LoadLastTable();
			}
			if (GUILayout.Button(operactionPanel.IsActive ? SP.backButtonText : SP.operationButtonText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.ShortButtonWidth) }))
			{
				operactionPanel.IsActive = !operactionPanel.IsActive;
				if (operactionPanel.IsActive)
				{
					settingPanel.IsActive = false;
				}
			}
			if (GUILayout.Button(settingPanel.IsActive ? SP.backButtonText : SP.settingButtonText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Utils.ShortButtonWidth) }))
			{
				settingPanel.IsActive = !settingPanel.IsActive;
				if (settingPanel.IsActive)
				{
					settingPanel.RefreshInputs();
					operactionPanel.IsActive = false;
				}
			}
			ratePanel.IsActive = !operactionPanel.IsActive && !settingPanel.IsActive;
			GUILayout.EndHorizontal();
			if (isExpandTitleSettings)
			{
				settingPanel.RateUnitQuickBar();
				settingPanel.CountMultiplierSetter();
			}
			else
			{
				CalDB.CountMultiplier = 1;
			}
		}

		private void HandleWindowResize(ref Rect windowRect)
		{
			//IL_0005: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Invalid comparison between Unknown and I4
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			Vector2 mousePosition = Event.current.mousePosition;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref windowRect)).xMax - 10f, ((Rect)(ref windowRect)).yMax - 10f, 25f, 25f);
			InWindow = ((Rect)(ref windowRect)).Contains(mousePosition);
			if (((Rect)(ref val)).Contains(mousePosition) && !InWindow)
			{
				InResizingArea = true;
				GUI.Box(val, "↘");
				if ((int)Event.current.type == 0)
				{
					isResizingWindow = true;
				}
			}
			if ((int)Event.current.type == 1)
			{
				isResizingWindow = false;
			}
			if (isResizingWindow)
			{
				((Rect)(ref windowRect)).xMax = Math.Max(Event.current.mousePosition.x, ((Rect)(ref windowRect)).xMin + 30f);
				((Rect)(ref windowRect)).yMax = Math.Max(Event.current.mousePosition.y, ((Rect)(ref windowRect)).yMin + 30f);
				ProfilePanelWidth = ((Rect)(ref windowRect)).width - RatePanelWidth - 40f;
			}
			if (InWindow && (Input.GetMouseButton(0) || Input.GetMouseButtonDown(0)))
			{
				SelectionTool tool = SelectionTool_Patches.tool;
				if (tool == null || !tool.IsSelecting)
				{
					Input.ResetInputAxes();
				}
			}
		}

		private void HandlePanelResize(ref Rect windowRect)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Invalid comparison between Unknown and I4
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref windowRect)).xMin + RatePanelWidth + 3f + 2f, ((Rect)(ref windowRect)).yMin, 18f, ((Rect)(ref windowRect)).height);
			if (((Rect)(ref val)).Contains(Event.current.mousePosition))
			{
				InResizingArea = true;
				GUI.Box(val, "");
				if ((int)Event.current.type == 0)
				{
					isResizingPanel = true;
				}
			}
			if ((int)Event.current.type == 1)
			{
				isResizingPanel = false;
			}
			if (isResizingPanel)
			{
				RatePanelWidth = Event.current.mousePosition.x - ((Rect)(ref windowRect)).xMin - 12f;
				RatePanelWidth = (float)Maths.Clamp((double)RatePanelWidth, 10.0, (double)(((Rect)(ref windowRect)).width - 60f));
				ProfilePanelWidth = ((Rect)(ref windowRect)).width - RatePanelWidth - 40f;
			}
		}
	}
	public static class Utils
	{
		public static bool IsInit = false;

		public static GUISkin CustomSkin;

		public static float BaseScale = 16f;

		public static float RecordHeight = 24f;

		public static float IconHeight = 32f;

		public static float RateWidth = 56f;

		public static float ShortButtonWidth = 72f;

		public static float MediumButtonWidth = 86f;

		public static float InputWidth = 100f;

		public static float LargeButtonWidth = 200f;

		private static GUILayoutOption[] iconoptions;

		private static GUIContent iconTextContent;

		private static GUIStyle itemIconStyle;

		private static GUIStyle focusItemIconStyle;

		private static GUIStyle normalIconStyle;

		public static void SetScale(float baseScale)
		{
			float num = baseScale / 16f;
			BaseScale = baseScale;
			RecordHeight = 24f * num;
			IconHeight = 32f * num;
			RateWidth = 56f * num;
			ShortButtonWidth = 72f * num;
			MediumButtonWidth = 86f * num;
			LargeButtonWidth = 200f * num;
			InputWidth = 100f * num;
			iconoptions = (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(IconHeight),
				GUILayout.Height(IconHeight)
			};
			UpdateFontSize((int)(baseScale + 0.5f));
		}

		public static void OnDestroy()
		{
			Object.Destroy((Object)(object)CustomSkin);
		}

		public static void Init()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00c1: 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_00db: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			IsInit = true;
			CustomSkin = ScriptableObject.CreateInstance<GUISkin>();
			CloneCurrentSkinSettings();
			iconoptions = (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(IconHeight),
				GUILayout.Height(IconHeight)
			};
			iconTextContent = new GUIContent();
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, new Color(1f, 1f, 0.8f, 0.6f));
			val.Apply();
			Texture2D val2 = new Texture2D(1, 1);
			val2.SetPixel(0, 0, new Color(1f, 1f, 0.7f, 0.3f));
			val2.Apply();
			Texture2D val3 = new Texture2D(1, 1);
			val3.SetPixel(0, 0, new Color(0.5f, 0.5f, 1f, 0.3f));
			val3.Apply();
			normalIconStyle = new GUIStyle();
			normalIconStyle.hover.background = val3;
			itemIconStyle = new GUIStyle();
			itemIconStyle.hover.background = val2;
			focusItemIconStyle = new GUIStyle();
			focusItemIconStyle.normal.background = val;
			focusItemIconStyle.hover.background = val2;
		}

		private static void CloneCurrentSkinSettings()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Expected O, but got Unknown
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Expected O, but got Unknown
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Expected O, but got Unknown
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Expected O, but got Unknown
			if (!((Object)(object)CustomSkin == (Object)null) && !((Object)(object)GUI.skin == (Object)null))
			{
				CustomSkin.box = new GUIStyle(GUI.skin.box);
				CustomSkin.button = new GUIStyle(GUI.skin.button);
				CustomSkin.label = new GUIStyle(GUI.skin.label);
				CustomSkin.textField = new GUIStyle(GUI.skin.textField);
				CustomSkin.textArea = new GUIStyle(GUI.skin.textArea);
				CustomSkin.toggle = new GUIStyle(GUI.skin.toggle);
				CustomSkin.window = new GUIStyle(GUI.skin.window);
				CustomSkin.horizontalSlider = new GUIStyle(GUI.skin.horizontalSlider);
				CustomSkin.horizontalSliderThumb = new GUIStyle(GUI.skin.horizontalSliderThumb);
				CustomSkin.verticalSlider = new GUIStyle(GUI.skin.verticalSlider);
				CustomSkin.verticalSliderThumb = new GUIStyle(GUI.skin.verticalSliderThumb);
				CustomSkin.horizontalScrollbar = new GUIStyle(GUI.skin.horizontalScrollbar);
				CustomSkin.horizontalScrollbarThumb = new GUIStyle(GUI.skin.horizontalScrollbarThumb);
				CustomSkin.horizontalScrollbarLeftButton = new GUIStyle(GUI.skin.horizontalScrollbarLeftButton);
				CustomSkin.horizontalScrollbarRightButton = new GUIStyle(GUI.skin.horizontalScrollbarRightButton);
				CustomSkin.verticalScrollbar = new GUIStyle(GUI.skin.verticalScrollbar);
				CustomSkin.verticalScrollbarThumb = new GUIStyle(GUI.skin.verticalScrollbarThumb);
				CustomSkin.verticalScrollbarUpButton = new GUIStyle(GUI.skin.verticalScrollbarUpButton);
				CustomSkin.verticalScrollbarDownButton = new GUIStyle(GUI.skin.verticalScrollbarDownButton);
				CustomSkin.scrollView = new GUIStyle(GUI.skin.scrollView);
				CustomSkin.customStyles = (GUIStyle[])((GUI.skin.customStyles != null) ? ((Array)(GUIStyle[])GUI.skin.customStyles.Clone()) : ((Array)new GUIStyle[0]));
				CustomSkin.font = GUI.skin.font;
			}
		}

		private static void UpdateFontSize(int fontSize)
		{
			if (!((Object)(object)CustomSkin == (Object)null))
			{
				CustomSkin.label.fontSize = fontSize;
				CustomSkin.button.fontSize = fontSize;
				CustomSkin.toggle.fontSize = fontSize;
				CustomSkin.textField.fontSize = fontSize;
				CustomSkin.textArea.fontSize = fontSize;
				CustomSkin.box.fontSize = fontSize;
				CustomSkin.window.fontSize = fontSize;
			}
		}

		public static void FocusItemIconButton(int itemId)
		{
			bool flag = ProfilePanel.FocusItmeId == itemId;
			ItemProto obj = ((ProtoSet<ItemProto>)(object)LDB.items).Select(itemId);
			if (GUILayout.Button((Texture)(object)((obj != null) ? obj.iconSprite.texture : null), flag ? focusItemIconStyle : itemIconStyle, iconoptions))
			{
				ProfilePanel.FocusItmeId = ((!flag) ? itemId : 0);
			}
		}

		public static bool RecipeExpandButton(int itemId)
		{
			ItemProto obj = ((ProtoSet<ItemProto>)(object)LDB.items).Select(itemId);
			return GUILayout.Button((Texture)(object)((obj != null) ? obj.iconSprite.texture : null), normalIconStyle, iconoptions);
		}

		public static void EntityRecordButton(EntityRecord entityRecord)
		{
			ItemProto obj = ((ProtoSet<ItemProto>)(object)LDB.items).Select(entityRecord.itemId);
			Texture2D image = ((obj != null) ? obj.iconSprite.texture : null);
			iconTextContent.image = (Texture)(object)image;
			iconTextContent.text = entityRecord.ToString();
			if (GUILayout.Button(iconTextContent, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(RecordHeight) }))
			{
				NavigateToEntity(UIWindow.Instance.Table.GetFactory(), entityRecord.entityId);
			}
		}

		public static void NavigateToEntity(PlanetFactory factory, int entityId)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (GameMain.mainPlayer == null || factory == null)
			{
				return;
			}
			if (GameMain.data.localPlanet?.factory == factory)
			{
				if (entityId <= 0 || entityId >= factory.entityPool.Length)
				{
					UIRealtimeTip.Popup($"EntityId {entityId} exceed Pool length {factory.entityPool.Length}!", true, 0);
					return;
				}
				Vector3 pos = factory.entityPool[entityId].pos;
				GameMain.data.mainPlayer.Order(OrderNode.MoveTo(pos), false);
				UIRealtimeTip.Popup($"Move to entity {entityId}", true, 0);
			}
			else
			{
				GameMain.mainPlayer.navigation.indicatorAstroId = factory.planetId;
			}
		}

		public static string RateKMG(float num)
		{
			return KMG(num / (float)ModSettings.RateUnit.Value);
		}

		public static string KMG(float num)
		{
			if (num < 100f)
			{
				return num.ToString("0.##");
			}
			if (num < 1000f)
			{
				return num.ToString("0.#");
			}
			if (num < 10000f)
			{
				return num.ToString();
			}
			string arg;
			if (num < 1000000f)
			{
				arg = "k";
				num /= 1000f;
			}
			else if (num < 1E+09f)
			{
				arg = "M";
				num /= 1000000f;
			}
			else if (num < 1E+12f)
			{
				arg = "G";
				num /= 1E+09f;
			}
			else if (num < 1E+15f)
			{
				arg = "T";
				num /= 1E+12f;
			}
			else if (num < 1E+18f)
			{
				arg = "P";
				num /= 1E+15f;
			}
			else
			{
				arg = "E";
				num /= 1E+18f;
			}
			if ((double)num < 9.995)
			{
				return $"{num:0.000} {arg}";
			}
			if ((double)num < 99.95)
			{
				return $"{num:0.00} {arg}";
			}
			if ((double)num < 999.5)
			{
				return $"{num:0.0} {arg}";
			}
			return $"{num} {arg}";
		}
	}
}
namespace RateMonitor.Patches
{
	public class MainPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameData), "GameTick")]
		private static void UpdateMonitor(bool __runOriginal)
		{
			if (Plugin.MainTable != null && __runOriginal)
			{
				try
				{
					Plugin.MainTable.OnGameTick();
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)ex);
					Plugin.MainTable.OnError();
				}
				if (UIWindow.InResizingArea)
				{
					UICursor.SetCursor((ECursor)13);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameMain), "End")]
		private static void OnGameEnd()
		{
			Plugin.MainTable = null;
			UIWindow.SaveUIWindowConfig();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(VFInput), "OnUpdate")]
		private static void PreventZoomInWindow()
		{
			if (UIWindow.InWindow)
			{
				VFInput.mouseWheel = 0f;
			}
		}
	}
	public class QuickBarButton
	{
		private static UIButton enableButton;

		public static void Enable(bool enable)
		{
			if (enable)
			{
				CrateButton();
			}
			else
			{
				Destroy();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameMain), "Start")]
		public static void CrateButton()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)enableButton != (Object)null)
			{
				return;
			}
			try
			{
				UIButton infiniteEnergyButton = UIRoot.instance.uiGame.energyBar.infiniteEnergyButton;
				GameObject val = Object.Instantiate<GameObject>(((Component)infiniteEnergyButton).gameObject, ((Component)infiniteEnergyButton).transform.parent.parent);
				((Object)val).name = "[Rate Monitor] Toggle";
				RectTransform val2 = (RectTransform)((Component)UIRoot.instance.uiGame.energyBar.energyChangesTip).transform;
				Transform transform = val.transform;
				float x = ((Transform)val2).localPosition.x;
				Rect rect = val2.rect;
				transform.localPosition = new Vector3(x - ((Rect)(ref rect)).width / 1.5f - 20f, val.transform.localPosition.y, val.transform.localPosition.z);
				val.SetActive(true);
				((Component)val.transform.Find("icon")).GetComponent<Image>().sprite = ((ProtoSet<SignalProto>)(object)LDB.signals).Select(511).iconSprite;
				enableButton = val.GetComponent<UIButton>();
				enableButton.onClick += OnButtonClick;
				enableButton.tips.corner = 8;
				enableButton.tips.tipTitle = "Rate Monitor";
				enableButton.tips.tipText = "Click to open/close the window and selection tool";
				enableButton.transitions[1].normalColor = new Color(1f, 1f, 1f, 0.8f);
				enableButton.transitions[1].mouseoverColor = new Color(1f, 1f, 1f, 1f);
				enableButton.transitions[0].mouseoverColor = new Color(0.6f, 0.6f, 1f, 0.2f);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)"Error when creating button!");
				Plugin.Log.LogWarning((object)ex);
				ModSettings.EnableQuickBarButton.Value = false;
			}
		}

		public static void OnButtonClick(int _)
		{
			if (Plugin.MainTable == null)
			{
				if (!Plugin.LoadLastTable())
				{
					Plugin.CreateMainTable(null, new List<int>(0));
				}
				if (VFInput.readyToBuild)
				{
					SelectionTool_Patches.SetEnable(active: true);
				}
			}
			else if (VFInput.control)
			{
				if (VFInput.readyToBuild)
				{
					SelectionTool_Patches.SetEnable(active: true);
				}
			}
			else
			{
				Plugin.SaveCurrentTable();
				Plugin.MainTable = null;
				SelectionTool_Patches.SetEnable(active: false);
			}
		}

		public static void Destroy()
		{
			UIButton obj = enableButton;
			Object.Destroy((Object)(object)((obj != null) ? ((Component)obj).gameObject : null));
		}
	}
	public class SelectionTool : BuildTool
	{
		public Action<PlanetFactory, HashSet<int>> OnSelectionFinish;

		private bool castTerrain;

		private bool castGround;

		private Vector3 castGroundPos = Vector3.zero;

		private Vector3 castGroundPosSnapped = Vector3.zero;

		private int castObjectId;

		private bool cursorValid;

		private Vector3 cursorTarget;

		private Vector3 startGroundPosSnapped = Vector3.zero;

		private Vector3 lastGroundPosSnapped = Vector3.zero;

		public BPGratBox selectGratBox = BPGratBox.zero;

		private BPGratBox lastSelectGratBox = BPGratBox.zero;

		private BPGratBox selectArcBox = BPGratBox.zero;

		private HashSet<int> selectObjIds;

		private BuildPreview[] bpPool;

		private AnimData[] animPool;

		private ComputeBuffer animBuffer;

		private int bpCursor = 1;

		private int bpPoolCapacity;

		private int[] bpRecycle;

		private int bpRecycleCursor;

		public bool IsEnable { get; set; }

		public bool IsSelecting { get; private set; }

		public void FinishSelectAction()
		{
			IsSelecting = false;
			OnSelectionFinish?.Invoke(base.factory, selectObjIds);
			ClearSelection();
		}

		public static bool ShouldAddObject(PlanetFactory factory, int objId)
		{
			if (objId <= 0 || objId >= factory.entityCursor)
			{
				return false;
			}
			ref EntityData reference = ref factory.entityPool[objId];
			if (reference.assemblerId > 0)
			{
				return factory.factorySystem.assemblerPool[reference.assemblerId].recipeId > 0;
			}
			if (reference.labId > 0)
			{
				ref LabComponent reference2 = ref factory.factorySystem.labPool[reference.labId];
				if (!((LabComponent)(ref reference2)).matrixMode || reference2.recipeId <= 0)
				{
					return reference2.researchMode;
				}
				return true;
			}
			if (reference.minerId > 0 || reference.fractionatorId > 0 || reference.ejectorId > 0 || reference.siloId > 0)
			{
				return true;
			}
			if (reference.powerGenId > 0)
			{
				ref PowerGeneratorComponent reference3 = ref factory.powerSystem.genPool[reference.powerGenId];
				if (reference3.gamma)
				{
					return reference3.productId > 0;
				}
				if (reference3.wind || reference3.photovoltaic || reference3.geothermal)
				{
					return false;
				}
				bool flag = reference3.curFuelId > 0;
				return CalDB.IncludeFuelGenerator && flag;
			}
			if (reference.powerExcId > 0)
			{
				ref PowerExchangerComponent reference4 = ref factory.powerSystem.excPool[reference.powerExcId];
				if (reference4.state != 1f)
				{
					return reference4.state == -1f;
				}
				return true;
			}
			if (reference.spraycoaterId > 0)
			{
				ref SpraycoaterComponent reference5 = ref factory.cargoTraffic.spraycoaterPool[reference.spraycoaterId];
				if (reference5.incItemId > 0)
				{
					return reference5.cargoBeltId > 0;
				}
				return false;
			}
			return false;
		}

		public override void _OnInit()
		{
			selectObjIds = new HashSet<int>();
			SetDisplayPreviewCapacity(256);
		}

		public override void _OnFree()
		{
			selectObjIds = null;
			FreeBuildPreviews();
			IsEnable = false;
			IsSelecting = false;
		}

		public override void _OnOpen()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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)
			//IL_0052: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			ClearSelection();
			ResetBuildPreviews();
			castTerrain = false;
			castGround = false;
			castGroundPos = Vector3.zero;
			startGroundPosSnapped = (lastGroundPosSnapped = (castGroundPosSnapped = Vector3.zero));
			lastSelectGratBox = (selectGratBox = (selectArcBox = BPGratBox.zero));
			castObjectId = 0;
			cursorValid = false;
			cursorTarget = Vector3.zero;
			IsSelecting = false;
		}

		public override void _OnClose()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			ClearSelection();
			ResetBuildPreviews();
			startGroundPosSnapped = (lastGroundPosSnapped = (castGroundPosSnapped = Vector3.zero));
			lastSelectGratBox = (selectGratBox = (selectArcBox = BPGratBox.zero));
			castObjectId = 0;
			cursorValid = false;
			cursorTarget = Vector3.zero;
			IsEnable = false;
			IsSelecting = false;
		}

		public override void _OnTick(long time)
		{
			UpdateRaycast();
			Operating();
			if (((BuildTool)this).active)
			{
				((BuildTool)this).UpdatePreviewModels(((BuildTool)this).actionBuild.model);
			}
		}

		public override bool DetermineActive()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (IsEnable && (int)((BuildTool)this).actionBuild.blueprintMode == 0)
			{
				return ((BuildTool)this).controller.cmd.mode == 0;
			}
			return false;
		}

		public override void EscLogic()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			bool flag = !VFInput.onGUI && VFInput.inScreen && !VFInput.inputing;
			bool flag2 = VFInput.escKey.onDown || VFInput.escape;
			bool num = !VFInput._godModeMechaMove && VFInput.rtsCancel.onDown && flag;
			if (num || flag2)
			{
				((BuildTool)this).player.SetHandItems(0, 0, 0);
				((BuildTool)this)._Close();
				((BuildTool)this).actionBuild.Close();
			}
			if (flag2)
			{
				VFInput.UseEscape();
			}
			if (num)
			{
				VFInput.UseMouseRight();
			}
		}

		public override void UpdatePreviewModels(BuildModel model)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 1; i < bpCursor; i++)
			{
				BuildPreview val = bpPool[i];
				if (val == null || val.bpgpuiModelId <= 0 || !val.isConnNode)
				{
					continue;
				}
				if (val.objId > 0)
				{
					base.factory.cargoTraffic.SetBeltSelected(base.factory.entityPool[val.objId].beltId);
					continue;
				}
				uint beltSpeed = (uint)val.desc.beltSpeed;
				if (val.outputObjId == 0 || val.inputObjId == 0 || val.coverbp != null)
				{
					model.connRenderer.AddBlueprintBeltMajorPoint(val.lpos, val.lrot, beltSpeed);
				}
				else
				{
					model.connRenderer.AddBlueprintBeltPoint(val.lpos, val.lrot, beltSpeed);
				}
			}
		}

		public void UpdateRaycast()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_001f: 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_0038: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Invalid comparison between Unknown and I4
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Invalid comparison between Unknown and I4
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: 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_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			castTerrain = false;
			castGround = false;
			castGroundPos = Vector3.zero;
			castGroundPosSnapped = Vector3.zero;
			castObjectId = 0;
			cursorValid = false;
			cursorTarget = Vector3.zero;
			if (!VFInput.onGUI && VFInput.inScreen)
			{
				RaycastHit val = default(RaycastHit);
				castGround = Physics.Raycast(base.mouseRay, ref val, 800f, 8720, (QueryTriggerInteraction)2);
				if (castGround)
				{
					Layer val2 = (Layer)((Component)((RaycastHit)(ref val)).collider).gameObject.layer;
					castTerrain = (int)val2 == 9 || (int)val2 == 4;
					castGroundPos = (((BuildTool)this).controller.cmd.test = (((BuildTool)this).controller.cmd.target = ((RaycastHit)(ref val)).point));
					castGroundPosSnapped = ((BuildTool)this).actionBuild.planetAux.Snap(castGroundPos, castTerrain);
					castGroundPosSnapped = ((Vector3)(ref castGroundPosSnapped)).normalized * (base.planet.realRadius + 0.2f);
					((BuildTool)this).controller.cmd.test = castGroundPosSnapped;
					Vector3 normalized = ((Vector3)(ref castGroundPosSnapped)).normalized;
					if (Physics.Raycast(new Ray(castGroundPosSnapped + normalized * 10f, -normalized), ref val, 20f, 8720, (QueryTriggerInteraction)2))
					{
						((BuildTool)this).controller.cmd.test = ((RaycastHit)(ref val)).point;
					}
					cursorTarget = castGroundPosSnapped;
					cursorValid = true;
				}
			}
			((BuildTool)this).controller.cmd.state = (cursorValid ? 1 : 0);
			((BuildTool)this).controller.cmd.target = (cursorValid ? cursorTarget : Vector3.zero);
		}

		public void Operating()
		{
			//IL_0047: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			if (!IsSelecting && VFInput.blueprintCopyOperate0.onDown && cursorValid)
			{
				IsSelecting = true;
				startGroundPosSnapped = castGroundPosSnapped;
				lastGroundPosSnapped = startGroundPosSnapped;
				InitSelectGratBox();
				VFInput.UseMouseLeft();
			}
			Vector3 val = castGroundPosSnapped - startGroundPosSnapped;
			bool num = ((Vector3)(ref val)).sqrMagnitude > 0.01f;
			bool flag = VFInput.blueprintCopyOperate0.onDown || VFInput.blueprintCopyOperate1.onDown;
			if (IsSelecting && flag && cursorValid)
			{
				FinishSelectAction();
				ResetBuildPreviews();
				IsSelecting = false;
				VFInput.UseMouseLeft();
				VFInput.UseEnterConfirm();
				((BuildTool)this)._Close();
			}
			else if (IsSelecting && VFInput.rtsCancel.onUp)
			{
				IsSelecting = false;
				startGroundPosSnapped = castGroundPosSnapped;
				lastGroundPosSnapped = startGroundPosSnapped;
				ClearSelection();
				ResetBuildPreviews();
			}
			if (IsSelecting)
			{
				UICursor.SetCursor((ECursor)2);
				DetermineSelectGratBox();
				if (lastSelectGratBox != selectGratBox)
				{
					DetermineAddSelection();
					lastSelectGratBox = selectGratBox;
				}
			}
			else
			{
				startGroundPosSnapped = castGroundPosSnapped;
				ReDeterminePreviews();
			}
			if (num)
			{
				ReDeterminePreviews();
			}
			string text = "[RateMonitor]";
			if (Plugin.Operation != 0)
			{
				text = text + ": " + Plugin.Operation;
			}
			((BuildTool)this).actionBuild.model.cursorText = text + "\r\nselected count:" + selectObjIds.Count;
		}

		private void InitSelectGratBox()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			BlueprintUtils.GetMinimumGratBox(((Vector3)(ref startGroundPosSnapped)).normalized, ref selectGratBox);
			selectArcBox = selectGratBox;
			if (selectArcBox.y >= 1.5707864f)
			{
				selectArcBox.y = (selectArcBox.w = (float)Math.PI / 2f);
				selectArcBox.z = selectArcBox.x + (float)Math.PI * 200f;
			}
			else if (selectArcBox.y <= -1.5707864f)
			{
				selectArcBox.y = (selectArcBox.w = -(float)Math.PI / 2f);
				selectArcBox.z = selectArcBox.x + (float)Math.PI * 200f;
			}
			lastSelectGratBox = selectGratBox;
		}

		public void DetermineSelectGratBox()
		{
			//IL_0011: 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)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			if (!cursorValid)
			{
				return;
			}
			float longitudeRad = BlueprintUtils.GetLongitudeRad(((Vector3)(ref castGroundPosSnapped)).normalized);
			float longitudeRad2 = BlueprintUtils.GetLongitudeRad(((Vector3)(ref lastGroundPosSnapped)).normalized);
			float latitudeRad = BlueprintUtils.GetLatitudeRad(((Vector3)(ref castGroundPosSnapped)).normalized);
			int num;
			float num2;
			if (!(latitudeRad >= 1.5707864f))
			{
				num = ((latitudeRad <= -1.5707864f) ? 1 : 0);
				if (num == 0)
				{
					num2 = longitudeRad - longitudeRad2;
					goto IL_0061;
				}
			}
			else
			{
				num = 1;
			}
			num2 = 0f;
			goto IL_0061;
			IL_0061:
			float num3 = num2;
			num3 = Mathf.Repeat(num3 + (float)Math.PI, (float)Math.PI * 2f) - (float)Math.PI;
			ref BPGratBox reference = ref selectArcBox;
			((BPGratBox)(ref reference)).endLongitudeRad = ((BPGratBox)(ref reference)).endLongitudeRad + num3;
			((BPGratBox)(ref selectArcBox)).endLatitudeRad = latitudeRad;
			selectGratBox = selectArcBox;
			selectGratBox.x = ((selectArcBox.x < selectArcBox.z) ? selectArcBox.x : selectArcBox.z);
			selectGratBox.z = ((selectArcBox.x > selectArcBox.z) ? selectArcBox.x : selectArcBox.z);
			if (selectArcBox.x < selectArcBox.z)
			{
				if (selectGratBox.z > selectGratBox.x + (float)Math.PI * 2f - 1E-05f - 4E-06f)
				{
					selectGratBox.z = selectGratBox.x + (float)Math.PI * 2f - 1E-05f - 4E-06f;
				}
				selectGratBox.z = Mathf.Repeat(selectGratBox.z + (float)Math.PI, (float)Math.PI * 2f) - (float)Math.PI;
			}
			else
			{
				if (selectGratBox.x < selectGratBox.z - (float)Math.PI * 2f + 1E-05f + 4E-06f)
				{
					selectGratBox.x = selectGratBox.z - (float)Math.PI * 2f + 1E-05f + 4E-06f;
				}
				selectGratBox.x = Mathf.Repeat(selectGratBox.x + (float)Math.PI, (float)Math.PI * 2f) - (float)Math.PI;
			}
			selectGratBox.y = ((selectArcBox.y < selectArcBox.w) ? selectArcBox.y : selectArcBox.w);
			selectGratBox.w = ((selectArcBox.y > selectArcBox.w) ? selectArcBox.y : selectArcBox.w);
			float num4 = BlueprintUtils.GetLongitudeRadPerGrid((Mathf.Abs(castGroundPosSnapped.y) < Mathf.Abs(startGroundPosSnapped.y)) ? ((Vector3)(ref castGroundPosSnapped)).normalized : ((Vector3)(ref startGroundPosSnapped)).normalized, 200) * 0.33f;
			((BPGratBox)(ref selectGratBox)).Extend(num4, 0.002f);
			if (num == 0)
			{
				lastGroundPosSnapped = castGroundPosSnapped;
			}
		}

		public void DetermineAddSelection()
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			selectObjIds.Clear();
			if (Mathf.Abs(selectArcBox.x - selectArcBox.z) < 0.01f && Mathf.Abs(selectArcBox.y - selectArcBox.w) < 0.01f && castObjectId != 0)
			{
				if (ShouldAddObject(base.factory, castObjectId))
				{
					selectObjIds.Add(castObjectId);
				}
			}
			else
			{
				EntityData[] entityPool = base.factory.entityPool;
				int entityCursor = base.factory.entityCursor;
				for (int i = 1; i < entityCursor; i++)
				{
					ref EntityData reference = ref entityPool[i];
					if (reference.id == i && ((BPGratBox)(ref selectGratBox)).InGratBox(reference.pos) && ShouldAddObject(base.factory, i))
					{
						selectObjIds.Add(i);
					}
				}
			}
			DeterminePreviews();
		}

		public void ClearSelection()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_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_001d: 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)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			selectObjIds.Clear();
			lastSelectGratBox = (selectGratBox = (selectArcBox = BPGratBox.zero));
		}

		public void ReDeterminePreviews()
		{
			ResetBuildPreviews();
			foreach (int selectObjId in selectObjIds)
			{
				BuildPreview buildPreview = GetBuildPreview(selectObjId);
				AddBPGPUIModel(buildPreview);
			}
			SyncAnimBuffer();
			base.planet.factoryModel.bpgpuiManager.animBuffer = animBuffer;
			base.planet.factoryModel.bpgpuiManager.SyncAllGPUBuffer();
		}

		public void DeterminePreviews()
		{
			HashSet<int> hashSet = new HashSet<int>(selectObjIds);
			for (int i = 1; i < bpCursor; i++)
			{
				BuildPreview val = bpPool[i];
				if (val == null || val.bpgpuiModelId <= 0)
				{
					continue;
				}
				if (!selectObjIds.Contains(val.objId))
				{
					if (val.bpgpuiModelInstIndex >= 0)
					{
						base.planet.factoryModel.bpgpuiManager.RemoveBuildPreviewModel(val.desc.modelIndex, val.bpgpuiModelInstIndex, false);
					}
					RemoveBuildPreview(i);
				}
				else
				{
					hashSet.Remove(val.objId);
				}
			}
			foreach (int item in hashSet)
			{
				BuildPreview buildPreview = GetBuildPreview(item);
				AddBPGPUIModel(buildPreview);
			}
			if (castObjectId != 0)
			{
				BuildPreview buildPreview2 = GetBuildPreview(castObjectId);
				AddBPGPUIModel(buildPreview2);
			}
			SyncAnimBuffer();
			base.planet.factoryModel.bpgpuiManager.animBuffer = animBuffer;
			base.planet.factoryModel.bpgpuiManager.SyncAllGPUBuffer();
		}

		public void AddBPGPUIModel(BuildPreview preview)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: 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)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: 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_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: 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_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			if (preview == null || preview.bpgpuiModelId <= 0 || !preview.needModel)
			{
				return;
			}
			ModelProto val = ((ProtoSet<ModelProto>)(object)LDB.models).Select(preview.desc.modelIndex);
			Color32 val2 = default(Color32);
			((Color32)(ref val2))..ctor((byte)44, (byte)123, (byte)250, byte.MaxValue);
			if (val.RendererType == 2)
			{
				bool flag = default(bool);
				bool flag2 = default(bool);
				((BuildTool)this).GetInserterT1T2(preview.objId, ref flag, ref flag2);
				if (preview.objId > 0)
				{
					animPool[preview.bpgpuiModelId] = base.factory.entityAnimPool[preview.objId];
				}
				animPool[preview.bpgpuiModelId].state = (uint)((val2.r << 24) + (val2.g << 16) + (val2.b << 8) + val2.a);
				base.planet.factoryModel.bpgpuiManager.AddBuildPreviewModel(preview.desc.modelIndex, ref preview.bpgpuiModelInstIndex, preview.bpgpuiModelId, preview.lpos, preview.lrot, preview.lpos2, preview.lrot2, flag ? 1 : 0, flag2 ? 1 : 0, false);
				return;
			}
			if (val.RendererType == 3)
			{
				bool flag3 = default(bool);
				int num = default(int);
				int num2 = default(int);
				base.factory.ReadObjectConn(preview.objId, 14, ref flag3, ref num, ref num2);
				if (preview.objId > 0)
				{
					animPool[preview.bpgpuiModelId] = base.factory.entityAnimPool[preview.objId];
				}
				animPool[preview.bpgpuiModelId].state = (uint)((val2.r << 24) + (val2.g << 16) + (val2.b << 8) + val2.a);
				base.planet.factoryModel.bpgpuiManager.AddBuildPreviewModel(preview.desc.modelIndex, ref preview.bpgpuiModelInstIndex, preview.bpgpuiModelId, preview.lpos, preview.lrot, (num != 0) ? 1u : 0u, false);
				return;
			}
			if (preview.objId > 0)
			{
				animPool[preview.bpgpuiModelId] = base.factory.entityAnimPool[preview.objId];
			}
			animPool[preview.bpgpuiModelId].state = (uint)((val2.r << 24) + (val2.g << 16) + (val2.b << 8) + val2.a);
			if (preview.objId > 0 && preview.desc.isEjector)
			{
				animPool[preview.bpgpuiModelId].power = base.factory.factorySystem.ejectorPool[base.factory.entityPool[preview.objId].ejectorId].localDir.z;
			}
			base.planet.factoryModel.bpgpuiManager.AddBuildPreviewModel(preview.desc.modelIndex, ref preview.bpgpuiModelInstIndex, preview.bpgpuiModelId, preview.lpos, preview.lrot, false);
		}

		public void GeneratePreviewByObjId(BuildPreview preview, int objId)
		{
			//IL_001f: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references