Decompiled source of CrackedTerminal v1.1.0

plugins/CrackedTerminal/aj.CrackedTerminal.dll

Decompiled 4 days 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.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CrackedTerminal.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("aj.CrackedTerminal")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("CrackedTerminal")]
[assembly: AssemblyTitle("aj.CrackedTerminal")]
[assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was created with the assistance of generative AI (code); see the README credits for which assets.")]
[assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 CrackedTerminal
{
	internal sealed class CrackedScreen : MonoBehaviour
	{
		private const float RefWidth = 1920f;

		private const float RefHeight = 1080f;

		private const float WindowWidth = 1560f;

		private const float WindowHeight = 900f;

		private const float HeaderHeight = 92f;

		private const float FooterHeight = 52f;

		private const float MenuWidth = 250f;

		private const float PollEverySeconds = 0.25f;

		private static CrackedScreen? instance;

		private readonly List<Page> pages = new List<Page>
		{
			new MoonsPage(),
			new StorePage(),
			new StoragePage(),
			new BestiaryPage(),
			new MonstersPage(),
			new LogsPage(),
			new MonitorPage(),
			new TransmitPage(),
			new StatusPage()
		};

		private int current;

		private bool open;

		private Canvas? canvas;

		private RectTransform? pageArea;

		private TextMeshProUGUI? credits;

		private TextMeshProUGUI? quota;

		private TextMeshProUGUI? deadline;

		private TextMeshProUGUI? moon;

		private TextMeshProUGUI? dropship;

		private TextMeshProUGUI? status;

		private readonly List<Invert> menuItems = new List<Invert>();

		private float nextPoll;

		private float statusUntil;

		private string snapshot = "";

		private int seenLive = -1;

		private int seenDropship = -1;

		internal static bool IsOpen
		{
			get
			{
				if ((Object)(object)instance != (Object)null)
				{
					return instance.open;
				}
				return false;
			}
		}

		internal static int PageCount
		{
			get
			{
				if (!((Object)(object)instance != (Object)null))
				{
					return 0;
				}
				return instance.pages.Count;
			}
		}

		internal static void Create(GameObject host)
		{
			instance = host.AddComponent<CrackedScreen>();
		}

		internal static void Open()
		{
			if (!((Object)(object)instance == (Object)null) && !instance.open)
			{
				instance.Show();
			}
		}

		internal static void Close()
		{
			instance?.Hide();
		}

		internal static void FillCartForTest()
		{
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			foreach (Page page in instance.pages)
			{
				if (page is StorePage storePage)
				{
					storePage.FillForTest();
				}
			}
		}

		internal static void ShowPageForTest(int index)
		{
			if ((Object)(object)instance != (Object)null && instance.open && index >= 0 && index < instance.pages.Count)
			{
				instance.ShowPage(index);
			}
		}

		internal static void ShowCreature(string name)
		{
			if (!((Object)(object)instance == (Object)null))
			{
				int num = instance.pages.FindIndex((Page p) => p is BestiaryPage);
				if (num >= 0)
				{
					((BestiaryPage)instance.pages[num]).Select(name);
					instance.ShowPage(num);
				}
			}
		}

		internal static void OpenTextTerminal()
		{
			instance?.TextTerminal();
		}

		private void TextTerminal()
		{
			if (Ship.TextTerminalBusy)
			{
				Say("Someone else is at the text terminal. Everything is on this screen too.", ok: false);
				return;
			}
			Hide();
			TerminalHook.OpenPlainTerminal();
		}

		internal static void Say(string text, bool ok = true)
		{
			//IL_003e: 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)
			if (!((Object)(object)instance?.status == (Object)null))
			{
				((TMP_Text)instance.status).text = text;
				((Graphic)instance.status).color = (ok ? Ui.Accent : Ui.Warn);
				instance.statusUntil = Time.unscaledTime + 6f;
			}
		}

		internal static void Rebuild()
		{
			if (!((Object)(object)instance == (Object)null))
			{
				if ((Object)(object)instance.canvas != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)instance.canvas).gameObject);
				}
				instance.canvas = null;
				if (instance.open)
				{
					instance.Build();
					instance.ShowPage(instance.current);
				}
			}
		}

		private void Show()
		{
			PlayerControllerB local = Ship.Local;
			if (!((Object)(object)local == (Object)null))
			{
				if ((Object)(object)canvas == (Object)null)
				{
					Build();
				}
				open = true;
				((Component)canvas).gameObject.SetActive(true);
				local.inSpecialMenu = true;
				local.disableMoveInput = true;
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				HUDManager obj = HUDManager.Instance;
				if (obj != null)
				{
					obj.ClearControlTips();
				}
				Sounds.Enter();
				ShowPage(current);
			}
		}

		private void Hide()
		{
			if (!open)
			{
				return;
			}
			open = false;
			if (TransmitPage.typing)
			{
				TransmitPage.SetTyping(typing: false);
			}
			if ((Object)(object)canvas != (Object)null)
			{
				((Component)canvas).gameObject.SetActive(false);
			}
			PlayerControllerB local = Ship.Local;
			if ((Object)(object)local != (Object)null)
			{
				local.disableMoveInput = false;
				if (local.inSpecialMenu)
				{
					local.SetInSpecialMenu(false, (SpecialHUDMenu)1);
				}
				if (local.isHoldingObject && (Object)(object)local.currentlyHeldObjectServer != (Object)null)
				{
					local.currentlyHeldObjectServer.SetControlTipsForItem();
				}
			}
			Sounds.Leave();
		}

		private void Update()
		{
			if (!open)
			{
				return;
			}
			PlayerControllerB local = Ship.Local;
			if ((Object)(object)local == (Object)null || !local.inSpecialMenu || local.isPlayerDead || !local.isInHangarShipRoom)
			{
				Hide();
				return;
			}
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			Keys();
			if ((Object)(object)status != (Object)null && ((TMP_Text)status).text.Length > 0 && Time.unscaledTime > statusUntil)
			{
				((TMP_Text)status).text = "";
			}
			if (Time.unscaledTime >= nextPoll)
			{
				nextPoll = Time.unscaledTime + 0.25f;
				RefreshIfChanged();
			}
		}

		private void Keys()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			Keyboard val = Keyboard.current;
			if (val == null)
			{
				return;
			}
			EventSystem obj = EventSystem.current;
			GameObject val2 = ((obj != null) ? obj.currentSelectedGameObject : null);
			if ((Object)(object)val2 != (Object)null && (Object)(object)val2.GetComponent<TMP_InputField>() != (Object)null)
			{
				return;
			}
			if (((ButtonControl)val.tabKey).wasPressedThisFrame)
			{
				TextTerminal();
				return;
			}
			for (int i = 0; i < pages.Count; i++)
			{
				if (((ButtonControl)val[pages[i].Key]).wasPressedThisFrame)
				{
					Sounds.Click();
					ShowPage(i);
					break;
				}
			}
		}

		private void RefreshIfChanged()
		{
			Terminal terminal = Ship.Terminal;
			StartOfRound val = StartOfRound.Instance;
			string text = (((Object)(object)terminal == (Object)null || (Object)(object)val == (Object)null) ? "" : $"{terminal.groupCredits}|{terminal.numberOfItemsInDropship}|{terminal.useCreditsCooldown}|{val.currentLevelID}|{Ship.ShipState}|{TimeOfDay.Instance?.quotaFulfilled}|{Ship.RadarTarget}");
			bool num = pages[current].Changed() || text != snapshot || Live.Version != seenLive || Dropship.Version != seenDropship;
			UpdateHeader();
			if (num)
			{
				snapshot = text;
				seenLive = Live.Version;
				seenDropship = Dropship.Version;
				pages[current].Refresh();
			}
		}

		private void ShowPage(int index)
		{
			current = index;
			for (int i = 0; i < menuItems.Count; i++)
			{
				menuItems[i].SetSelected(i == index);
			}
			if (!((Object)(object)pageArea == (Object)null))
			{
				pages[current].Show(pageArea);
				UpdateHeader();
			}
		}

		private void Build()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			Ui.Scale = Plugin.BoundConfig.TextScale.Value;
			Terminal terminal = Ship.Terminal;
			if ((Object)(object)Ui.Font == (Object)null && (Object)(object)terminal != (Object)null && (Object)(object)terminal.screenText != (Object)null && (Object)(object)terminal.screenText.textComponent != (Object)null)
			{
				Ui.Font = terminal.screenText.textComponent.font;
			}
			GameObject val = new GameObject("CrackedTerminal", new Type[1] { typeof(RectTransform) });
			Object.DontDestroyOnLoad((Object)(object)val);
			canvas = val.AddComponent<Canvas>();
			canvas.renderMode = (RenderMode)0;
			canvas.sortingOrder = 50;
			CanvasScaler obj = val.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)1;
			obj.referenceResolution = new Vector2(1920f, 1080f);
			obj.matchWidthOrHeight = 0.5f;
			val.AddComponent<GraphicRaycaster>();
			Ui.Fill(((Graphic)Ui.Box(val.transform, "Backdrop", Ui.Backdrop)).rectTransform);
			RectTransform rectTransform = ((Graphic)Ui.Box(val.transform, "Window", Ui.Window)).rectTransform;
			rectTransform.sizeDelta = new Vector2(1560f, 900f);
			Ui.Frame(rectTransform, Ui.Line, 2f);
			BuildHeader(rectTransform);
			BuildMenu(rectTransform);
			BuildFooter(rectTransform);
			pageArea = Ui.Rect((Transform)(object)rectTransform, "Page");
			Ui.Fill(pageArea, 290f, 110f, 24f, 66f);
			Ui.Crt(rectTransform);
			((Component)canvas).gameObject.SetActive(open);
		}

		private void BuildHeader(RectTransform window)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_005b: 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_008f: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = Ui.Rect((Transform)(object)window, "Header");
			obj.anchorMin = new Vector2(0f, 1f);
			obj.anchorMax = Vector2.one;
			obj.pivot = new Vector2(0.5f, 1f);
			obj.sizeDelta = new Vector2(0f, 92f);
			Image obj2 = Ui.Box((Transform)(object)obj, "Line", Ui.Line);
			((Graphic)obj2).rectTransform.anchorMin = new Vector2(0f, 0f);
			((Graphic)obj2).rectTransform.anchorMax = new Vector2(1f, 0f);
			((Graphic)obj2).rectTransform.sizeDelta = new Vector2(-32f, 1.5f);
			TextMeshProUGUI val = Ui.Label((Transform)(object)obj, "CRACKED<color=#6BFF85>TERMINAL</color>", 36f, Ui.Text, (TextAlignmentOptions)4097);
			((TMP_Text)val).fontStyle = (FontStyles)1;
			((TMP_Text)val).rectTransform.anchorMin = new Vector2(0f, 0f);
			((TMP_Text)val).rectTransform.anchorMax = new Vector2(0f, 1f);
			((TMP_Text)val).rectTransform.pivot = new Vector2(0f, 0.5f);
			((TMP_Text)val).rectTransform.anchoredPosition = new Vector2(24f, 0f);
			((TMP_Text)val).rectTransform.sizeDelta = new Vector2(370f, 0f);
			((TMP_Text)val).ForceMeshUpdate(false, false);
			Image val2 = Ui.Cursor((Transform)(object)obj, 16f * Ui.Scale, 30f * Ui.Scale);
			RectTransform rectTransform = ((Graphic)val2).rectTransform;
			RectTransform rectTransform2 = ((Graphic)val2).rectTransform;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0f, 0.5f);
			rectTransform2.anchorMax = val3;
			rectTransform.anchorMin = val3;
			((Graphic)val2).rectTransform.pivot = new Vector2(0f, 0.5f);
			((Graphic)val2).rectTransform.anchoredPosition = new Vector2(24f + ((TMP_Text)val).preferredWidth + 6f, 0f);
			RectTransform obj3 = Ui.Rect((Transform)(object)obj, "Stats");
			Ui.Fill(obj3, 400f, 8f, 24f, 8f);
			Ui.Column(obj3, 2f);
			HorizontalLayoutGroup val4 = Ui.Row((Transform)(object)obj3, 40f, 16f);
			credits = Ui.Label(((Component)val4).transform, "", 28f, Ui.Accent, (TextAlignmentOptions)4097);
			((TMP_Text)credits).fontStyle = (FontStyles)1;
			Ui.Size(((Component)credits).gameObject, 300f);
			quota = Ui.Label(((Component)val4).transform, "", 22f, null, (TextAlignmentOptions)4097);
			Ui.Size(((Component)quota).gameObject, -1f, -1f, 1f);
			deadline = Ui.Label(((Component)val4).transform, "", 22f, Ui.Text, (TextAlignmentOptions)4100);
			Ui.Size(((Component)deadline).gameObject, -1f, -1f, 1f);
			HorizontalLayoutGroup val5 = Ui.Row((Transform)(object)obj3, 32f, 16f);
			moon = Ui.Label(((Component)val5).transform, "", 18f, Ui.Dim, (TextAlignmentOptions)4097);
			Ui.Size(((Component)moon).gameObject, -1f, -1f, 1f);
			dropship = Ui.Label(((Component)val5).transform, "", 18f, Ui.Dim, (TextAlignmentOptions)4100);
			Ui.Size(((Component)dropship).gameObject, -1f, -1f, 1f);
		}

		private void BuildMenu(RectTransform window)
		{
			//IL_000d: 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_0037: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = Ui.Rect((Transform)(object)window, "Menu");
			val.anchorMin = Vector2.zero;
			val.anchorMax = new Vector2(0f, 1f);
			val.pivot = new Vector2(0f, 0.5f);
			val.offsetMin = new Vector2(16f, 66f);
			val.offsetMax = new Vector2(266f, -110f);
			Ui.Column(val, 4f);
			Image obj = Ui.Box((Transform)(object)window, "MenuLine", Ui.Line);
			((Graphic)obj).rectTransform.anchorMin = Vector2.zero;
			((Graphic)obj).rectTransform.anchorMax = new Vector2(0f, 1f);
			((Graphic)obj).rectTransform.pivot = new Vector2(0f, 0.5f);
			((Graphic)obj).rectTransform.offsetMin = new Vector2(278f, 66f);
			((Graphic)obj).rectTransform.offsetMax = new Vector2(279.5f, -110f);
			menuItems.Clear();
			for (int i = 0; i < pages.Count; i++)
			{
				int index = i;
				Page page = pages[i];
				Button val2 = Ui.Button((Transform)(object)val, page.Title, delegate
				{
					ShowPage(index);
				}, primary: false, enabled: true, 22f, 48f, -1f, framed: false, i == current);
				TextMeshProUGUI componentInChildren = ((Component)val2).GetComponentInChildren<TextMeshProUGUI>();
				((TMP_Text)componentInChildren).alignment = (TextAlignmentOptions)4097;
				((TMP_Text)componentInChildren).text = "> " + page.Title + "<pos=74%><alpha=#70>[" + ((object)page.Key/*cast due to .constrained prefix*/).ToString().ToUpper() + "]";
				menuItems.Add(((Component)val2).GetComponent<Invert>());
			}
		}

		private void BuildFooter(RectTransform window)
		{
			//IL_000d: 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_0037: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = Ui.Rect((Transform)(object)window, "Footer");
			val.anchorMin = Vector2.zero;
			val.anchorMax = new Vector2(1f, 0f);
			val.pivot = new Vector2(0.5f, 0f);
			val.sizeDelta = new Vector2(0f, 52f);
			Image obj = Ui.Box((Transform)(object)val, "Line", Ui.Line);
			((Graphic)obj).rectTransform.anchorMin = new Vector2(0f, 1f);
			((Graphic)obj).rectTransform.anchorMax = Vector2.one;
			((Graphic)obj).rectTransform.sizeDelta = new Vector2(-32f, 1.5f);
			((Component)obj).gameObject.AddComponent<LayoutElement>().ignoreLayout = true;
			HorizontalLayoutGroup obj2 = ((Component)val).gameObject.AddComponent<HorizontalLayoutGroup>();
			((LayoutGroup)obj2).padding = new RectOffset(18, 18, 6, 6);
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 10f;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = true;
			Ui.Size(((Component)Ui.Label((Transform)(object)val, "[ESC] CLOSE   [TAB] TEXT TERMINAL   [LETTER] PAGE", 18f, Ui.Dim, (TextAlignmentOptions)4097)).gameObject, 600f);
			status = Ui.Label((Transform)(object)val, "", 22f, Ui.Accent, (TextAlignmentOptions)514);
			Ui.Size(((Component)status).gameObject, -1f, -1f, 1f);
			Ui.Size(((Component)Ui.Button((Transform)(object)val, "A-", delegate
			{
				TextSize(-0.1f);
			}, primary: false, enabled: true, 18f, 38f, 56f)).gameObject, 56f);
			Ui.Size(((Component)Ui.Button((Transform)(object)val, "A+", delegate
			{
				TextSize(0.1f);
			}, primary: false, enabled: true, 18f, 38f, 56f)).gameObject, 56f);
			Ui.Size(((Component)Ui.Button((Transform)(object)val, "TEXT TERMINAL", TextTerminal, primary: false, enabled: true, 18f, 38f, 200f)).gameObject, 200f);
			Ui.Size(((Component)Ui.Button((Transform)(object)val, "CLOSE", Hide, primary: false, enabled: true, 18f, 38f, 120f)).gameObject, 120f);
		}

		private static void TextSize(float step)
		{
			ConfigEntry<float> textScale = Plugin.BoundConfig.TextScale;
			textScale.Value = Mathf.Clamp(Mathf.Round((textScale.Value + step) * 10f) / 10f, 0.7f, 1.6f);
			Rebuild();
		}

		private void UpdateHeader()
		{
			if (!((Object)(object)credits == (Object)null))
			{
				TimeOfDay val = TimeOfDay.Instance;
				StartOfRound val2 = StartOfRound.Instance;
				((TMP_Text)credits).text = Ui.Money(Ship.Credits) + (Ship.Busy ? " <size=60%><color=#FFBD4D>syncing…</color></size>" : "");
				((TMP_Text)quota).text = (((Object)(object)val != (Object)null) ? ("QUOTA  " + Ui.Money(val.quotaFulfilled) + " / " + Ui.Money(val.profitQuota)) : "");
				((TMP_Text)deadline).text = ((Ship.Deadline.Length > 0) ? ("DEADLINE  " + Ship.Deadline) : "");
				((TMP_Text)moon).text = (((Object)(object)val2?.currentLevel != (Object)null) ? (val2.currentLevel.PlanetName + " · " + Ship.Weather(val2.currentLevel) + " · " + Ship.ShipState).ToUpperInvariant() : "");
				((TMP_Text)dropship).text = Dropship.Summary.ToUpperInvariant();
			}
		}
	}
	public static class CrackedTerminalTest
	{
		private const int TestCredits = 2000;

		private static readonly string[] MildMonsters = new string[4] { "Hoarding bug", "Centipede", "Puffer", "Blob" };

		private static readonly Func<PlayerControllerB, bool> UseConditionsMet = AccessTools.MethodDelegate<Func<PlayerControllerB, bool>>(AccessTools.Method(typeof(PlayerControllerB), "InteractTriggerUseConditionsMet", (Type[])null, (Type[])null), (object)null, true);

		public static bool IsOpen => CrackedScreen.IsOpen;

		public static bool TextTerminalBusy => Ship.TextTerminalBusy;

		public static int PageCount => CrackedScreen.PageCount;

		public static int MonstersInside => Ship.InsideMonsters().Sum((Ship.Monster m) => m.Count);

		public static int CreaturesScanned => Ship.Creatures().Count;

		public static void OpenScreen()
		{
			CrackedScreen.Open();
		}

		public static void UseTerminal()
		{
			PlayerControllerB local = Ship.Local;
			if ((Object)(object)local != (Object)null)
			{
				InteractTrigger? trigger = Ship.Trigger;
				if (trigger != null)
				{
					trigger.Interact(((Component)local).transform);
				}
			}
		}

		public static bool PressEAtTerminal()
		{
			PlayerControllerB local = Ship.Local;
			InteractTrigger trigger = Ship.Trigger;
			if ((Object)(object)local == (Object)null || (Object)(object)trigger == (Object)null)
			{
				return false;
			}
			local.hoveringOverTrigger = trigger;
			bool flag = UseConditionsMet(local);
			if (flag)
			{
				trigger.Interact(local.thisPlayerBody);
			}
			Plugin.Logger.LogInfo((object)$"CTTEST press E: allowed {flag}, text terminal busy {Ship.TextTerminalBusy}, screen open {CrackedScreen.IsOpen}");
			return flag;
		}

		public static void SitAtTextTerminal()
		{
			CrackedScreen.Close();
			TerminalHook.OpenPlainTerminal();
		}

		public static void LeaveTextTerminal()
		{
			Terminal terminal = Ship.Terminal;
			if ((Object)(object)terminal != (Object)null && terminal.terminalInUse)
			{
				terminal.QuitTerminal(true);
			}
		}

		public static void ShowPage(int index)
		{
			CrackedScreen.ShowPageForTest(index);
		}

		public static void FillCart()
		{
			CrackedScreen.FillCartForTest();
		}

		public static void GiveCredits()
		{
			Terminal terminal = Ship.Terminal;
			if ((Object)(object)terminal == (Object)null || (Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer)
			{
				HUDManager instance = HUDManager.Instance;
				if (instance != null)
				{
					instance.DisplayTip("CrackedTerminal test", "Only the host can give credits.", false, false, "LC_Tip1");
				}
				return;
			}
			terminal.groupCredits += 2000;
			terminal.SyncGroupCreditsClientRpc(terminal.groupCredits, terminal.numberOfItemsInDropship);
			HUDManager instance2 = HUDManager.Instance;
			if (instance2 != null)
			{
				instance2.DisplayTip("CrackedTerminal test", $"+{2000} credits.", false, false, "LC_Tip1");
			}
		}

		public static void ScanAllCreatures()
		{
			Terminal terminal = Ship.Terminal;
			if ((Object)(object)terminal == (Object)null || (Object)(object)HUDManager.Instance == (Object)null)
			{
				return;
			}
			for (int i = 0; i < terminal.enemyFiles.Count; i++)
			{
				if ((Object)(object)terminal.enemyFiles[i] != (Object)null && !terminal.scannedEnemyIDs.Contains(i))
				{
					HUDManager.Instance.ScanNewCreatureServerRpc(i);
				}
			}
			HUDManager.Instance.DisplayTip("CrackedTerminal test", $"Scanned all {Ship.CreatureCount} creatures.", false, false, "LC_Tip1");
		}

		public static void SpawnInsideMonsters()
		{
			//IL_0113: 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)
			RoundManager instance = RoundManager.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer || !Ship.OnAMoon || instance.insideAINodes == null || instance.insideAINodes.Length == 0)
			{
				HUDManager instance2 = HUDManager.Instance;
				if (instance2 != null)
				{
					instance2.DisplayTip("CrackedTerminal test", "Host only, landed on a moon.", false, false, "LC_Tip1");
				}
				return;
			}
			List<EnemyType> list = (from e in instance.currentLevel.Enemies
				select e.enemyType into e
				where (Object)(object)e != (Object)null && (Object)(object)e.enemyPrefab != (Object)null
				select e).OrderBy(delegate(EnemyType e)
			{
				int num3 = Array.IndexOf(MildMonsters, e.enemyName);
				return (num3 < 0) ? 99 : num3;
			}).Take(2).ToList();
			int num = 0;
			for (int num2 = 0; num2 < 3; num2++)
			{
				if (list.Count <= 0)
				{
					break;
				}
				GameObject val = instance.insideAINodes[Random.Range(0, instance.insideAINodes.Length)];
				if (!((Object)(object)val == (Object)null))
				{
					instance.SpawnEnemyGameObject(val.transform.position, 0f, -1, list[num2 % list.Count]);
					num++;
				}
			}
			Plugin.Logger.LogInfo((object)string.Format("CTTEST spawned {0} inside: {1}", num, string.Join(", ", list.Select((EnemyType k) => k.enemyName))));
			HUDManager instance3 = HUDManager.Instance;
			if (instance3 != null)
			{
				instance3.DisplayTip("CrackedTerminal test", $"Spawned {num} monsters inside.", false, false, "LC_Tip1");
			}
		}

		public static void OrderThreeKinds()
		{
			Ship.Order order = Ship.OrderCart((from p in (from p in Ship.Items.Select((Item item, int index) => (item: item, index: index))
					orderby Ship.ItemPrice(p.index)
					select p).Take(3)
				select (index: p.index, 1)).ToList());
			string text = ((order.Placed.Count == 0) ? order.Problem : ($"Ordered {order.Placed.Count} kinds for ${order.Cost}" + ((order.Left.Count > 0) ? $", {order.Left.Count} left over" : "")));
			Plugin.Logger.LogInfo((object)("CTTEST order: " + text));
			HUDManager instance = HUDManager.Instance;
			if (instance != null)
			{
				instance.DisplayTip("CrackedTerminal test", text, false, false, "LC_Tip1");
			}
		}
	}
	internal sealed class Dropship : MonoBehaviour
	{
		internal enum State : byte
		{
			Idle,
			Waiting,
			Coming,
			Landed
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__Receive;
		}

		private const string Message = "CrackedTerminal.Dropship";

		private const float SendEverySeconds = 5f;

		private const float CheckEverySeconds = 0.25f;

		private const float WaitBeforeComing = 40f;

		private const float StayLanded = 30f;

		internal static State Now;

		internal static float Seconds;

		internal static int[] Waiting = new int[0];

		internal static int[] Delivering = new int[0];

		internal static int Version;

		private static readonly FieldRef<ItemDropship, List<int>> ItemsToDeliver = AccessTools.FieldRefAccess<ItemDropship, List<int>>("itemsToDeliver");

		private float nextCheck;

		private float nextSend;

		private string lastSent = "";

		private ItemDropship? dropship;

		internal static string Summary
		{
			get
			{
				switch (Now)
				{
				case State.Waiting:
					if (!(Seconds >= 0f))
					{
						return "Dropship comes once the ship lands";
					}
					return $"Dropship comes in {Mathf.CeilToInt(Seconds)} s";
				case State.Coming:
					return "Dropship on its way";
				case State.Landed:
					return $"Dropship landed, leaves in {Mathf.Max(0, Mathf.CeilToInt(Seconds))} s";
				default:
					if (Ship.InDropship <= 0)
					{
						return "Dropship idle";
					}
					return $"{Ship.InDropship} item(s) ordered";
				}
			}
		}

		internal static void Register()
		{
			//IL_004b: 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_0056: Expected O, but got Unknown
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null)
			{
				return;
			}
			singleton.CustomMessagingManager.UnregisterNamedMessageHandler("CrackedTerminal.Dropship");
			if (!singleton.IsServer)
			{
				CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager;
				object obj = <>O.<0>__Receive;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = Receive;
					<>O.<0>__Receive = val;
					obj = (object)val;
				}
				customMessagingManager.RegisterNamedMessageHandler("CrackedTerminal.Dropship", (HandleNamedMessageDelegate)obj);
			}
		}

		private void Update()
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsServer || Time.unscaledTime < nextCheck)
			{
				return;
			}
			nextCheck = Time.unscaledTime + 0.25f;
			Terminal terminal = Ship.Terminal;
			if (!((Object)(object)terminal == (Object)null))
			{
				if ((Object)(object)dropship == (Object)null)
				{
					dropship = Object.FindObjectOfType<ItemDropship>();
				}
				float num = 0f;
				int[] delivering = new int[0];
				State state;
				if ((Object)(object)dropship != (Object)null && dropship.shipLanded)
				{
					state = State.Landed;
					num = 30f - dropship.shipTimer;
					delivering = ItemsToDeliver.Invoke(dropship).ToArray();
				}
				else if ((Object)(object)dropship != (Object)null && dropship.deliveringOrder)
				{
					state = State.Coming;
					delivering = ItemsToDeliver.Invoke(dropship).ToArray();
				}
				else if (terminal.orderedItemsFromTerminal.Count > 0)
				{
					state = State.Waiting;
					num = (((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipHasLanded && (Object)(object)dropship != (Object)null) ? (40f - dropship.shipTimer) : (-1f));
				}
				else
				{
					state = State.Idle;
				}
				Set(state, num, terminal.orderedItemsFromTerminal.ToArray(), delivering);
				string text = string.Format("{0}|{1}|{2}|{3}", state, Mathf.CeilToInt(num), string.Join(",", Waiting), string.Join(",", Delivering));
				if (text != lastSent || Time.unscaledTime >= nextSend)
				{
					lastSent = text;
					nextSend = Time.unscaledTime + 5f;
					Send();
				}
			}
		}

		private static void Set(State state, float seconds, int[] waiting, int[] delivering)
		{
			bool num = state != Now || !waiting.SequenceEqual(Waiting) || !delivering.SequenceEqual(Delivering);
			Now = state;
			Seconds = seconds;
			Waiting = waiting;
			Delivering = delivering;
			if (num)
			{
				Version++;
			}
		}

		private unsafe static void Send()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0068: 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_007d: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			if (((singleton != null) ? singleton.CustomMessagingManager : null) == null || singleton.ConnectedClientsIds.Count <= 1)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(64, (Allocator)2, 1024);
			try
			{
				byte now = (byte)Now;
				((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref now, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref Seconds, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(Waiting, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(Delivering, default(ForPrimitives));
				singleton.CustomMessagingManager.SendNamedMessageToAll("CrackedTerminal.Dropship", val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private static void Receive(ulong sender, FastBufferReader reader)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			byte state = default(byte);
			((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref state, default(ForPrimitives));
			float seconds = default(float);
			((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref seconds, default(ForPrimitives));
			int[] waiting = default(int[]);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref waiting, default(ForPrimitives));
			int[] delivering = default(int[]);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref delivering, default(ForPrimitives));
			Set((State)state, seconds, waiting, delivering);
		}

		internal static string Describe(int[] items)
		{
			Item[] names = Ship.Items;
			return string.Join(", ", from i in items
				where i >= 0 && i < names.Length
				group i by i into g
				select (g.Count() <= 1) ? names[g.Key].itemName : $"{names[g.Key].itemName} x{g.Count()}");
		}
	}
	[HarmonyPatch]
	internal static class Live
	{
		internal static int Version;

		[HarmonyPatch(typeof(Terminal), "SyncGroupCreditsClientRpc")]
		[HarmonyPatch(typeof(Terminal), "BuyItemsServerRpc")]
		[HarmonyPatch(typeof(Terminal), "BuyVehicleClientRpc")]
		[HarmonyPatch(typeof(Terminal), "SyncTerminalValuesClientRpc")]
		[HarmonyPatch(typeof(StartOfRound), "ChangeLevelClientRpc")]
		[HarmonyPatch(typeof(StartOfRound), "BuyShipUnlockableClientRpc")]
		[HarmonyPatch(typeof(StartOfRound), "ReturnUnlockableFromStorageClientRpc")]
		[HarmonyPatch(typeof(HUDManager), "ScanNewCreatureClientRpc")]
		[HarmonyPatch(typeof(HUDManager), "GetNewStoryLogClientRpc")]
		[HarmonyPostfix]
		private static void Changed()
		{
			Version++;
		}
	}
	internal sealed class StoragePage : Page
	{
		internal override string Title => "STORAGE";

		internal override Key Key => (Key)29;

		protected override void Build(RectTransform area)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			RectTransform parent = List(area, "storage");
			List<Ship.Unlock> list = Ship.Stored();
			if (list.Count == 0)
			{
				Ui.Label((Transform)(object)parent, "Nothing in storage.", 22f, Ui.Dim, (TextAlignmentOptions)4097);
			}
			foreach (Ship.Unlock item in list)
			{
				Ship.Unlock u = item;
				HorizontalLayoutGroup obj = Ui.Row((Transform)(object)parent, 50f, 12f);
				((LayoutGroup)obj).padding = new RectOffset(10, 0, 0, 0);
				Page.Cell(((Component)obj).transform, ">", 18f, Ui.Dim, (TextAlignmentOptions)4097);
				Page.Cell(((Component)obj).transform, u.Name, -1f, null, (TextAlignmentOptions)4097);
				Ui.Size(((Component)Ui.Button(((Component)obj).transform, "Take out", delegate
				{
					Page.Report(Ship.Retrieve(u));
					Redraw();
				}, primary: false, enabled: true, 18f, 40f)).gameObject, 170f);
			}
		}
	}
	internal abstract class EntriesPage : Page
	{
		private string selected = "";

		protected abstract string Empty { get; }

		internal void Select(string name)
		{
			selected = name;
		}

		protected abstract List<TerminalNode> Entries();

		protected abstract string NameOf(TerminalNode node);

		protected override void Build(RectTransform area)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			List<TerminalNode> list = Entries();
			if (list.Count == 0)
			{
				Ui.Label((Transform)(object)area, Empty, 22f, Ui.Dim, (TextAlignmentOptions)4097);
				return;
			}
			if (!list.Exists((TerminalNode e) => NameOf(e) == selected))
			{
				selected = NameOf(list[0]);
			}
			(RectTransform left, RectTransform right) tuple = Page.Split(area, 0.34f);
			RectTransform item = tuple.left;
			RectTransform item2 = tuple.right;
			RectTransform parent = List(item, "entries");
			foreach (TerminalNode item3 in list)
			{
				string name = NameOf(item3);
				Page.Cell(((Component)Page.ListRow((Transform)(object)parent, delegate
				{
					selected = name;
					Redraw();
				}, name == selected, 46f)).transform, name, -1f, null, (TextAlignmentOptions)4097);
			}
			TerminalNode val = list.Find((TerminalNode e) => NameOf(e) == selected);
			RectTransform val2 = Ui.Card((Transform)(object)item2, "Entry");
			Ui.Fill(val2);
			TextMeshProUGUI obj = Ui.Label((Transform)(object)val2, selected.ToUpperInvariant(), 28f, Ui.Accent, (TextAlignmentOptions)4097);
			((TMP_Text)obj).fontStyle = (FontStyles)1;
			Ui.Size(((Component)obj).gameObject, -1f, 44f);
			if ((Object)(object)val.displayTexture != (Object)null)
			{
				RawImage obj2 = ((Component)Ui.Rect((Transform)(object)val2, "Picture")).gameObject.AddComponent<RawImage>();
				obj2.texture = val.displayTexture;
				((Graphic)obj2).raycastTarget = false;
				AspectRatioFitter obj3 = ((Component)obj2).gameObject.AddComponent<AspectRatioFitter>();
				obj3.aspectMode = (AspectMode)3;
				obj3.aspectRatio = (float)val.displayTexture.width / (float)Mathf.Max(1, val.displayTexture.height);
				Ui.Size(((Component)obj2).gameObject, -1f, 240f);
			}
			RectTransform val3 = Ui.Rect((Transform)(object)val2, "Body");
			Ui.Size(((Component)val3).gameObject, -1f, -1f, -1f, 1f);
			Ui.Label((Transform)(object)List(val3, "entry-" + selected), Tidy(val.displayText), 18f, Ui.Text, (TextAlignmentOptions)257, wrap: true);
		}

		private static string Tidy(string text)
		{
			text = (text ?? "").Replace("\r", "");
			while (text.Contains("\n\n\n"))
			{
				text = text.Replace("\n\n\n", "\n\n");
			}
			return Regex.Replace(text, "\\[[A-Za-z]+\\]", "").Trim();
		}
	}
	internal sealed class BestiaryPage : EntriesPage
	{
		internal override string Title => "BESTIARY";

		internal override Key Key => (Key)16;

		protected override string Empty => $"No creatures scanned yet ({Ship.CreatureCount} to find). Point your scanner (right mouse button) at a creature and its file shows up here for the whole crew.";

		protected override List<TerminalNode> Entries()
		{
			return Ship.Creatures();
		}

		protected override string NameOf(TerminalNode node)
		{
			return Ship.CreatureName(node);
		}
	}
	internal sealed class MonstersPage : Page
	{
		private string drawn = "";

		internal override string Title => "MONSTERS";

		internal override Key Key => (Key)28;

		internal override bool Changed()
		{
			string text = Ship.OnAMoon + Ship.MonstersSignature;
			if (text == drawn)
			{
				return false;
			}
			drawn = text;
			return true;
		}

		protected override void Build(RectTransform area)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = Ui.Card((Transform)(object)area, "Monsters", "Inside the facility");
			Ui.Fill(val);
			if (!Ship.OnAMoon)
			{
				Ui.Size(((Component)Ui.Label((Transform)(object)val, "The ship is in orbit. Land on a moon to see what's inside its facility.", 22f, Ui.Dim, (TextAlignmentOptions)4097, wrap: true)).gameObject, -1f, 60f);
				return;
			}
			List<Ship.Monster> list = Ship.InsideMonsters();
			int num = 0;
			foreach (Ship.Monster item in list)
			{
				num += item.Count;
			}
			Ui.Size(((Component)Ui.Label((Transform)(object)val, (list.Count == 0) ? "Nothing alive inside right now." : string.Format("{0} alive, {1} kind{2}. Updates live as they spawn and die.", num, list.Count, (list.Count == 1) ? "" : "s"), 22f, (list.Count == 0) ? Ui.Dim : Ui.Text, (TextAlignmentOptions)4097)).gameObject, -1f, 40f);
			Ui.Divider((Transform)(object)val);
			RectTransform parent = List(val, "monsters");
			foreach (Ship.Monster item2 in list)
			{
				Ship.Monster m = item2;
				HorizontalLayoutGroup obj = Page.ListRow((Transform)(object)parent, delegate
				{
					if ((Object)(object)m.File != (Object)null)
					{
						CrackedScreen.ShowCreature(Ship.CreatureName(m.File));
					}
				}, selected: false, 50f);
				Page.Cell(((Component)obj).transform, $"{m.Count}x", 90f, Ui.Accent, (TextAlignmentOptions)4097);
				Page.Cell(((Component)obj).transform, m.Name, -1f, null, (TextAlignmentOptions)4097);
				Page.Cell(((Component)obj).transform, ((Object)(object)m.File != (Object)null) ? "BESTIARY >" : "not scanned", 220f, ((Object)(object)m.File != (Object)null) ? Ui.Text : Ui.Dim, (TextAlignmentOptions)4100, 18f);
			}
		}
	}
	internal sealed class LogsPage : EntriesPage
	{
		internal override string Title => "LOGS";

		internal override Key Key => (Key)26;

		protected override string Empty => "No logs found yet. They're hidden around the moons.";

		protected override List<TerminalNode> Entries()
		{
			return Ship.Logs();
		}

		protected override string NameOf(TerminalNode node)
		{
			string text = (node.displayText ?? "").Trim();
			int num = text.IndexOf('\n');
			return ((num > 0) ? text.Substring(0, num) : text).Trim();
		}
	}
	internal sealed class MoonsPage : Page
	{
		private enum Filter
		{
			All,
			Affordable,
			Free
		}

		private enum Sort
		{
			Catalogue,
			Price,
			Name,
			Risk
		}

		private static readonly string[] RiskOrder = new string[9] { "Safe", "D", "C", "B", "A", "S", "S+", "S++", "S+++" };

		private Filter filter;

		private Sort sort;

		private int selected = -1;

		private string confirm = "";

		internal override string Title => "MOONS";

		internal override Key Key => (Key)27;

		protected override void Build(RectTransform area)
		{
			//IL_012a: 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_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Invalid comparison between Unknown and I4
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			List<Ship.Moon> all = Ship.Moons();
			if (selected < 0 && (Object)(object)StartOfRound.Instance != (Object)null)
			{
				selected = StartOfRound.Instance.currentLevelID;
			}
			HorizontalLayoutGroup val = Page.Toolbar(area);
			foreach (Filter value in Enum.GetValues(typeof(Filter)))
			{
				Filter current = value;
				Ui.Size(((Component)Ui.Button(((Component)val).transform, (value == Filter.Affordable) ? "Can afford" : value.ToString(), delegate
				{
					filter = current;
					Redraw();
				}, primary: false, enabled: true, 18f, 42f, -1f, framed: true, filter == value)).gameObject, 150f);
			}
			Ui.Size(((Component)Ui.Label(((Component)val).transform, "SORT", 18f, Ui.Dim, (TextAlignmentOptions)4100)).gameObject, 70f);
			foreach (Sort value2 in Enum.GetValues(typeof(Sort)))
			{
				Sort current2 = value2;
				Ui.Size(((Component)Ui.Button(((Component)val).transform, (value2 == Sort.Catalogue) ? "Default" : value2.ToString(), delegate
				{
					sort = current2;
					Redraw();
				}, primary: false, enabled: true, 18f, 42f, -1f, framed: true, sort == value2)).gameObject, 110f);
			}
			Ui.Size(((Component)Ui.Button(((Component)val).transform, "Random", delegate
			{
				PickRandom(all);
			}, primary: false, enabled: true, 18f, 42f)).gameObject, 120f);
			(RectTransform left, RectTransform right) tuple = Page.Split(area, 0.58f, Page.ToolbarSpace());
			RectTransform item = tuple.left;
			RectTransform item2 = tuple.right;
			List<Ship.Moon> list = Shown(all);
			RectTransform parent = List(item, "moons");
			if (list.Count == 0)
			{
				Ui.Label((Transform)(object)parent, "No moons match.", 22f, Ui.Dim, (TextAlignmentOptions)4097);
			}
			foreach (Ship.Moon item3 in list)
			{
				Ship.Moon m = item3;
				HorizontalLayoutGroup obj = Page.ListRow((Transform)(object)parent, delegate
				{
					selected = m.Level.levelID;
					confirm = "";
					Redraw();
				}, m.Level.levelID == selected);
				Page.Cell(((Component)obj).transform, m.Name + (m.Current ? "  <alpha=#99>[HERE]<alpha=#FF>" : "") + (m.Hidden ? "  <alpha=#70>[HIDDEN]<alpha=#FF>" : "") + (m.Company ? "  <alpha=#70>[COMPANY]<alpha=#FF>" : ""), -1f, null, (TextAlignmentOptions)4097);
				Page.Cell(((Component)obj).transform, m.Company ? "" : m.Level.riskLevel, 70f, Ui.Dim, (TextAlignmentOptions)514);
				Page.Cell(((Component)obj).transform, Ship.Weather(m.Level), 150f, ((int)m.Level.currentWeather == -1) ? Ui.Dim : Ui.Warn, (TextAlignmentOptions)4097);
				Page.Cell(((Component)obj).transform, (m.Cost == 0) ? "FREE" : Ui.Money(m.Cost), 110f, (m.Cost > Ship.Credits) ? Ui.Bad : Ui.Text, (TextAlignmentOptions)4100);
			}
			Ship.Moon moon = all.FirstOrDefault((Ship.Moon moon2) => moon2.Level.levelID == selected);
			if (moon != null)
			{
				Details(item2, moon);
			}
		}

		private List<Ship.Moon> Shown(List<Ship.Moon> all)
		{
			IEnumerable<Ship.Moon> source = all.Where((Ship.Moon m) => Plugin.BoundConfig.ShowHiddenMoons.Value || !m.Hidden || m.Current);
			if (filter == Filter.Affordable)
			{
				source = source.Where((Ship.Moon m) => m.Cost <= Ship.Credits);
			}
			if (filter == Filter.Free)
			{
				source = source.Where((Ship.Moon m) => m.Cost == 0);
			}
			switch (sort)
			{
			case Sort.Price:
				source = source.OrderBy((Ship.Moon m) => m.Cost);
				break;
			case Sort.Name:
				source = source.OrderBy((Ship.Moon m) => m.Name);
				break;
			case Sort.Risk:
				source = source.OrderBy((Ship.Moon m) => Array.IndexOf(RiskOrder, m.Level.riskLevel));
				break;
			}
			return source.ToList();
		}

		private void PickRandom(List<Ship.Moon> all)
		{
			List<Ship.Moon> list = all.Where((Ship.Moon m) => !m.Company && !m.Current && m.Cost <= Ship.Credits && !m.Level.lockedForDemo).ToList();
			if (list.Count == 0)
			{
				CrackedScreen.Say("No other moon you can afford.", ok: false);
				return;
			}
			selected = list[Random.Range(0, list.Count)].Level.levelID;
			confirm = "";
			Redraw();
		}

		private void Details(RectTransform right, Ship.Moon moon)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = Ui.Card((Transform)(object)right, "Details");
			Ui.Fill(val);
			TextMeshProUGUI obj = Ui.Label((Transform)(object)val, moon.Name.ToUpperInvariant(), 36f, Ui.Accent, (TextAlignmentOptions)4097);
			((TMP_Text)obj).fontStyle = (FontStyles)1;
			Ui.Size(((Component)obj).gameObject, -1f, 48f);
			Line((Transform)(object)val, "Risk", moon.Company ? "None" : moon.Level.riskLevel);
			Line((Transform)(object)val, "Weather", Ship.Weather(moon.Level));
			Line((Transform)(object)val, "Route", (moon.Cost == 0) ? "Free" : Ui.Money(moon.Cost));
			Ui.Divider((Transform)(object)val);
			Ui.Size(((Component)Ui.Label((Transform)(object)val, Tidy(moon.Level.LevelDescription), 18f, Ui.Dim, (TextAlignmentOptions)257, wrap: true)).gameObject, -1f, -1f, -1f, 1f);
			StartOfRound instance = StartOfRound.Instance;
			string text = (moon.Current ? "You're already here." : (((Object)(object)instance == (Object)null || !instance.inShipPhase || instance.travellingToNewLevel) ? "Route from orbit, between days." : ((moon.Cost > Ship.Credits) ? "Not enough credits." : (moon.Level.lockedForDemo ? "Locked." : ""))));
			if (text.Length > 0)
			{
				Ui.Size(((Component)Ui.Label((Transform)(object)val, text, 22f, Ui.Warn, (TextAlignmentOptions)4097)).gameObject, -1f, 40f);
			}
			bool flag = confirm == moon.Name;
			Ui.Button((Transform)(object)val, flag ? ("Confirm: route to " + moon.Name + " (" + Ui.Money(moon.Cost) + ")") : ("Route to " + moon.Name), delegate
			{
				if (!Page.Confirming(ref confirm, moon.Name))
				{
					Redraw();
				}
				else
				{
					Page.Report(Ship.Route(moon));
					Redraw();
				}
			}, primary: true, text.Length == 0, 22f, 56f);
		}

		private static void Line(Transform card, string label, string value)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			HorizontalLayoutGroup obj = Ui.Row(card, 34f);
			Page.Cell(((Component)obj).transform, label, 140f, Ui.Dim, (TextAlignmentOptions)4097);
			Page.Cell(((Component)obj).transform, value, -1f, null, (TextAlignmentOptions)4097);
		}

		private static string Tidy(string text)
		{
			return (text ?? "").Replace("\n", " ").Replace("  ", " ").Trim();
		}
	}
	internal abstract class Page
	{
		private RectTransform? area;

		private readonly Dictionary<string, float> scrolls = new Dictionary<string, float>();

		private readonly Dictionary<string, ScrollRect> liveScrolls = new Dictionary<string, ScrollRect>();

		internal abstract string Title { get; }

		internal abstract Key Key { get; }

		internal void Show(RectTransform pageArea)
		{
			area = pageArea;
			scrolls.Clear();
			Redraw();
		}

		internal virtual void Refresh()
		{
			Redraw();
		}

		internal virtual bool Changed()
		{
			return false;
		}

		protected void Redraw()
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)area == (Object)null)
			{
				return;
			}
			foreach (KeyValuePair<string, ScrollRect> liveScroll in liveScrolls)
			{
				if ((Object)(object)liveScroll.Value != (Object)null)
				{
					scrolls[liveScroll.Key] = liveScroll.Value.verticalNormalizedPosition;
				}
			}
			liveScrolls.Clear();
			for (int num = ((Transform)area).childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)((Transform)area).GetChild(num)).gameObject);
			}
			try
			{
				Build(area);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"{Title} page: {arg}");
				Ui.Label((Transform)(object)area, "This page couldn't be shown (see the log).", 22f, Ui.Bad, (TextAlignmentOptions)4097);
			}
			Canvas.ForceUpdateCanvases();
			foreach (KeyValuePair<string, ScrollRect> liveScroll2 in liveScrolls)
			{
				if (scrolls.TryGetValue(liveScroll2.Key, out var value))
				{
					liveScroll2.Value.verticalNormalizedPosition = value;
				}
			}
		}

		protected abstract void Build(RectTransform area);

		protected RectTransform List(RectTransform parent, string key)
		{
			ScrollRect scroll;
			RectTransform result = Ui.Scroll(parent, out scroll);
			liveScrolls[key] = scroll;
			return result;
		}

		protected static (RectTransform left, RectTransform right) Split(RectTransform area, float leftShare, float top = 0f)
		{
			//IL_000c: 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_0028: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = Ui.Rect((Transform)(object)area, "Left");
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = new Vector2(leftShare, 1f);
			obj.offsetMin = Vector2.zero;
			obj.offsetMax = new Vector2(-10f, 0f - top);
			RectTransform val = Ui.Rect((Transform)(object)area, "Right");
			val.anchorMin = new Vector2(leftShare, 0f);
			val.anchorMax = Vector2.one;
			val.offsetMin = new Vector2(10f, 0f);
			val.offsetMax = new Vector2(0f, 0f - top);
			return (left: obj, right: val);
		}

		protected static HorizontalLayoutGroup Toolbar(RectTransform area, float height = 46f)
		{
			//IL_0017: 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_0027: 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_003c: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			HorizontalLayoutGroup obj = Ui.Row((Transform)(object)area, height, 8f, "Toolbar");
			RectTransform val = (RectTransform)((Component)obj).transform;
			val.anchorMin = new Vector2(0f, 1f);
			val.anchorMax = Vector2.one;
			val.pivot = new Vector2(0.5f, 1f);
			val.sizeDelta = new Vector2(0f, height * Mathf.Max(1f, Ui.Scale));
			return obj;
		}

		protected static float ToolbarSpace(float height = 46f)
		{
			return height * Mathf.Max(1f, Ui.Scale) + 12f;
		}

		protected static HorizontalLayoutGroup ListRow(Transform parent, Action onClick, bool selected, float height = 44f)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			Button obj = Ui.Button(parent, "", onClick, primary: false, enabled: true, 22f, height, -1f, framed: false, selected);
			Object.DestroyImmediate((Object)(object)((Component)((Component)obj).GetComponentInChildren<TextMeshProUGUI>()).gameObject);
			HorizontalLayoutGroup obj2 = ((Component)obj).gameObject.AddComponent<HorizontalLayoutGroup>();
			((LayoutGroup)obj2).padding = new RectOffset(10, 14, 0, 0);
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 12f;
			((LayoutGroup)obj2).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = true;
			Cell(((Component)obj2).transform, ">", 18f, Ui.Dim, (TextAlignmentOptions)4097);
			return obj2;
		}

		protected static TextMeshProUGUI Cell(Transform row, string text, float width = -1f, Color? color = null, TextAlignmentOptions align = (TextAlignmentOptions)4097, float size = 22f)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = Ui.Label(row, text, size, color, align);
			if (width < 0f)
			{
				Ui.Size(((Component)val).gameObject, -1f, -1f, 1f);
			}
			else
			{
				Ui.Size(((Component)val).gameObject, width);
			}
			return val;
		}

		protected static bool Confirming(ref string pending, string what)
		{
			if (!Plugin.BoundConfig.ConfirmPurchases.Value || pending == what)
			{
				pending = "";
				return true;
			}
			pending = what;
			return false;
		}

		protected static void Report(Ship.Result result)
		{
			CrackedScreen.Say(result.Message, result.Ok);
		}
	}
	internal sealed class MonitorPage : Page
	{
		internal override string Title => "MONITOR";

		internal override Key Key => (Key)32;

		protected override void Build(RectTransform area)
		{
			//IL_0090: 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_0195: Unknown result type (might be due to invalid IL or missing references)
			HorizontalLayoutGroup obj = Page.Toolbar(area);
			Ui.Size(((Component)Ui.Button(((Component)obj).transform, "< Previous", delegate
			{
				Ship.SwitchRadar(-1);
			}, primary: false, enabled: true, 18f, 42f)).gameObject, 170f);
			((TMP_Text)Page.Cell(((Component)obj).transform, (Ship.RadarTarget.Length > 0) ? Ship.RadarTarget : "No target", -1f, Ui.Accent, (TextAlignmentOptions)514, 28f)).fontStyle = (FontStyles)1;
			Ui.Size(((Component)Ui.Button(((Component)obj).transform, "Next >", delegate
			{
				Ship.SwitchRadar(1);
			}, primary: false, enabled: true, 18f, 42f)).gameObject, 170f);
			RectTransform rectTransform = ((Graphic)Ui.Box((Transform)(object)area, "Frame", Ui.Clear)).rectTransform;
			Ui.Frame(rectTransform, Ui.Line);
			Ui.Fill(rectTransform, 0f, Page.ToolbarSpace());
			ManualCameraRenderer radar = Ship.Radar;
			RenderTexture val = (((Object)(object)radar != (Object)null && (Object)(object)radar.cam != (Object)null) ? radar.cam.targetTexture : null);
			if ((Object)(object)val == (Object)null)
			{
				Ui.Fill(((TMP_Text)Ui.Label((Transform)(object)rectTransform, "The radar isn't running.", 22f, Ui.Dim, (TextAlignmentOptions)514)).rectTransform);
				return;
			}
			RawImage obj2 = ((Component)Ui.Rect((Transform)(object)rectTransform, "Radar")).gameObject.AddComponent<RawImage>();
			obj2.texture = (Texture)(object)val;
			((Graphic)obj2).raycastTarget = false;
			Ui.Fill(((Graphic)obj2).rectTransform, 8f, 8f, 8f, 8f);
			AspectRatioFitter obj3 = ((Component)obj2).gameObject.AddComponent<AspectRatioFitter>();
			obj3.aspectMode = (AspectMode)3;
			obj3.aspectRatio = (float)((Texture)val).width / (float)Mathf.Max(1, ((Texture)val).height);
		}
	}
	internal sealed class TransmitPage : Page
	{
		private string draft = "";

		internal static bool typing;

		internal override string Title => "TRANSMIT";

		internal override Key Key => (Key)38;

		internal override void Refresh()
		{
			if (!typing)
			{
				Redraw();
			}
		}

		protected override void Build(RectTransform area)
		{
			//IL_0042: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = Ui.Card((Transform)(object)area, "Transmit");
			Ui.Fill(val);
			TextMeshProUGUI obj = Ui.Label((Transform)(object)val, "SIGNAL TRANSLATOR", 28f, Ui.Accent, (TextAlignmentOptions)4097);
			((TMP_Text)obj).fontStyle = (FontStyles)1;
			Ui.Size(((Component)obj).gameObject, -1f, 44f);
			bool flag = (Object)(object)Ship.Translator != (Object)null;
			Ui.Size(((Component)Ui.Label((Transform)(object)val, flag ? $"Sends up to {10} characters to everyone's screen, once every {8f:0} seconds." : "The ship has no signal translator. Buy one in the store (Upgrades).", 22f, flag ? Ui.Dim : Ui.Warn, (TextAlignmentOptions)4097, wrap: true)).gameObject, -1f, 70f);
			HorizontalLayoutGroup val2 = Ui.Row((Transform)(object)val, 60f, 12f);
			TMP_InputField field = Input(((Component)val2).transform);
			Ui.Size(((Component)field).gameObject, -1f, -1f, 1f);
			Ui.Size(((Component)Ui.Button(((Component)val2).transform, "Send", delegate
			{
				Send(field);
			}, primary: true, flag, 22f, 56f)).gameObject, 180f);
			float transmitWait = Ship.TransmitWait;
			if (transmitWait > 0f)
			{
				Ui.Size(((Component)Ui.Label((Transform)(object)val, $"Ready again in {transmitWait:0} s.", 22f, Ui.Warn, (TextAlignmentOptions)4097)).gameObject, -1f, 40f);
			}
		}

		private void Send(TMP_InputField field)
		{
			Ship.Result result = Ship.Transmit(field.text);
			if (result.Ok)
			{
				draft = "";
			}
			Page.Report(result);
			Redraw();
		}

		private TMP_InputField Input(Transform parent)
		{
			//IL_0013: 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_0076: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			Image val = Ui.Box(parent, "Input", Ui.Clear);
			Ui.Frame(((Graphic)val).rectTransform, Ui.Line);
			RectTransform val2 = Ui.Rect(((Component)val).transform, "Viewport");
			Ui.Fill(val2, 14f, 6f, 14f, 6f);
			((Component)val2).gameObject.AddComponent<RectMask2D>();
			TextMeshProUGUI val3 = Ui.Label((Transform)(object)val2, "", 28f, Ui.Text, (TextAlignmentOptions)4097);
			Ui.Fill(((TMP_Text)val3).rectTransform);
			TextMeshProUGUI val4 = Ui.Label((Transform)(object)val2, "Message…", 28f, Ui.Dim, (TextAlignmentOptions)4097);
			Ui.Fill(((TMP_Text)val4).rectTransform);
			TMP_InputField field = ((Component)val).gameObject.AddComponent<TMP_InputField>();
			field.textViewport = val2;
			field.textComponent = (TMP_Text)(object)val3;
			field.placeholder = (Graphic)(object)val4;
			field.characterLimit = 10;
			field.lineType = (LineType)0;
			field.customCaretColor = true;
			field.caretColor = Ui.Accent;
			field.caretWidth = 12;
			field.caretBlinkRate = 1.9f;
			field.selectionColor = new Color(Ui.Accent.r, Ui.Accent.g, Ui.Accent.b, 0.35f);
			field.text = draft;
			((UnityEvent<string>)(object)field.onValueChanged).AddListener((UnityAction<string>)delegate(string value)
			{
				draft = value;
			});
			((UnityEvent<string>)(object)field.onSelect).AddListener((UnityAction<string>)delegate
			{
				SetTyping(typing: true);
			});
			((UnityEvent<string>)(object)field.onDeselect).AddListener((UnityAction<string>)delegate
			{
				SetTyping(typing: false);
			});
			((UnityEvent<string>)(object)field.onSubmit).AddListener((UnityAction<string>)delegate
			{
				Send(field);
			});
			return field;
		}

		internal static void SetTyping(bool typing)
		{
			TransmitPage.typing = typing;
			PlayerControllerB local = Ship.Local;
			if ((Object)(object)local != (Object)null)
			{
				local.isTypingChat = typing;
			}
		}
	}
	internal sealed class StatusPage : Page
	{
		internal override string Title => "STATUS";

		internal override Key Key => (Key)23;

		protected override void Build(RectTransform area)
		{
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			(RectTransform left, RectTransform right) tuple = Page.Split(area, 0.55f);
			RectTransform item = tuple.left;
			RectTransform item2 = tuple.right;
			RectTransform val = Ui.Card((Transform)(object)item, "Info", "Ship status");
			Ui.Fill(val);
			TimeOfDay instance = TimeOfDay.Instance;
			StartOfRound instance2 = StartOfRound.Instance;
			Line((Transform)(object)val, "Credits", Ui.Money(Ship.Credits));
			if ((Object)(object)instance != (Object)null)
			{
				Line((Transform)(object)val, "Quota", Ui.Money(instance.quotaFulfilled) + " of " + Ui.Money(instance.profitQuota));
				Progress((Transform)(object)val, (instance.profitQuota > 0) ? ((float)instance.quotaFulfilled / (float)instance.profitQuota) : 0f);
			}
			Line((Transform)(object)val, "Deadline", Ship.Deadline);
			if ((Object)(object)instance2?.currentLevel != (Object)null)
			{
				Line((Transform)(object)val, "Moon", instance2.currentLevel.PlanetName);
				Line((Transform)(object)val, "Weather", Ship.Weather(instance2.currentLevel));
			}
			Line((Transform)(object)val, "Ship", Ship.ShipState);
			Ui.Divider((Transform)(object)val);
			Line((Transform)(object)val, "Dropship", Dropship.Summary);
			int[] array = ((Dropship.Delivering.Length != 0) ? Dropship.Delivering : Dropship.Waiting);
			if (array.Length != 0)
			{
				Ui.Size(((Component)Ui.Label((Transform)(object)val, Dropship.Describe(array), 18f, Ui.Dim, (TextAlignmentOptions)257, wrap: true)).gameObject, -1f, 60f);
			}
			RectTransform obj = Ui.Card((Transform)(object)item2, "Controls");
			Ui.Fill(obj);
			TextMeshProUGUI obj2 = Ui.Label((Transform)(object)obj, "SHIP CONTROLS", 28f, Ui.Accent, (TextAlignmentOptions)4097);
			((TMP_Text)obj2).fontStyle = (FontStyles)1;
			Ui.Size(((Component)obj2).gameObject, -1f, 44f);
			Ui.Button((Transform)(object)obj, Ship.LightsOn ? "Lights off" : "Lights on", delegate
			{
				Ship.ToggleLights();
				Redraw();
			}, primary: false, enabled: true, 22f, 54f);
			ShipTeleporter teleporter = Ship.Teleporter(inverse: false);
			Ui.Button((Transform)(object)obj, ((Object)(object)teleporter != (Object)null) ? ("Teleport " + Ship.RadarTarget + " back") : "Teleporter (not bought)", delegate
			{
				ShipTeleporter obj3 = teleporter;
				if (obj3 != null)
				{
					obj3.PressTeleportButtonOnLocalClient();
				}
			}, primary: false, (Object)(object)teleporter != (Object)null, 22f, 54f);
			ShipTeleporter inverse = Ship.Teleporter(inverse: true);
			Ui.Button(enabled: (Object)(object)inverse != (Object)null && (Object)(object)instance2 != (Object)null && !instance2.inShipPhase, parent: (Transform)(object)obj, text: ((Object)(object)inverse == (Object)null) ? "Inverse teleporter (not bought)" : "Inverse teleport", onClick: delegate
			{
				ShipTeleporter obj3 = inverse;
				if (obj3 != null)
				{
					obj3.PressTeleportButtonOnLocalClient();
				}
			}, primary: false, size: 22f, height: 54f);
			Ui.Button((Transform)(object)obj, "Text terminal", CrackedScreen.OpenTextTerminal, primary: false, enabled: true, 22f, 54f);
		}

		private static void Line(Transform card, string label, string value)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			HorizontalLayoutGroup obj = Ui.Row(card, 36f);
			Page.Cell(((Component)obj).transform, label, 160f, Ui.Dim, (TextAlignmentOptions)4097);
			Page.Cell(((Component)obj).transform, value, -1f, null, (TextAlignmentOptions)4097);
		}

		private static void Progress(Transform card, float share)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_005a: 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_008b: 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)
			//IL_0091: 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)
			Image obj = Ui.Box(card, "Track", Ui.LineDim);
			Ui.Size(((Component)obj).gameObject, -1f, 12f);
			Image val = Ui.Box(((Component)obj).transform, "Fill", (share >= 1f) ? Ui.Accent : Ui.Line);
			((Graphic)val).rectTransform.anchorMin = Vector2.zero;
			((Graphic)val).rectTransform.anchorMax = new Vector2(Mathf.Clamp01(share), 1f);
			RectTransform rectTransform = ((Graphic)val).rectTransform;
			Vector2 offsetMin = (((Graphic)val).rectTransform.offsetMax = Vector2.zero);
			rectTransform.offsetMin = offsetMin;
		}
	}
	internal sealed class StorePage : Page
	{
		private enum Tab
		{
			Items,
			Upgrades,
			Decor,
			Suits,
			Vehicles
		}

		private const int SavedSlots = 3;

		private Tab tab;

		private string confirm = "";

		private string receipt = "";

		private readonly List<(int item, int count)> cart = new List<(int, int)>();

		internal override string Title => "STORE";

		internal override Key Key => (Key)33;

		protected override void Build(RectTransform area)
		{
			HorizontalLayoutGroup val = Page.Toolbar(area);
			foreach (Tab value in Enum.GetValues(typeof(Tab)))
			{
				Tab current = value;
				Ui.Size(((Component)Ui.Button(((Component)val).transform, value.ToString(), delegate
				{
					tab = current;
					confirm = "";
					Redraw();
				}, primary: false, enabled: true, 18f, 42f, -1f, framed: true, tab == value)).gameObject, 150f);
			}
			var (left, right) = Page.Split(area, 0.6f, Page.ToolbarSpace());
			if (tab == Tab.Items)
			{
				Items(left);
			}
			else
			{
				Unlocks(left);
			}
			Cart(right);
		}

		private void Items(RectTransform left)
		{
			//IL_00c7: 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_0146: Unknown result type (might be due to invalid IL or missing references)
			RectTransform parent = List(left, "items");
			Item[] items = Ship.Items;
			for (int i = 0; i < items.Length; i++)
			{
				int index = i;
				int num = Ship.ItemPrice(i);
				int num2 = Ship.ItemSale(i);
				HorizontalLayoutGroup obj = Page.ListRow((Transform)(object)parent, delegate
				{
					Add(index, 1);
				}, selected: false);
				Page.Cell(((Component)obj).transform, items[i].itemName + ((num2 > 0) ? $"  <color=#FFBD4D>[{num2}% OFF]</color>" : ""), -1f, null, (TextAlignmentOptions)4097);
				Page.Cell(((Component)obj).transform, Ui.Money(num), 110f, (num > Ship.Credits) ? Ui.Bad : Ui.Text, (TextAlignmentOptions)4100);
				int num3 = cart.Where(((int item, int count) c) => c.item == index).Sum(((int item, int count) c) => c.count);
				Page.Cell(((Component)obj).transform, (num3 > 0) ? $"x{num3}" : "", 56f, Ui.Accent, (TextAlignmentOptions)514);
				Ui.Size(((Component)Ui.Button(((Component)obj).transform, "+5", delegate
				{
					Add(index, 5);
				}, primary: false, enabled: true, 18f, 38f)).gameObject, 64f);
			}
		}

		private void Unlocks(RectTransform left)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: 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)
			RectTransform parent = List(left, "unlocks-" + tab);
			Ship.Kind kind = tab switch
			{
				Tab.Upgrades => Ship.Kind.Upgrade, 
				Tab.Decor => Ship.Kind.Decor, 
				Tab.Suits => Ship.Kind.Suit, 
				_ => Ship.Kind.Vehicle, 
			};
			List<Ship.Unlock> list = (from unlock in Ship.Unlocks()
				where unlock.Kind == kind
				select unlock).ToList();
			if (list.Count == 0)
			{
				Ui.Label((Transform)(object)parent, (tab == Tab.Decor) ? "No decorations this quota." : "Nothing here right now.", 22f, Ui.Dim, (TextAlignmentOptions)4097);
			}
			foreach (Ship.Unlock item in list)
			{
				Ship.Unlock u = item;
				HorizontalLayoutGroup val = Ui.Row((Transform)(object)parent, 50f, 12f);
				TextMeshProUGUI val2 = Page.Cell(((Component)val).transform, u.Name, -1f, null, (TextAlignmentOptions)4097);
				Page.Cell(((Component)val).transform, Ui.Money(u.Cost), 110f, (u.Cost > Ship.Credits && !u.Owned) ? Ui.Bad : Ui.Text, (TextAlignmentOptions)4100);
				if (u.Owned)
				{
					Page.Cell(((Component)val).transform, u.Stored ? "In storage" : "Owned", 170f, Ui.Dim, (TextAlignmentOptions)514);
					continue;
				}
				string key = "unlock:" + u.Name;
				bool flag = confirm == key;
				Transform transform = ((Component)val).transform;
				string text = (flag ? "Confirm" : "Buy");
				Action onClick = delegate
				{
					if (!Page.Confirming(ref confirm, key))
					{
						Redraw();
					}
					else
					{
						Page.Report(Ship.BuyUnlock(u));
						Redraw();
					}
				};
				bool selected = flag;
				Ui.Size(((Component)Ui.Button(transform, text, onClick, primary: false, u.Cost <= Ship.Credits, 18f, 40f, -1f, framed: true, selected)).gameObject, 170f);
				((Graphic)val2).color = Ui.Text;
			}
		}

		private void Cart(RectTransform right)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0535: Unknown result type (might be due to invalid IL or missing references)
			//IL_0577: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = Ui.Card((Transform)(object)right, "Cart");
			Ui.Fill(val);
			HorizontalLayoutGroup obj = Ui.Row((Transform)(object)val, 40f);
			((TMP_Text)Page.Cell(((Component)obj).transform, "CART", -1f, Ui.Accent, (TextAlignmentOptions)4097, 28f)).fontStyle = (FontStyles)1;
			Ui.Size(((Component)Ui.Button(((Component)obj).transform, "Clear", delegate
			{
				cart.Clear();
				Redraw();
			}, primary: false, cart.Count > 0, 18f, 36f)).gameObject, 90f);
			RectTransform val2 = Ui.Rect((Transform)(object)val, "Lines");
			Ui.Size(((Component)val2).gameObject, -1f, -1f, -1f, 1f);
			RectTransform parent = List(val2, "cart");
			Item[] items = Ship.Items;
			if (cart.Count == 0)
			{
				Ui.Label((Transform)(object)parent, "Click items to add them.", 18f, Ui.Dim, (TextAlignmentOptions)4097);
			}
			foreach (var item3 in cart.ToList())
			{
				int item = item3.item;
				int item2 = item3.count;
				int index = item;
				HorizontalLayoutGroup obj2 = Ui.Row((Transform)(object)parent, 40f, 8f);
				Page.Cell(((Component)obj2).transform, (index < items.Length) ? items[index].itemName : "?", -1f, null, (TextAlignmentOptions)4097, 18f);
				Ui.Size(((Component)Ui.Button(((Component)obj2).transform, "-", delegate
				{
					Add(index, -1);
				}, primary: false, enabled: true, 18f, 34f)).gameObject, 40f);
				Page.Cell(((Component)obj2).transform, item2.ToString(), 36f, Ui.Text, (TextAlignmentOptions)514, 18f);
				Ui.Size(((Component)Ui.Button(((Component)obj2).transform, "+", delegate
				{
					Add(index, 1);
				}, primary: false, enabled: true, 18f, 34f)).gameObject, 40f);
				Page.Cell(((Component)obj2).transform, Ui.Money(Ship.ItemPrice(index) * item2), 90f, Ui.Text, (TextAlignmentOptions)4100, 18f);
			}
			int num = cart.Sum(((int item, int count) c) => Ship.ItemPrice(c.item) * c.count);
			int num2 = cart.Sum(((int item, int count) c) => c.count);
			int num3 = 12 - Ship.InDropship;
			Ui.Divider((Transform)(object)val);
			Summary((Transform)(object)val, "Total", Ui.Money(num), (num > Ship.Credits) ? Ui.Bad : Ui.Text);
			Summary((Transform)(object)val, "Credits after", Ui.Money(Mathf.Max(0, Ship.Credits - num)), Ui.Dim);
			Summary((Transform)(object)val, "Dropship space", $"{num2} items, {num3} free", (num2 > num3) ? Ui.Warn : Ui.Dim);
			if (Dropship.Waiting.Length != 0 || Dropship.Delivering.Length != 0)
			{
				string text = Dropship.Describe((Dropship.Delivering.Length != 0) ? Dropship.Delivering : Dropship.Waiting);
				Ui.Size(((Component)Ui.Label((Transform)(object)val, Dropship.Summary + ": " + text, 18f, Ui.Dim, (TextAlignmentOptions)257, wrap: true)).gameObject, -1f, 46f);
			}
			if (receipt.Length > 0)
			{
				Ui.Size(((Component)Ui.Label((Transform)(object)val, receipt, 18f, Ui.Accent, (TextAlignmentOptions)257, wrap: true)).gameObject, -1f, 52f);
			}
			bool flag = confirm == "order";
			Ui.Button((Transform)(object)val, flag ? ("Confirm order (" + Ui.Money(num) + ")") : "Order", delegate
			{
				if (!Page.Confirming(ref confirm, "order"))
				{
					Redraw();
				}
				else
				{
					Order();
				}
			}, primary: true, num2 > 0 && !Ship.Busy, 22f, 54f);
			Dictionary<int, List<(string, int)>> dictionary = SavedCarts();
			HorizontalLayoutGroup val3 = Ui.Row((Transform)(object)val, 36f, 6f);
			Page.Cell(((Component)val3).transform, "Load", 80f, Ui.Dim, (TextAlignmentOptions)4097, 18f);
			HorizontalLayoutGroup val4 = Ui.Row((Transform)(object)val, 36f, 6f);
			Page.Cell(((Component)val4).transform, "Save to", 80f, Ui.Dim, (TextAlignmentOptions)4097, 18f);
			for (int num4 = 1; num4 <= 3; num4++)
			{
				int s = num4;
				Ui.Size(((Component)Ui.Button(((Component)val3).transform, $"Cart {s}", delegate
				{
					Load(s);
				}, primary: false, dictionary.ContainsKey(s), 18f, 34f)).gameObject, -1f, -1f, 1f);
				Ui.Size(((Component)Ui.Button(((Component)val4).transform, $"Cart {s}", delegate
				{
					Save(s);
				}, primary: false, cart.Count > 0, 18f, 34f)).gameObject, -1f, -1f, 1f);
			}
		}

		private static void Summary(Transform card, string label, string value, Color color)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			HorizontalLayoutGroup obj = Ui.Row(card, 30f);
			Page.Cell(((Component)obj).transform, label, -1f, Ui.Dim, (TextAlignmentOptions)4097, 18f);
			Page.Cell(((Component)obj).transform, value, 200f, color, (TextAlignmentOptions)4100);
		}

		internal void FillForTest()
		{
			cart.Clear();
			for (int i = 0; i < Mathf.Min(4, Ship.Items.Length); i++)
			{
				cart.Add((i, i + 1));
			}
			receipt = "";
		}

		private void Add(int item, int by)
		{
			int num = cart.FindIndex(((int item, int count) c) => c.item == item);
			int num2 = Mathf.Clamp(((num >= 0) ? cart[num].count : 0) + by, 0, 12);
			if (num >= 0)
			{
				if (num2 == 0)
				{
					cart.RemoveAt(num);
				}
				else
				{
					cart[num] = (item, num2);
				}
			}
			else if (num2 > 0)
			{
				cart.Add((item, num2));
			}
			confirm = "";
			receipt = "";
			Redraw();
		}

		private void Order()
		{
			Ship.Order order = Ship.OrderCart(cart);
			Item[] items = Ship.Items;
			cart.Clear();
			cart.AddRange(order.Left);
			if (order.Placed.Count == 0)
			{
				receipt = "";
				CrackedScreen.Say(order.Problem, ok: false);
			}
			else
			{
				receipt = "Ordered " + Names(order.Placed) + " for " + Ui.Money(order.Cost) + "." + ((order.Left.Count > 0) ? (" Still in the cart: " + Names(order.Left) + ".") : "");
				CrackedScreen.Say((order.Left.Count > 0) ? "Part of the order placed (dropship full or not enough credits)." : "Ordered. It all comes on one dropship.", order.Left.Count == 0);
			}
			Redraw();
			string Names(List<(int item, int count)> lines)
			{
				return string.Join(", ", lines.Select(((int item, int count) l) => ((l.item < items.Length) ? items[l.item].itemName : "?") + ((l.count > 1) ? $" x{l.count}" : "")));
			}
		}

		private static Dictionary<int, List<(string name, int count)>> SavedCarts()
		{
			Dictionary<int, List<(string, int)>> dictionary = new Dictionary<int, List<(string, int)>>();
			string[] array = Plugin.BoundConfig.SavedCarts.Value.Split('|');
			foreach (string text in array)
			{
				int num = text.IndexOf('=');
				if (num <= 0 || !int.TryParse(text.Substring(0, num), out var result))
				{
					continue;
				}
				List<(string, int)> list = new List<(string, int)>();
				string[] array2 = text.Substring(num + 1).Split(',');
				foreach (string text2 in array2)
				{
					int num2 = text2.LastIndexOf(':');
					if (num2 > 0 && int.TryParse(text2.Substring(num2 + 1), out var result2))
					{
						list.Add((text2.Substring(0, num2), result2));
					}
				}
				if (list.Count > 0)
				{
					dictionary[result] = list;
				}
			}
			return dictionary;
		}

		private void Save(int slot)
		{
			Dictionary<int, List<(string, int)>> dictionary = SavedCarts();
			Item[] items = Ship.Items;
			dictionary[slot] = (from c in cart
				where c.item < items.Length
				select (items[c.item].itemName.Replace("|", "").Replace(",", "").Replace(":", ""), count: c.count)).ToList();
			Plugin.BoundConfig.SavedCarts.Value = string.Join("|", from p in dictionary
				orderby p.Key
				select $"{p.Key}=" + string.Join(",", p.Value.Select(((string name, int count) l) => $"{l.name}:{l.count}")));
			CrackedScreen.Say($"Cart saved to slot {slot}.");
			Redraw();
		}

		private void Load(int slot)
		{
			if (!SavedCarts().TryGetValue(slot, out List<(string, int)> value))
			{
				return;
			}
			Item[] items = Ship.Items;
			cart.Clear();
			int num = 0;
			foreach (var item2 in value)
			{
				string name = item2.Item1;
				int item = item2.Item2;
				int num2 = Array.FindIndex(items, (Item i) => i.itemName.Replace("|", "").Replace(",", "").Replace(":", "") == name);
				if (num2 >= 0)
				{
					cart.Add((num2, item));
				}
				else
				{
					num++;
				}
			}
			confirm = "";
			receipt = "";
			CrackedScreen.Say((num > 0) ? $"Loaded slot {slot}; {num} item(s) aren't sold any more." : $"Loaded slot {slot}.", num == 0);
			Redraw();
		}
	}
	[BepInPlugin("CrackedTerminal", "CrackedTerminal", "1.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		internal static PluginConfig BoundConfig { get; private set; }

		private void Awake()
		{
			//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)
			//IL_0035: 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_005e: 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_006c: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			BoundConfig = new PluginConfig(((BaseUnityPlugin)this).Config);
			Harmony val = new Harmony("CrackedTerminal");
			val.PatchAll(typeof(TerminalHook));
			val.PatchAll(typeof(Live));
			val.PatchAll(typeof(Lobby));
			GameObject val2 = new GameObject("CrackedTerminal")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)val2);
			CrackedScreen.Create(val2);
			val2.AddComponent<Dropship>();
			Logger.LogInfo((object)"Plugin CrackedTerminal is loaded!");
		}
	}
	[HarmonyPatch]
	internal static class Lobby
	{
		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPostfix]
		private static void Begin()
		{
			Dropship.Register();
		}
	}
	internal static class Ship
	{
		internal readonly struct Result
		{
			internal readonly bool Ok;

			internal readonly string Message;

			internal Result(bool ok, string message)
			{
				Ok = ok;
				Message = message;
			}
		}

		internal sealed class Moon
		{
			internal SelectableLevel Level;

			internal TerminalNode Route;

			internal int Cost;

			internal bool Hidden;

			internal bool Company;

			internal string Name => Level.PlanetName;

			internal bool Current
			{
				get
				{
					if ((Object)(object)StartOfRound.Instance != (Object)null)
					{
						return (Object)(object)StartOfRound.Instance.currentLevel == (Object)(object)Level;
					}
					return false;
				}
			}
		}

		internal enum Kind
		{
			Upgrade,
			Decor,
			Suit,
			Vehicle
		}

		internal sealed class Unlock
		{
			internal Kind Kind;

			internal string Name = "";

			internal int Cost;

			internal int Id = -1;

			internal bool Owned;

			internal bool Stored;

			internal TerminalNode Buy;
		}

		internal sealed class Order
		{
			internal readonly List<(int item, int count)> Placed = new List<(int, int)>();

			internal readonly List<(int item, int count)> Left = new List<(int, int)>();

			internal int Cost;

			internal string Problem = "";
		}

		internal sealed class Monster
		{
			internal string Name = "";

			internal int Count;

			internal TerminalNode? File;
		}

		internal const int DropshipCapacity = 12;

		internal const int TransmitLength = 10;

		internal const float TransmitCooldown = 8f;

		private static Terminal? terminal;

		private static readonly Action<Terminal, TerminalNode> LoadNewNodeIfAffordable = AccessTools.MethodDelegate<Action<Terminal, TerminalNode>>(AccessTools.Method(typeof(Terminal), "LoadNewNodeIfAffordable", (Type[])null, (Type[])null), (object)null, true);

		private static readonly FieldRef<Terminal, InteractTrigger> TriggerOf = AccessTools.FieldRefAccess<Terminal, InteractTrigger>("terminalTrigger");

		private static readonly Action<Terminal, int[], int> SyncBoughtItemsWithServer = AccessTools.MethodDelegate<Action<Terminal, int[], int>>(AccessTools.Method(typeof(Terminal), "SyncBoughtItemsWithServer", (Type[])null, (Type[])null), (object)null, true);

		internal static Terminal? Terminal
		{
			get
			{
				if ((Object)(object)terminal == (Object)null)
				{
					terminal = Object.FindObjectOfType<Terminal>();
				}
				return terminal;
			}
		}

		internal static InteractTrigger? Trigger
		{
			get
			{
				if (!((Object)(object)Terminal != (Object)null))
				{
					return null;
				}
				return TriggerOf.Invoke(Terminal);
			}
		}

		internal static PlayerControllerB? Local
		{
			get
			{
				if (!((Object)(object)GameNetworkManager.Instance != (Object)null))
				{
					return null;
				}
				return GameNetworkManager.Instance.localPlayerController;
			}
		}

		private static bool IsHost
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton != (Object)null)
				{
					return NetworkManager.Singleton.IsServer;
				}
				return false;
			}
		}

		internal static int Credits
		{
			get
			{
				if (!((Object)(object)Terminal != (Object)null))
				{
					return 0;
				}
				return Terminal.groupCredits;
			}
		}

		internal static bool Busy
		{
			get
			{
				if ((Object)(object)Terminal != (Object)null)
				{
					return Terminal.useCreditsCooldown;
				}
				return false;
			}
		}

		internal static int InDropship
		{
			get
			{
				if (!((Object)(object)Terminal != (Object)null))
				{
					return 0;
				}
				return Terminal.numberOfItemsInDropship;
			}
		}

		internal static string ShipState
		{
			get
			{
				StartOfRound instance = StartOfRound.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return "";
				}
				if (instance.travellingToNewLevel)
				{
					return "Travelling";
				}
				if (instance.shipIsLeaving)
				{
					return "Taking off";
				}
				if (instance.inShipPhase)
				{
					return "In orbit";
				}
				if (!instance.shipHasLanded)
				{
					return "Landing";
				}
				return "Landed";
			}
		}

		internal static string Deadline
		{
			get
			{
				StartOfRound instance = StartOfRound.Instance;
				string text = (((Object)(object)instance != (Object)null && (Object)(object)instance.deadlineMonitorText != (Object)null) ? ((TMP_Text)instance.deadlineMonitorText).text.Replace("\n", " ").Trim() : "");
				if (text.Length == 0)
				{
					return "";
				}
				if (text.IndexOf("NOW", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return "Now";
				}
				Match match = Regex.Match(text, "\\d+");
				if (!match.Success)
				{
					return text;
				}
				bool flag = text.IndexOf("Job", StringComparison.OrdinalIgnoreCase) >= 0;
				int num = int.Parse(match.Value);
				return string.Format("{0} {1}{2}", num, flag ? "Job" : "Day", (num == 1) ? "" : "s");
			}
		}

		internal static Item[] Items => Terminal?.buyableItemsList ?? Array.Empty<Item>();

		internal static int CreatureCount
		{
			get
			{
				if (!((Object)(object)Terminal != (Object)null))
				{
					return 0;
				}
				return Terminal.enemyFiles.Count((TerminalNode n) => (Object)(object)n != (Object)null);
			}
		}

		internal static string MonstersSignature => string.Join("|", from m in InsideMonsters()
			select $"{m.Name}:{m.Count}:{(Object)(object)m.File != (Object)null}");

		internal static bool OnAMoon
		{
			get
			{
				if ((Object)(object)StartOfRound.Instance != (Object)null)
				{
					return !StartOfRound.Instance.inShipPhase;
				}
				return false;
			}
		}

		internal static bool TextTerminalBusy
		{
			get
			{
				InteractTrigger trigger = Trigger;
				PlayerControllerB local = Local;
				if ((Object)(object)trigger != (Object)null && trigger.isPlayingSpecialAnimation)
				{
					if (!((Object)(object)local == (Object)null))
					{
						return !local.inTerminalMenu;
					}
					return true;
				}
				return false;
			}
		}

		internal static ManualCameraRenderer? Radar
		{
			get
			{
				if (!((Object)(object)StartOfRound.Instance != (Object)null))
				{
					return null;
				}
				return StartOfRound.Instance.mapScreen;
			}
		}

		internal static string RadarTarget
		{
			get
			{
				ManualCameraRenderer radar = Radar;
				if ((Object)(object)radar == (Object)null || radar.radarTargets.Count == 0)
				{
					return "";
				}
				int index = Mathf.Clamp(radar.targetTransformIndex, 0, radar.radarTargets.Count - 1);
				return radar.radarTargets[index]?.name ?? "";
			}
		}

		internal static SignalTranslator? Translator => Object.FindObjectOfType<SignalTranslator>();

		internal static float TransmitWait
		{
			get
			{
				SignalTranslator translator = Translator;
				if (!((Object)(object)translator == (Object)null))
				{
					return Mathf.Max(0f, 8f - (Time.realtimeSinceStartup - translator.timeLastUsingSignalTranslator));
				}
				return 0f;
			}
		}

		internal static bool LightsOn
		{
			get
			{
				if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.shipRoomLights != (Object)null)
				{
					return StartOfRound.Instance.shipRoomLights.areLightsOn;
				}
				return false;
			}
		}

		internal static string Weather(SelectableLevel level)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)level.currentWeather != -1)
			{
				return ((object)Unsafe.As<LevelWeatherType, LevelWeatherType>(ref level.currentWeather)/*cast due to .constrained prefix*/).ToString();
			}
			return "Clear";
		}

		private static string NodeText(TerminalNode? node)
		{
			if ((Object)(object)node == (Object)null)
			{
				return "";
			}
			string text = node.displayText.Trim();
			int num = text.IndexOf("\n\n", StringComparison.Ordinal);
			return ((num > 0) ? text.Substring(0, num) : text).Replace("\n", " ").Trim();
		}

		private static Result BuyNode(TerminalNode node, string done)
		{
			Terminal val = Terminal;
			if ((Object)(object)val == (Object)null)
			{
				return new Result(ok: false, "No terminal on this ship.");
			}
			val.playerDefinedAmount = 1;
			LoadNewNodeIfAffordable(val, node);
			bool num = (Object)(object)val.currentNode == (Object)(object)node;
			if (num)
			{
				Sounds.Bought();
			}
			return new Result(num, num ? done : NodeText(val.currentNode));
		}

		private static TerminalNode? Confirmed(TerminalNode? node)
		{
			if (node?.terminalOptions == null)
			{
				return null;
			}
			CompatibleNoun[] terminalOptions = node.terminalOptions;
			foreach (CompatibleNoun val in terminalOptions)
			{
				if ((Object)(object)val?.noun != (Object)null && val.noun.word == "confirm")
				{
					return val.result;
				}
			}
			return null;
		}

		private static TerminalKeyword? Verb(string word)
		{
			return Terminal?.terminalNodes?.allKeywords?.FirstOrDefault((Func<TerminalKeyword, bool>)((TerminalKeyword k) => (Object)(object)k != (Object)null && k.word == word));
		}

		internal static List<Moon> Moons()
		{
			List<Moon> list = new List<Moon>();
			StartOfRound instance = StartOfRound.Instance;
			Terminal t = Terminal;
			TerminalKeyword val = Verb("route");
			if ((Object)(object)instance == (Object)null || (Object)(object)t == (Object)null || val?.compatibleNouns == null)
			{
				return list;
			}
			HashSet<int> hashSet = new HashSet<int>();
			CompatibleNoun[] compatibleNouns = val.compatibleNouns;
			for (int i = 0; i < compatibleNouns.Length; i++)
			{
				TerminalNode val2 = Confirmed(compatibleNouns[i]?.result);
				if (!((Object)(object)val2 == (Object)null) && val2.buyRerouteToMoon >= 0 && val2.buyRerouteToMoon < instance.levels.Length && hashSet.Add(val2.buyRerouteToMoon))
				{
					SelectableLevel val3 = instance.levels[val2.buyRerouteToMoon];
					list.Add(new Moon
					{
						Level = val3,
						Route = val2,
						Cost = val2.itemCost,
						Hidden = (t.moonsCatalogueList == null || !t.moonsCatalogueList.Contains(val3)),
						Company = !val3.planetHasTime
					});
				}
			}
			return list.OrderBy((Moon m) => m.Company ? (-1) : 0).ThenBy(Order).ThenBy((Moon m) => m.Name)
				.ToList();
			int Order(Moon m)
			{
				if (t.moonsCatalogueList != null)
				{
					int num = Array.IndexOf(t.moonsCatalogueList, m.Level);
					if (num < 0)
					{
						return 999;
					}
					return num;
				}
				return 999;
			}
		}

		internal static Result Route(Moon moon)
		{
			return BuyNode(moon.Route, "Routing to " + moon.Name + ".");
		}

		internal static int ItemPrice(int index)
		{
			Terminal val = Terminal;
			if ((Object)(object)val == (Object)null || index < 0 || index >= val.buyableItemsList.Length)
			{
				return 0;
			}
			int num = ((val.itemSalesPercentages != null && index < val.itemSalesPercentages.Length) ? val.itemSalesPercentages[index] : 100);
			return (int)((float)val.buyableItemsList[index].creditsWorth * ((float)num / 100f));
		}

		internal static int ItemSale(int index)
		{
			Terminal val = Terminal;
			if (val?.itemSalesPercentages == null || index < 0 || index >= val.itemSalesPercentages.Length)
			{
				return 0;
			}
			return 100 - val.itemSalesPercentages[index];
		}

		internal static List<Unlock> Unlocks()
		{
			List<Unlock> list = new List<Unlock>();
			StartOfRound instance = StartOfRound.Instance;
			Terminal val = Terminal;
			if ((Object)(object)instance == (Object)null || (Object)(object)val == (Object)null)
			{
				return list;
			}
			List<UnlockableItem> unlockables = instance.unlockablesList.unlockables;
			for (int i = 0; i < unlockables.Count; i++)
			{
				UnlockableItem val2 = unlockables[i];
				if (val2 == null)
				{
					continue;
				}
				TerminalNode val3 = Confirmed(val2.shopSelectionNode);
				if (!((Object)(object)val3 == (Object)null))
				{
					bool flag = val2.unlockableType == 0;
					if (val2.alwaysInStock || val.ShipDecorSelection.Contains(val2.shopSelectionNode))
					{
						list.Add(new Unlock
						{
							Kind = (flag ? Kind.Suit : ((!val2.alwaysInStock) ? Kind.Decor : Kind.Upgrade)),
							Name = val2.unlockableName,
							Cost = val3.itemCost,
							Id = i,
							Owned = (val2.hasBeenUnlockedByPlayer || val2.alreadyUnlocked),
							Stored = val2.inStorage,
							Buy = val3
						});
					}
				}
			}
			TerminalKeyword val4 = Verb("buy");
			if (val4?.compatibleNouns != null && val.buyableVehicles != null)
			{
				CompatibleNoun[] compatibleNouns = val4.compatibleNouns;
				for (int j = 0; j < compatibleNouns.Length; j++)
				{
					TerminalNode val5 = Confirmed(compatibleNouns[j]?.result);
					if (!((Object)(object)val5 == (Object)null) && val5.buyVehicleIndex >= 0 && val5.buyVehicleIndex < val.buyableVehicles.Length)
					{
						int num = ((val.itemSalesPercentages != null && val.buyableItemsList.Length + val5.buyVehicleIndex < val.itemSalesPercentages.Length) ? val.itemSalesPercentages[val.buyableItemsList.Length + val5.buyVehicleIndex] : 100);
						list.Add(new Unlock
						{
							Kind = Kind.Vehicle,
							Name = val.buyableVehicles[val5.buyVehicleIndex].vehicleDisplayName,
							Cost = (int)((float)val5.itemCost * ((float)num / 100f)),
							Buy = val5
						});
					}
				}
			}
			return list;
		}

		internal static Result BuyUnlock(Unlock unlock)
		{
			return BuyNode(unlock.Buy, unlock.Name + " bought.");
		}

		internal static Order OrderCart(IList<(int item, int count)> cart)
		{
			Order order = new Order();
			Terminal val = Terminal;
			if ((Object)(object)val == (Object)null)
			{
				order.Problem = "No terminal on this ship.";
				return order;
			}
			if (val.useCreditsCooldown)
			{
				order.Problem = "Waiting for the host to confirm the last purchase. Try again in a moment.";
			}
			else if (val.vehicleInDropship)
			{
				order.Problem = "A vehicle is on the dropship; items go on its next trip.";
			}
			int num = 12 - val.numberOfItemsInDropship;
			int groupCredits = val.groupCredits;
			List<int> list = new List<int>();
			foreach (var item3 in cart)
			{
				int item = item3.item;
				int item2 = item3.count;
				int num2 = ItemPrice(item);
				int num3 = ((order.Problem.Length <= 0) ? Mathf.Min(new int[3]
				{
					item2,
					num - list.Count,
					(num2 > 0) ? ((groupCredits - order.Cost) / num2) : item2
				}) : 0);
				num3 = Mathf.Max(0, num3);
				if (num3 > 0)
				{
					order.Placed.Add((item, num3));
					order.Cost += num3 * num2;
					for (int i = 0; i < num3; i++)
					{
						list.Add(item);
					}
				}
				if (num3 < item2)
				{
					order.Left.Add((item, item2 - num3));
				}
			}
			if (list.Count == 0)
			{
				if (order.Problem.Length == 0)
				{
					order.Problem = ((num <= 0) ? "The dropshi