Decompiled source of PowerPlantCalc v1.0.2

PowerPlantCalc.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PowerPlantCalc
{
	public enum Language
	{
		English,
		Chinese,
		Turkish
	}
	[BepInPlugin("bug.dsp.powerplantcalc", "PowerPlantCalc", "1.0.2")]
	public class Plugin : BaseUnityPlugin
	{
		private static ConfigEntry<KeyboardShortcut> hotkey;

		public static ConfigEntry<Language> language;

		private void Awake()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "OpenWindow", new KeyboardShortcut((KeyCode)120, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Opens/closes the power plant calculator.");
			language = ((BaseUnityPlugin)this).Config.Bind<Language>("General", "Language", Language.English, "Window language: English, Chinese or Turkish (applies after restarting the game).");
		}

		private void Update()
		{
			//IL_0040: 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)
			if (!DSPGame.IsMenuDemo && GameMain.isRunning && !((Object)(object)UIRoot.instance?.uiGame?.generatorWindow == (Object)null) && !VFInput.inputing)
			{
				KeyboardShortcut value = hotkey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					CalcWindow.Toggle();
				}
			}
		}
	}
	public static class Lang
	{
		private static readonly Dictionary<string, string[]> texts = new Dictionary<string, string[]>
		{
			["title"] = new string[3] { "Power Plant Calculator", "发电设施计算器", "Santral Hesaplayıcı" },
			["onlyFocus"] = new string[3] { "Only this planet's focus", "仅本星球聚焦", "Sadece bu gezegenin odağı" },
			["onlyPlanet"] = new string[3] { "Only makeable on this planet", "仅本星球可生产", "Sadece bu gezegende üretilebilenler" },
			["plants"] = new string[3] { "Fuel-burning power plants", "燃料发电设施", "Yakıtla çalışan santraller" },
			["modeFuel"] = new string[3] { "Fuel → Power", "燃料 → 电力", "Yakıt → Güç" },
			["modePower"] = new string[3] { "Power → Fuel", "电力 → 燃料", "Güç → Yakıt" },
			["amount"] = new string[3] { "Amount", "数量", "Miktar" },
			["power"] = new string[3] { "Power", "功率", "Güç" },
			["perMin"] = new string[3] { "/ min", "/ 分钟", "/ dk" },
			["proliferator"] = new string[3] { "Proliferator", "增产剂", "Artırıcı" },
			["noProliferator"] = new string[3] { "No proliferator", "无增产剂", "Artırıcı yok" },
			["fuelOf"] = new string[3] { "{0} — fuel: {1}", "{0} — 燃料:{1}", "{0} — girdi kaynağı: {1}" },
			["focusIncluded"] = new string[3] { "   (planet focus +{0}% included)", "   (含星球聚焦 +{0}%)", "   (gezegen odağı +%{0} dahil)" },
			["usePerPlant"] = new string[3] { "Use per plant (full load)", "单台消耗(满载)", "Santral başına tüketim (tam yük)" },
			["powerPerPlant"] = new string[3] { "Power per plant", "单台功率", "Santral başına güç" },
			["plantsNeeded"] = new string[3] { "Plants needed", "所需设施数量", "Gereken santral" },
			["totalFuel"] = new string[3] { "Total fuel", "燃料总量", "Toplam yakıt" },
			["totalPower"] = new string[3] { "Total power", "总功率", "Toplam güç" },
			["noPlanet"] = new string[3] { "Filters need you to be on a planet.", "筛选需要位于星球上。", "Filtreler için bir gezegende olmalısın." },
			["noGenesis"] = new string[3] { "Planet focus comes from GenesisBook; GenesisBook was not found.", "星球聚焦来自创世之书;未找到创世之书。", "Gezegen odağı GenesisBook ile gelir; GenesisBook bulunamadı." },
			["noFocus"] = new string[3] { "This planet's focus boosts no power plant.", "本星球的聚焦未加成任何发电设施。", "Bu gezegenin odağında bir santral bonusu yok." },
			["noFocusOrMake"] = new string[3] { "This planet's focus boosts no power plant, or its fuel can't be made here.", "本星球的聚焦未加成任何发电设施,或其燃料无法在此生产。", "Bu gezegenin odağında bir santral bonusu yok ya da yakıtı burada üretilemiyor." },
			["noMake"] = new string[3] { "No fuel can be made on this planet.", "本星球无法生产任何燃料。", "Bu gezegende üretilebilen bir yakıt bulunamadı." }
		};

		public static string T(string key)
		{
			return texts[key][(int)(Plugin.language?.Value ?? Language.English)];
		}
	}
	public struct Result
	{
		public double PerMachine;

		public double MachinePower;

		public double Machines;

		public double TotalPower;
	}
	public static class Calc
	{
		public static readonly int[] IncLevels = new int[4] { 0, 1, 2, 4 };

		public static readonly string[] Units = new string[6] { "W", "kW", "MW", "GW", "TW", "PW" };

		public static Result Run(long genEnergyPerTick, long useFuelPerTick, int fuelMask, int fuelId, long heatValue, bool productive, int incLevel, double ratePerMinute, double focusMultiplier = 1.0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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)
			PowerGeneratorComponent val = new PowerGeneratorComponent
			{
				genEnergyPerTick = genEnergyPerTick,
				useFuelPerTick = useFuelPerTick,
				fuelMask = (short)fuelMask,
				fuelId = (short)fuelId,
				curFuelId = (short)fuelId,
				fuelCount = 1,
				productive = productive,
				fuelIncLevel = (byte)incLevel
			};
			long num = (long)((double)((PowerGeneratorComponent)(ref val)).EnergyCap_Fuel() * focusMultiplier);
			if (num <= 0 || heatValue <= 0 || genEnergyPerTick <= 0)
			{
				return default(Result);
			}
			double num2 = (productive ? ((double)num * (double)useFuelPerTick * 40.0 / ((double)genEnergyPerTick * (double)Cargo.incFastDivisionNumerator[incLevel])) : ((double)num * (double)useFuelPerTick / (double)genEnergyPerTick));
			Result result = new Result
			{
				PerMachine = num2 * 3600.0 / (double)heatValue,
				MachinePower = (double)num * 60.0
			};
			result.Machines = ratePerMinute / result.PerMachine;
			result.TotalPower = result.Machines * result.MachinePower;
			return result;
		}

		public static double RateForPower(Result r, double watts)
		{
			if (!(r.MachinePower > 0.0))
			{
				return 0.0;
			}
			return watts / r.MachinePower * r.PerMachine;
		}

		public static HashSet<int> Closure(HashSet<int> have, IList<(int[] items, int[] results)> recipes)
		{
			bool flag = true;
			while (flag)
			{
				flag = false;
				foreach (var (source, array) in recipes)
				{
					if (source.All(have.Contains))
					{
						int[] array2 = array;
						foreach (int item in array2)
						{
							flag |= have.Add(item);
						}
					}
				}
			}
			return have;
		}

		public static string Power(double watts)
		{
			int num = 0;
			while (Math.Abs(watts) >= 1000.0 && num < Units.Length - 1)
			{
				watts /= 1000.0;
				num++;
			}
			return watts.ToString("0.##") + " " + Units[num];
		}
	}
	public static class Planet
	{
		private static Func<int, int, bool> containsFocus;

		private static bool focusLooked;

		public static bool HasFocusSystem => Focus() != null;

		private static Func<int, int, bool> Focus()
		{
			if (focusLooked)
			{
				return containsFocus;
			}
			focusLooked = true;
			MethodInfo methodInfo = AccessTools.Method("ProjectGenesis.Patches.PlanetFocusPatches:ContainsFocus", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				containsFocus = (Func<int, int, bool>)Delegate.CreateDelegate(typeof(Func<int, int, bool>), methodInfo);
			}
			return containsFocus;
		}

		public static double FocusMultiplier(PlanetData p, int fuelMask)
		{
			int arg;
			double result;
			switch (fuelMask)
			{
			case 1:
				arg = 6524;
				result = 1.2;
				break;
			case 2:
				arg = 6529;
				result = 1.2;
				break;
			case 16:
				arg = 6527;
				result = 1.1;
				break;
			default:
				return 1.0;
			}
			if (p == null || Focus() == null || !Focus()(p.id, arg))
			{
				return 1.0;
			}
			return result;
		}

		public static HashSet<int> Producible(PlanetData p)
		{
			//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_002d: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected I4, but got Unknown
			HashSet<int> hashSet = new HashSet<int>();
			VeinGroup[] array = (VeinGroup[])(((object)p.veinGroups) ?? ((object)new VeinGroup[0]));
			for (int i = 0; i < array.Length; i++)
			{
				VeinGroup val = array[i];
				VeinProto val2 = ((((VeinGroup)(ref val)).isNull || val.amount <= 0) ? null : ((ProtoSet<VeinProto>)(object)LDB.veins).Select((int)val.type));
				if (val2 != null && val2.MiningItem > 0)
				{
					hashSet.Add(val2.MiningItem);
				}
			}
			if (p.waterItemId > 0)
			{
				hashSet.Add(p.waterItemId);
			}
			int[] array2 = p.gasItems ?? new int[0];
			foreach (int num in array2)
			{
				if (num > 0)
				{
					hashSet.Add(num);
				}
			}
			ItemProto[] dataArray = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray;
			foreach (ItemProto val3 in dataArray)
			{
				if (val3?.prefabDesc != null && val3.prefabDesc.gammaRayReceiver && val3.prefabDesc.powerProductId > 0)
				{
					hashSet.Add(val3.prefabDesc.powerProductId);
				}
			}
			List<(int[], int[])> recipes = (from r in ((ProtoSet<RecipeProto>)(object)LDB.recipes).dataArray
				where r != null && r.GridIndex > 0 && r.Items != null && r.Results != null && r.Results.Length != 0
				select (Items: r.Items, Results: r.Results)).ToList();
			return Calc.Closure(hashSet, recipes);
		}
	}
	public static class CalcWindow
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<ItemProto, bool> <>9__40_0;

			public static Func<int, bool> <>9__41_0;

			public static Func<int, ItemProto> <>9__41_1;

			public static Func<ItemProto, bool> <>9__41_2;

			public static UnityAction <>9__44_0;

			public static Action<bool> <>9__44_1;

			public static Action<bool> <>9__44_2;

			public static Action <>9__44_3;

			public static Action <>9__44_4;

			public static UnityAction<string> <>9__44_5;

			internal bool <Generators>b__40_0(ItemProto i)
			{
				if (i?.prefabDesc != null && i.prefabDesc.isPowerGen && i.prefabDesc.fuelMask > 0 && i.prefabDesc.useFuelPerTick > 0 && i.prefabDesc.fuelMask < ItemProto.fuelNeeds.Length)
				{
					return i.GridIndex > 0;
				}
				return false;
			}

			internal bool <Fuels>b__41_0(int id)
			{
				if (producible != null)
				{
					return producible.Contains(id);
				}
				return true;
			}

			internal ItemProto <Fuels>b__41_1(int id)
			{
				return ((ProtoSet<ItemProto>)(object)LDB.items).Select(id);
			}

			internal bool <Fuels>b__41_2(ItemProto i)
			{
				if (i != null)
				{
					return !IsLoreItem(i);
				}
				return false;
			}

			internal void <Build>b__44_0()
			{
				win.SetActive(false);
			}

			internal void <Build>b__44_1(bool on)
			{
				onlyFocus = on;
				RebuildCards();
			}

			internal void <Build>b__44_2(bool on)
			{
				onlyPlanet = on;
				RebuildCards();
			}

			internal void <Build>b__44_3()
			{
				SetMode(power: false);
			}

			internal void <Build>b__44_4()
			{
				SetMode(power: true);
			}

			internal void <Build>b__44_5(string s)
			{
				double.TryParse(s.Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out amounts[powerMode ? 1u : 0u]);
				Refresh();
			}
		}

		private const float Width = 620f;

		private const float CardW = 150f;

		private const float CardH = 132f;

		private const float CardsTop = -100f;

		private static GameObject win;

		private static GameObject fuelTpl;

		private static GameObject switchTpl;

		private static GameObject buttonTpl;

		private static RectTransform root;

		private static RectTransform cardsRoot;

		private static RectTransform fuelSection;

		private static RectTransform fuelGrid;

		private static RectTransform modeRow;

		private static RectTransform inputRow;

		private static RectTransform results;

		private static Text labelTpl;

		private static Text valueTpl;

		private static Text fuelTitle;

		private static Text emptyText;

		private static Text amountLabel;

		private static Text perMinText;

		private static InputField amountInput;

		private static readonly List<Text> resultValues = new List<Text>();

		private static readonly List<(ItemProto item, Image ring)> genRings = new List<(ItemProto, Image)>();

		private static readonly List<(ItemProto item, Image ring)> fuelRings = new List<(ItemProto, Image)>();

		private static readonly List<Image> incRings = new List<Image>();

		private static readonly List<UIButton> modeButtons = new List<UIButton>();

		private static readonly List<UIButton> unitButtons = new List<UIButton>();

		private static ItemProto gen;

		private static ItemProto fuel;

		private static int incIndex;

		private static int unitIndex = 3;

		private static bool powerMode;

		private static readonly double[] amounts = new double[2] { 60.0, 1.0 };

		private static float cardsBottom;

		private static bool onlyFocus;

		private static bool onlyPlanet;

		private static PlanetData planet;

		private static HashSet<int> producible;

		public static void Toggle()
		{
			if ((Object)(object)win == (Object)null)
			{
				Build();
			}
			win.SetActive(!win.activeSelf);
			if (win.activeSelf)
			{
				win.transform.SetAsLastSibling();
				RebuildCards();
			}
		}

		private static IEnumerable<ItemProto> Generators()
		{
			return ((ProtoSet<ItemProto>)(object)LDB.items).dataArray.Where((ItemProto i) => i?.prefabDesc != null && i.prefabDesc.isPowerGen && i.prefabDesc.fuelMask > 0 && i.prefabDesc.useFuelPerTick > 0 && i.prefabDesc.fuelMask < ItemProto.fuelNeeds.Length && i.GridIndex > 0);
		}

		private static ItemProto[] Fuels(ItemProto g)
		{
			return (from id in ItemProto.fuelNeeds[g.prefabDesc.fuelMask] ?? new int[0]
				where producible == null || producible.Contains(id)
				select ((ProtoSet<ItemProto>)(object)LDB.items).Select(id) into i
				where i != null && !IsLoreItem(i)
				select i).ToArray();
		}

		private static bool IsLoreItem(ItemProto i)
		{
			if (!(((Proto)i).Name == "创世之书") && !(((Proto)i).Name == "虚空之书") && !(((Proto)i).Name == "起源之书"))
			{
				return ((Proto)i).Name?.StartsWith("开发者日志") ?? false;
			}
			return true;
		}

		private static bool Visible(ItemProto g)
		{
			if (!onlyFocus || Planet.FocusMultiplier(planet, g.prefabDesc.fuelMask) > 1.0)
			{
				return Fuels(g).Length != 0;
			}
			return false;
		}

		private static void Build()
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Expected O, but got Unknown
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Expected O, but got Unknown
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: 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_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_059d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_05de: Unknown result type (might be due to invalid IL or missing references)
			//IL_063f: Unknown result type (might be due to invalid IL or missing references)
			//IL_064e: Unknown result type (might be due to invalid IL or missing references)
			//IL_065d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0667: Expected O, but got Unknown
			//IL_066c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0676: Expected O, but got Unknown
			//IL_067b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0685: Expected O, but got Unknown
			//IL_06de: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_073a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0749: Unknown result type (might be due to invalid IL or missing references)
			//IL_0788: Unknown result type (might be due to invalid IL or missing references)
			//IL_0797: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0805: Unknown result type (might be due to invalid IL or missing references)
			//IL_0838: Unknown result type (might be due to invalid IL or missing references)
			//IL_0847: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)UIRoot.instance.uiGame.generatorWindow).transform;
			fuelTpl = ((Component)transform.Find("produce-2/fuel")).gameObject;
			switchTpl = ((Component)transform.Find("boost-switch")).gameObject;
			buttonTpl = ((Component)transform.Find("ray-receiver/switch-button-1")).gameObject;
			labelTpl = ((Component)transform.Find("power-network-desc/desc-group/label-1")).GetComponent<Text>();
			valueTpl = ((Component)transform.Find("power-network-desc/desc-group/value-1")).GetComponent<Text>();
			win = Object.Instantiate<GameObject>(((Component)transform).gameObject, transform.parent, false);
			((Object)win).name = "Power Plant Calculator";
			Object.DestroyImmediate((Object)(object)win.GetComponent<UIPowerGeneratorWindow>());
			foreach (Transform item in win.transform)
			{
				Transform val = item;
				if (((Object)val).name != "panel-bg")
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
			}
			Object.Destroy((Object)(object)((Component)win.transform.Find("panel-bg/btn-box/menu-wnd-btn")).gameObject);
			StripLocalizers(win);
			Button component = ((Component)win.transform.Find("panel-bg/btn-box/close-wnd-btn")).GetComponent<Button>();
			component.onClick = new ButtonClickedEvent();
			ButtonClickedEvent onClick = component.onClick;
			object obj = <>c.<>9__44_0;
			if (obj == null)
			{
				UnityAction val2 = delegate
				{
					win.SetActive(false);
				};
				<>c.<>9__44_0 = val2;
				obj = (object)val2;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			Text component2 = ((Component)win.transform.Find("panel-bg/title-text")).GetComponent<Text>();
			component2.text = Lang.T("title");
			((Graphic)component2).rectTransform.sizeDelta = new Vector2(400f, ((Graphic)component2).rectTransform.sizeDelta.y);
			root = (RectTransform)win.transform;
			root.anchoredPosition = new Vector2(0f, 330f);
			Switch(new Vector2(20f, -50f), Lang.T("onlyFocus"), delegate(bool on)
			{
				onlyFocus = on;
				RebuildCards();
			});
			Switch(new Vector2(320f, -50f), Lang.T("onlyPlanet"), delegate(bool on)
			{
				onlyPlanet = on;
				RebuildCards();
			});
			NewText(labelTpl, (Transform)(object)root, new Vector2(20f, -76f), new Vector2(400f, 20f), (TextAnchor)3, Lang.T("plants"));
			cardsRoot = NewRect("cards", (Transform)(object)root, new Vector2(0f, -100f), new Vector2(620f, 10f));
			emptyText = NewText(labelTpl, (Transform)(object)root, new Vector2(20f, -100f), new Vector2(580f, 40f), (TextAnchor)0, "");
			emptyText.horizontalOverflow = (HorizontalWrapMode)0;
			fuelSection = NewRect("fuel-section", (Transform)(object)root, Vector2.zero, new Vector2(620f, 10f));
			fuelTitle = NewText(labelTpl, (Transform)(object)fuelSection, new Vector2(20f, 0f), new Vector2(580f, 20f), (TextAnchor)3, "");
			fuelGrid = NewRect("fuel-grid", (Transform)(object)fuelSection, new Vector2(0f, -24f), new Vector2(620f, 10f));
			modeRow = NewRect("mode-row", (Transform)(object)fuelSection, Vector2.zero, new Vector2(620f, 44f));
			modeButtons.Add(TextButton((Transform)(object)modeRow, new Vector2(20f, -8f), new Vector2(140f, 28f), Lang.T("modeFuel"), delegate
			{
				SetMode(power: false);
			}));
			modeButtons.Add(TextButton((Transform)(object)modeRow, new Vector2(166f, -8f), new Vector2(140f, 28f), Lang.T("modePower"), delegate
			{
				SetMode(power: true);
			}));
			NewText(labelTpl, (Transform)(object)modeRow, new Vector2(330f, -12f), new Vector2(90f, 20f), (TextAnchor)3, Lang.T("proliferator"));
			int[] array = new int[4] { 0, 1141, 1142, 1143 };
			for (int num = 0; num < array.Length; num++)
			{
				int index = num;
				Image val3 = Circle((Transform)(object)modeRow, new Vector2(420f + (float)num * 46f, -3f), 38f, ((ProtoSet<ItemProto>)(object)LDB.items).Select(array[num]), delegate
				{
					incIndex = index;
					Refresh();
				});
				if (num == 0)
				{
					((Component)((Component)val3).transform.parent.Find("button")).GetComponent<UIButton>().tips.tipTitle = Lang.T("noProliferator");
				}
				incRings.Add(val3);
			}
			inputRow = NewRect("input-row", (Transform)(object)fuelSection, Vector2.zero, new Vector2(620f, 30f));
			amountLabel = NewText(labelTpl, (Transform)(object)inputRow, new Vector2(20f, -4f), new Vector2(70f, 20f), (TextAnchor)3, "");
			amountInput = Object.Instantiate<InputField>(((Component)((Component)UIRoot.instance.uiGame.beltWindow).transform.Find("number-input")).GetComponent<InputField>(), (Transform)(object)inputRow, false);
			StripLocalizers(((Component)amountInput).gameObject);
			Place((RectTransform)((Component)amountInput).transform, new Vector2(90f, -4f), new Vector2(80f, 22f));
			amountInput.onValueChanged = new OnChangeEvent();
			amountInput.onEndEdit = new EndEditEvent();
			amountInput.contentType = (ContentType)3;
			amountInput.characterLimit = 10;
			((UnityEvent<string>)(object)amountInput.onValueChanged).AddListener((UnityAction<string>)delegate(string s)
			{
				double.TryParse(s.Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out amounts[powerMode ? 1u : 0u]);
				Refresh();
			});
			perMinText = NewText(labelTpl, (Transform)(object)inputRow, new Vector2(176f, -4f), new Vector2(60f, 20f), (TextAnchor)3, Lang.T("perMin"));
			for (int num2 = 0; num2 < Calc.Units.Length; num2++)
			{
				int index2 = num2;
				unitButtons.Add(TextButton((Transform)(object)inputRow, new Vector2(176f + (float)num2 * 46f, -3f), new Vector2(42f, 24f), Calc.Units[num2], delegate
				{
					unitIndex = index2;
					Refresh();
				}));
			}
			results = NewRect("results", (Transform)(object)fuelSection, Vector2.zero, new Vector2(620f, 130f));
			string[] array2 = new string[5] { "usePerPlant", "powerPerPlant", "plantsNeeded", "totalFuel", "totalPower" };
			for (int num3 = 0; num3 < array2.Length; num3++)
			{
				NewText(labelTpl, (Transform)(object)results, new Vector2(20f, (float)(-num3) * 24f), new Vector2(330f, 20f), (TextAnchor)3, Lang.T(array2[num3]));
				resultValues.Add(NewText(valueTpl, (Transform)(object)results, new Vector2(330f, (float)(-num3) * 24f), new Vector2(270f, 20f), (TextAnchor)5, ""));
			}
			SetMode(power: false);
		}

		private static void SetMode(bool power)
		{
			powerMode = power;
			amountLabel.text = Lang.T(power ? "power" : "amount");
			((Component)perMinText).gameObject.SetActive(!power);
			foreach (UIButton unitButton in unitButtons)
			{
				((Component)unitButton).gameObject.SetActive(power);
			}
			amountInput.text = amounts[power ? 1u : 0u].ToString(CultureInfo.InvariantCulture);
			Refresh();
		}

		private static void Switch(Vector2 pos, string label, Action<bool> onToggle)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0049: 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_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_0090: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(switchTpl, (Transform)(object)root, false);
			Transform val = obj.transform.Find("label");
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			obj.SetActive(true);
			RectTransform val2 = (RectTransform)obj.transform;
			Place(val2, pos, val2.sizeDelta);
			UISwitch component = obj.GetComponent<UISwitch>();
			component.SetToggleNoEvent(false);
			component.onToggle += onToggle;
			NewText(labelTpl, (Transform)(object)root, pos + new Vector2(46f, 2f), new Vector2(250f, 20f), (TextAnchor)3, label);
		}

		private static UIButton TextButton(Transform parent, Vector2 pos, Vector2 size, string label, Action onClick)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			GameObject obj = Object.Instantiate<GameObject>(buttonTpl, parent, false);
			StripLocalizers(obj);
			Place((RectTransform)obj.transform, pos, size);
			obj.GetComponentInChildren<Text>().text = label;
			Button component = obj.GetComponent<Button>();
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				onClick();
			});
			UIButton component2 = obj.GetComponent<UIButton>();
			component2.tips.tipTitle = "";
			component2.tips.tipText = "";
			return component2;
		}

		private static void RebuildCards()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			planet = GameMain.localPlanet;
			producible = ((onlyPlanet && planet != null) ? Planet.Producible(planet) : null);
			foreach (Transform item in (Transform)cardsRoot)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			genRings.Clear();
			bool flag = (onlyFocus || onlyPlanet) && planet == null;
			ItemProto[] array = (ItemProto[])(flag ? ((Array)new ItemProto[0]) : ((Array)Generators().Where(Visible).ToArray()));
			for (int i = 0; i < array.Length; i++)
			{
				BuildCard(array[i], new Vector2(15f + (float)(i % 4) * 152f, (float)(-i / 4) * 132f));
			}
			cardsBottom = -100f - ((array.Length != 0) ? ((float)((array.Length + 3) / 4) * 132f) : 44f);
			emptyText.text = ((array.Length != 0) ? "" : (flag ? Lang.T("noPlanet") : ((onlyFocus && !Planet.HasFocusSystem) ? Lang.T("noGenesis") : (onlyFocus ? Lang.T(onlyPlanet ? "noFocusOrMake" : "noFocus") : Lang.T("noMake")))));
			fuelSection.anchoredPosition = new Vector2(0f, cardsBottom);
			if (!array.Contains(gen))
			{
				gen = array.FirstOrDefault();
			}
			((Component)fuelSection).gameObject.SetActive(gen != null);
			if (gen != null)
			{
				SelectGen(gen);
			}
			else
			{
				root.sizeDelta = new Vector2(620f, 0f - cardsBottom + 20f);
			}
		}

		private static void BuildCard(ItemProto g, Vector2 pos)
		{
			//IL_002c: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = NewRect("card-" + ((Proto)g).ID, (Transform)(object)cardsRoot, pos, new Vector2(150f, 132f));
			genRings.Add((g, Circle((Transform)(object)val, new Vector2(49f, 0f), 52f, g, delegate
			{
				SelectGen(g);
			})));
			NewText(labelTpl, (Transform)(object)val, new Vector2(0f, -54f), new Vector2(150f, 34f), (TextAnchor)1, ((Proto)g).name).horizontalOverflow = (HorizontalWrapMode)0;
			ItemProto[] array = Fuels(g);
			int num = ((array.Length > 14) ? 13 : array.Length);
			for (int num2 = 0; num2 < num; num2++)
			{
				Image component = new GameObject("fuel-" + ((Proto)array[num2]).ID, new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				}).GetComponent<Image>();
				((Component)component).transform.SetParent((Transform)(object)val, false);
				component.sprite = array[num2].iconSprite;
				((Graphic)component).raycastTarget = false;
				Place(((Graphic)component).rectTransform, new Vector2(6f + (float)(num2 % 7) * 20f, -90f - (float)(num2 / 7) * 20f), new Vector2(18f, 18f));
			}
			if (num < array.Length)
			{
				NewText(labelTpl, (Transform)(object)val, new Vector2(6f + (float)(num % 7) * 20f, -90f - (float)(num / 7) * 20f), new Vector2(30f, 18f), (TextAnchor)3, "+" + (array.Length - num));
			}
		}

		private static void SelectGen(ItemProto g)
		{
			//IL_0019: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_0181: Unknown result type (might be due to invalid IL or missing references)
			gen = g;
			foreach (Transform item in (Transform)fuelGrid)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			fuelRings.Clear();
			ItemProto[] array = Fuels(g);
			for (int i = 0; i < array.Length; i++)
			{
				ItemProto f = array[i];
				fuelRings.Add((f, Circle((Transform)(object)fuelGrid, new Vector2(15f + (float)(i % 13) * 45f, (float)(-i / 13) * 45f), 42f, f, delegate
				{
					fuel = f;
					Refresh();
				})));
			}
			if (!array.Contains(fuel))
			{
				fuel = array.FirstOrDefault();
			}
			float num = -30f - (float)((array.Length + 13 - 1) / 13) * 45f;
			modeRow.anchoredPosition = new Vector2(0f, num);
			inputRow.anchoredPosition = new Vector2(0f, num - 48f);
			results.anchoredPosition = new Vector2(0f, num - 48f - 36f);
			root.sizeDelta = new Vector2(620f, 0f - cardsBottom - num + 48f + 36f + 120f + 30f);
			Refresh();
		}

		private static void Refresh()
		{
			foreach (var genRing in genRings)
			{
				var (val, _) = genRing;
				genRing.ring.fillAmount = ((val == gen) ? 1f : 0f);
			}
			foreach (var fuelRing in fuelRings)
			{
				var (val2, _) = fuelRing;
				fuelRing.ring.fillAmount = ((val2 == fuel) ? 1f : 0f);
			}
			for (int i = 0; i < incRings.Count; i++)
			{
				incRings[i].fillAmount = ((i == incIndex) ? 1f : 0f);
			}
			for (int j = 0; j < modeButtons.Count; j++)
			{
				modeButtons[j].highlighted = j == 1 == powerMode;
			}
			for (int k = 0; k < unitButtons.Count; k++)
			{
				unitButtons[k].highlighted = k == unitIndex;
			}
			if (gen == null)
			{
				return;
			}
			double focus = (onlyFocus ? Planet.FocusMultiplier(planet, gen.prefabDesc.fuelMask) : 1.0);
			Text obj = fuelTitle;
			string format = Lang.T("fuelOf");
			string name = ((Proto)gen).name;
			ItemProto obj2 = fuel;
			obj.text = string.Format(format, name, ((obj2 != null) ? ((Proto)obj2).name : null) ?? "") + ((focus > 1.0) ? string.Format(Lang.T("focusIncluded"), Math.Round((focus - 1.0) * 100.0)) : "");
			double num = amounts[powerMode ? 1u : 0u];
			if (fuel == null || num <= 0.0)
			{
				Clear();
				return;
			}
			PrefabDesc pd = gen.prefabDesc;
			double rate = (powerMode ? Calc.RateForPower(Run(1.0), num * Math.Pow(1000.0, unitIndex)) : num);
			Result result = Run(rate);
			if (result.PerMachine <= 0.0)
			{
				Clear();
				return;
			}
			resultValues[0].text = result.PerMachine.ToString("0.##") + " " + Lang.T("perMin");
			resultValues[1].text = Calc.Power(result.MachinePower);
			resultValues[2].text = Math.Ceiling(result.Machines - 1E-09) + "   (" + result.Machines.ToString("0.##") + ")";
			resultValues[3].text = rate.ToString("0.##") + " " + Lang.T("perMin");
			resultValues[4].text = Calc.Power(result.TotalPower);
			Result Run(double ratePerMinute)
			{
				return Calc.Run(pd.genEnergyPerTick, pd.useFuelPerTick, pd.fuelMask, ((Proto)fuel).ID, fuel.HeatValue, fuel.Productive, Calc.IncLevels[incIndex], ratePerMinute, focus);
			}
		}

		private static void Clear()
		{
			foreach (Text resultValue in resultValues)
			{
				resultValue.text = "—";
			}
		}

		private static Image Circle(Transform parent, Vector2 pos, float size, ItemProto item, Action onClick)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: 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_010a: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: 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_01a7: Expected O, but got Unknown
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Expected O, but got Unknown
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(fuelTpl, parent, false);
			foreach (Transform item2 in val.transform)
			{
				Transform val2 = item2;
				if (((Object)val2).name != "circle-fg" && ((Object)val2).name != "fuel-icon" && ((Object)val2).name != "button")
				{
					Object.Destroy((Object)(object)((Component)val2).gameObject);
				}
			}
			foreach (Transform item3 in val.transform.Find("fuel-icon"))
			{
				Object.Destroy((Object)(object)((Component)item3).gameObject);
			}
			StripLocalizers(val);
			Place((RectTransform)val.transform, pos, new Vector2(size, size));
			Image component = ((Component)val.transform.Find("fuel-icon")).GetComponent<Image>();
			component.sprite = ((item != null) ? item.iconSprite : null);
			((Behaviour)component).enabled = (Object)(object)component.sprite != (Object)null;
			((Graphic)component).rectTransform.sizeDelta = new Vector2(size * 0.62f, size * 0.62f);
			Image component2 = ((Component)val.transform.Find("circle-fg")).GetComponent<Image>();
			((Component)component2).transform.localEulerAngles = Vector3.zero;
			Transform obj = val.transform.Find("button");
			Button component3 = ((Component)obj).GetComponent<Button>();
			component3.onClick = new ButtonClickedEvent();
			((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
			{
				onClick();
			});
			UIButton component4 = ((Component)obj).GetComponent<UIButton>();
			if ((Object)(object)component4 != (Object)null)
			{
				component4.tips.itemId = ((Proto)(item?)).ID ?? 0;
				component4.tips.itemCount = 0;
				component4.tips.itemInc = 0;
				component4.tips.type = (ItemTipType)0;
				component4.tips.tipTitle = ((item != null) ? ((Proto)item).name : null) ?? "";
				component4.tips.tipText = "";
			}
			return component2;
		}

		private static Text NewText(Text tpl, Transform parent, Vector2 pos, Vector2 size, TextAnchor align, string s)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			Text obj = Object.Instantiate<Text>(tpl, parent, false);
			StripLocalizers(((Component)obj).gameObject);
			Place(((Graphic)obj).rectTransform, pos, size);
			obj.alignment = align;
			obj.text = s;
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		private static RectTransform NewRect(string name, Transform parent, Vector2 pos, Vector2 size)
		{
			//IL_0014: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0034: Expected O, but got Unknown
			RectTransform val = (RectTransform)new GameObject(name, new Type[1] { typeof(RectTransform) }).transform;
			((Transform)val).SetParent(parent, false);
			Place(val, pos, size);
			return val;
		}

		private static void Place(RectTransform rt, Vector2 pos, Vector2 size)
		{
			//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_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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 1f);
			rt.pivot = val;
			Vector2 anchorMin = (rt.anchorMax = val);
			rt.anchorMin = anchorMin;
			rt.anchoredPosition = pos;
			rt.sizeDelta = size;
			((Transform)rt).localScale = Vector3.one;
		}

		private static void StripLocalizers(GameObject go)
		{
			Localizer[] componentsInChildren = go.GetComponentsInChildren<Localizer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
		}
	}
}