Decompiled source of BaconTerminal v1.2.0

BepInEx/plugins/BaconTerminal.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LethalLevelLoader;
using Microsoft.CodeAnalysis;
using MrovLib;
using MrovLib.ContentType;
using TMPro;
using TerminalUtils;
using TerminalUtils.Definitions;
using TerminalUtils.Utils;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using WeatherRegistry;

[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("BaconTerminal")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BaconTerminal")]
[assembly: AssemblyTitle("BaconTerminal")]
[assembly: AssemblyMetadata("AI_Assisted_Creation", "Code generated with Claude Code, Anthropic's AI coding agent")]
[assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BaconTerminal
{
	internal static class LevelLoaderDetails
	{
		private const int MinInteriorPercent = 1;

		internal static bool Installed => Chainloader.PluginInfos.ContainsKey("imabatby.lethallevelloader");

		internal static string Interiors(SelectableLevel level)
		{
			ExtendedLevel val = default(ExtendedLevel);
			if (!LevelManager.TryGetExtendedLevel(level, ref val, (ContentType)2))
			{
				return null;
			}
			List<ExtendedDungeonFlowWithRarity> validExtendedDungeonFlows = DungeonManager.GetValidExtendedDungeonFlows(val, false);
			long num = ((IEnumerable<ExtendedDungeonFlowWithRarity>)validExtendedDungeonFlows).Sum((Func<ExtendedDungeonFlowWithRarity, long>)((ExtendedDungeonFlowWithRarity flow) => flow.rarity));
			if (num <= 0)
			{
				return null;
			}
			List<string> list = new List<string>();
			int num2 = 100;
			foreach (ExtendedDungeonFlowWithRarity item in validExtendedDungeonFlows.OrderByDescending((ExtendedDungeonFlowWithRarity flow) => flow.rarity))
			{
				int num3 = (int)Math.Round(100.0 * (double)item.rarity / (double)num);
				if (num3 < 1)
				{
					break;
				}
				list.Add($"{item.extendedDungeonFlow.DungeonName.Trim()} {num3}%");
				num2 -= num3;
			}
			if (num2 > 0)
			{
				list.Add($"others {num2}%");
			}
			return "INTERIOR: " + string.Join(", ", list);
		}
	}
	internal static class ModernPages
	{
		private sealed class MoonRow
		{
			internal string Name;

			internal string Price;

			internal string Weather;

			internal string Bonus;

			internal string Extra;

			internal bool Hidden;
		}

		private enum StoreRowKind
		{
			Section,
			Item,
			Break
		}

		private sealed class StoreRow
		{
			internal StoreRowKind Kind;

			internal string Name;

			internal string Sale;

			internal string Price;

			internal string Owned;
		}

		private const int RuleWidth = 44;

		private const int MaxName = 18;

		private const int MaxWeather = 11;

		private const int MaxItem = 24;

		private const string Strong = "═";

		private const string Light = "·";

		private static readonly Regex Tags = new Regex("<[^>]*>");

		private static readonly char[] TitleBox = new char[3] { '╔', '║', '╚' };

		private static readonly Regex StoreHeader = new Regex("^\\s*Name\\s+Price\\s+Owned\\s*$");

		private static readonly Regex StoreSection = new Regex("^\\s*\\[(?<section>[A-Z][A-Z ]*)\\]\\s*$");

		private static readonly Regex StoreDivider = new Regex("^[\\s-]*-{3,}[\\s-]*$");

		private static readonly Regex StoreItem = new Regex("^\\s*(?:\\*\\s+)?(?<name>.*?)(?:\\s+\\(?-(?<sale>\\d+)%\\)?)?\\s+\\$(?<price>\\d+)(?:\\s+×(?<owned>\\d+))?\\s*$");

		private static Assembly _formatter;

		private static bool _weatherRegistry;

		private static bool _warned;

		private const string Unknown = "???";

		private const string HiddenColor = "#7A7A7A";

		internal static void Apply(Harmony h)
		{
			//IL_0076: 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_00a3: Expected O, but got Unknown
			//IL_00a3: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			if (Chainloader.PluginInfos.TryGetValue("TerminalFormatter", out var value) && value.Instance != null)
			{
				_formatter = ((object)value.Instance).GetType().Assembly;
				_weatherRegistry = Chainloader.PluginInfos.ContainsKey("mrov.WeatherRegistry");
				MethodInfo methodInfo = NodeText("Moons");
				MethodInfo methodInfo2 = NodeText("Store");
				if (methodInfo != null)
				{
					h.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(ModernPages), "DrawMoons", (Type[])null), new HarmonyMethod(typeof(ModernPages), "HideClassic", (Type[])null)
					{
						priority = 800
					}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				if (methodInfo2 != null)
				{
					h.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(ModernPages), "DrawStore", (Type[])null)
					{
						priority = 800
					}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				if (methodInfo == null || methodInfo2 == null)
				{
					Plugin.Log.LogWarning((object)"ModernPages: TerminalFormatter's layout changed, so a Modern page shows TerminalFormatter's own");
				}
			}
		}

		private static MethodInfo NodeText(string node)
		{
			Type type = _formatter.GetType("TerminalFormatter.Nodes." + node, throwOnError: false);
			if (!(type == null))
			{
				return AccessTools.Method(type, "GetNodeText", new Type[1] { typeof(TerminalNode) }, (Type[])null);
			}
			return null;
		}

		private static bool DrawMoons(ref string __result)
		{
			TerminalLook.DrewModernPage = false;
			if (!TerminalLook.ModernPages)
			{
				return true;
			}
			try
			{
				__result = MoonsPage();
				TerminalLook.DrewModernPage = true;
				return false;
			}
			catch (Exception e)
			{
				Warn(e);
				return true;
			}
		}

		private static void HideClassic(ref string __result)
		{
			if (TerminalLook.ModernPages || string.IsNullOrEmpty(__result))
			{
				return;
			}
			try
			{
				List<PreviewInfoType<SelectableLevel>> currentPreviewInfoType = TerminalManager.CurrentPreviewInfoType;
				if (currentPreviewInfoType == null)
				{
					return;
				}
				bool flag = FormatterSetting("ShowNumberedPlanetNames");
				string[] array = __result.Split('\n');
				bool flag2 = false;
				foreach (SelectableLevel currentLevel in TerminalManager.GetCurrentLevels())
				{
					if ((Object)(object)currentLevel == (Object)null || !MoonListApi.Hides(currentLevel))
					{
						continue;
					}
					string text = null;
					List<string> list = new List<string>();
					foreach (PreviewInfoType<SelectableLevel> item in currentPreviewInfoType)
					{
						if (((TerminalInfoType)item).Name.Contains("Name"))
						{
							text = ((flag && TerminalManager.PreviewInfoTypes.ContainsKey("NumberedName")) ? TerminalManager.PreviewInfoTypes["NumberedName"] : item).Value(currentLevel);
						}
						else
						{
							list.Add(item.Value(currentLevel));
						}
					}
					if (string.IsNullOrEmpty(text))
					{
						continue;
					}
					string text2 = "* " + text;
					for (int i = 0; i < array.Length; i++)
					{
						int num = array[i].IndexOf(text2, StringComparison.Ordinal);
						int num2 = num + text2.Length;
						if (num < 0 || (num2 < array[i].Length && !char.IsWhiteSpace(array[i][num2])))
						{
							continue;
						}
						string text3 = array[i].Substring(num2);
						foreach (string item2 in list)
						{
							int num3 = (string.IsNullOrEmpty(item2) ? (-1) : text3.IndexOf(item2, StringComparison.Ordinal));
							if (num3 >= 0)
							{
								text3 = text3.Substring(0, num3) + Gray("???") + new string(' ', Math.Max(0, Visible(item2) - "???".Length)) + text3.Substring(num3 + item2.Length);
							}
						}
						array[i] = array[i].Substring(0, num) + Gray(text2) + text3;
						flag2 = true;
						break;
					}
				}
				if (flag2)
				{
					__result = string.Join("\n", array);
				}
			}
			catch (Exception e)
			{
				Warn(e);
			}
		}

		private static void DrawStore(ref string __result)
		{
			TerminalLook.DrewModernPage = false;
			if (!TerminalLook.ModernPages || string.IsNullOrEmpty(__result))
			{
				return;
			}
			try
			{
				string text = StorePage(__result);
				if (text != null)
				{
					__result = text;
					TerminalLook.DrewModernPage = true;
				}
			}
			catch (Exception e)
			{
				Warn(e);
			}
		}

		private static void Warn(Exception e)
		{
			if (!_warned)
			{
				_warned = true;
				Plugin.Log.LogWarning((object)$"ModernPages: couldn't draw a page, so TerminalFormatter's shows instead: {e}");
			}
		}

		private static string Gray(string text)
		{
			return "<color=#7A7A7A>" + text + "</color>";
		}

		private static string MoonsPage()
		{
			TerminalPalette palette = TerminalLook.Palette;
			List<PreviewInfoType<SelectableLevel>> source = TerminalManager.CurrentPreviewInfoType ?? new List<PreviewInfoType<SelectableLevel>>();
			bool flag = source.Any((PreviewInfoType<SelectableLevel> info) => ((TerminalInfoType)info).Name == "Price") && TerminalManager.PreviewInfoTypes.ContainsKey("Price");
			bool flag2 = source.Any((PreviewInfoType<SelectableLevel> info) => ((TerminalInfoType)info).Name == "Weather");
			List<PreviewInfoType<SelectableLevel>> list = source.Where((PreviewInfoType<SelectableLevel> info) => !((TerminalInfoType)info).Name.Contains("Name") && ((TerminalInfoType)info).Name != "Price" && ((TerminalInfoType)info).Name != "Weather").ToList();
			bool flag3 = FormatterSetting("ShowNumberedPlanetNames");
			bool flag4 = FormatterSetting("AlwaysDisplayHiddenMoons");
			List<MoonRow> list2 = new List<MoonRow>();
			foreach (SelectableLevel level in TerminalManager.GetCurrentLevels())
			{
				if ((Object)(object)level == (Object)null || Defaults.IgnoreLevels.Contains(StringResolver.GetNumberlessName(level)) || (LevelHelper.IsHidden(level) && !flag4) || (ConfigManager.HideCompanyMoons.Value && LevelHelper.CompanyMoons.Contains(level)))
				{
					continue;
				}
				MoonRow moonRow = new MoonRow
				{
					Name = Fit(flag3 ? level.PlanetName : StringResolver.GetNumberlessName(level), 18),
					Hidden = MoonListApi.Hides(level)
				};
				if (flag)
				{
					moonRow.Price = (moonRow.Hidden ? "???" : TerminalManager.PreviewInfoTypes["Price"].Value(level));
				}
				if (flag2)
				{
					moonRow.Weather = (moonRow.Hidden ? Gray("???") : WeatherCell(level, out moonRow.Bonus));
				}
				if (list.Count > 0 && !moonRow.Hidden)
				{
					moonRow.Extra = string.Join("  ", list.Select((PreviewInfoType<SelectableLevel> info) => info.Value(level)));
				}
				list2.Add(moonRow);
			}
			int width = Math.Max(4, list2.Select((MoonRow row) => Visible(row.Name)).DefaultIfEmpty(0).Max());
			int width2 = Math.Max(5, list2.Select((MoonRow row) => Visible(row.Price ?? "")).DefaultIfEmpty(0).Max());
			StringBuilder stringBuilder = new StringBuilder();
			SortInfoType<SelectableLevel> currentSortInfoType = TerminalManager.CurrentSortInfoType;
			string text = Upper((currentSortInfoType != null) ? ((TerminalInfoType)currentSortInfoType).Name : null);
			FilterInfoType<SelectableLevel> currentFilterInfoType = TerminalManager.CurrentFilterInfoType;
			Banner(stringBuilder, palette, "MOONS", "SORT " + text + " · FILTER " + Upper((currentFilterInfoType != null) ? ((TerminalInfoType)currentFilterInfoType).Name : null));
			stringBuilder.Append("  ").Append(RouteDetails.SellingMoons()).Append($" buy scrap at {Mathf.RoundToInt(StartOfRound.Instance.companyBuyingRate * 100f)}%.\n");
			if (FormatterSetting("ShowHelpText"))
			{
				stringBuilder.Append("  ").Append(Dim("ROUTE or INFO and a moon's name.")).Append('\n');
			}
			stringBuilder.Append('\n');
			StringBuilder stringBuilder2 = new StringBuilder("  ").Append(PadRight("MOON", width));
			if (flag)
			{
				stringBuilder2.Append("  ").Append(PadLeft("PRICE", width2));
			}
			if (flag2)
			{
				stringBuilder2.Append("   ").Append("WEATHER");
			}
			stringBuilder.Append(Dim(stringBuilder2.ToString())).Append('\n');
			Rule(stringBuilder, "═", dim: true);
			int value = ConfigManager.DivideMoons.Value;
			int num = 0;
			bool flag5 = false;
			for (int num2 = 0; num2 < list2.Count; num2++)
			{
				MoonRow moonRow2 = list2[num2];
				StringBuilder stringBuilder3 = new StringBuilder("  ").Append(PadRight(moonRow2.Hidden ? Gray(moonRow2.Name) : moonRow2.Name, width));
				if (flag)
				{
					stringBuilder3.Append("  ").Append(PadLeft(moonRow2.Hidden ? Gray(moonRow2.Price) : Colored(palette.Money, moonRow2.Price), width2));
				}
				if (flag2)
				{
					stringBuilder3.Append("   ").Append(moonRow2.Weather);
					if (!string.IsNullOrEmpty(moonRow2.Bonus))
					{
						stringBuilder3.Append(' ').Append(moonRow2.Bonus);
					}
					flag5 |= !string.IsNullOrEmpty(moonRow2.Bonus);
				}
				if (!string.IsNullOrEmpty(moonRow2.Extra))
				{
					stringBuilder3.Append("  ").Append(Dim(moonRow2.Extra));
				}
				stringBuilder.Append(stringBuilder3.ToString().TrimEnd()).Append('\n');
				if (value > 0 && ++num == value && num2 < list2.Count - 1)
				{
					num = 0;
					Rule(stringBuilder, "·", dim: true);
				}
			}
			Rule(stringBuilder, "═", dim: true);
			if (flag5)
			{
				stringBuilder.Append("  ").Append(Colored(palette.Money, "$")).Append(Dim(" value  "))
					.Append(Colored(palette.Info, "▪"))
					.Append(Dim(" amount: the weather's scrap bonus"))
					.Append('\n');
			}
			if (TerminalHelp.SortBonusAdded)
			{
				stringBuilder.Append("  ").Append(Dim("SORT BONUS lists the best-paying moons first.")).Append('\n');
			}
			return stringBuilder.ToString().TrimEnd();
		}

		private static string WeatherCell(SelectableLevel level, out string bonus)
		{
			bonus = null;
			float value = 1f;
			float amount = 1f;
			string name;
			if (_weatherRegistry)
			{
				if (!RegistryWeather.TryGet(level, out name, out var shortName, out value, out amount))
				{
					return Dim(Fit(GetWeatherName.GetWeather(level, false) ?? "", 11));
				}
				if (name.Length > 11 && !string.IsNullOrEmpty(shortName))
				{
					name = shortName;
				}
			}
			else
			{
				name = ((object)Unsafe.As<LevelWeatherType, LevelWeatherType>(ref level.currentWeather)/*cast due to .constrained prefix*/).ToString();
			}
			if (string.IsNullOrEmpty(name) || name == "None")
			{
				return Dim("Clear");
			}
			bonus = WeatherLook.BonusIcons(value, amount);
			return WeatherLook.Colored(level, Fit(name, 11));
		}

		private static string StorePage(string formatted)
		{
			List<StoreRow> list = new List<StoreRow>();
			List<string> list2 = new List<string>();
			string[] array = formatted.Split('\n');
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].TrimEnd();
				if (text.Trim().Length == 0 || StoreDivider.IsMatch(text))
				{
					if (list.Count > 0 && list[list.Count - 1].Kind == StoreRowKind.Item)
					{
						list.Add(new StoreRow
						{
							Kind = StoreRowKind.Break
						});
					}
				}
				else
				{
					if (text.IndexOfAny(TitleBox) >= 0 || StoreHeader.IsMatch(text))
					{
						continue;
					}
					Match match = StoreSection.Match(text);
					if (match.Success)
					{
						if (list.Count > 0 && list[list.Count - 1].Kind == StoreRowKind.Break)
						{
							list.RemoveAt(list.Count - 1);
						}
						list.Add(new StoreRow
						{
							Kind = StoreRowKind.Section,
							Name = match.Groups["section"].Value.Trim()
						});
						continue;
					}
					Match match2 = StoreItem.Match(text);
					if (match2.Success && match2.Groups["name"].Value.Trim().Length > 0)
					{
						list.Add(new StoreRow
						{
							Kind = StoreRowKind.Item,
							Name = Fit(match2.Groups["name"].Value.Trim(), 24),
							Sale = (match2.Groups["sale"].Success ? ("-" + match2.Groups["sale"].Value + "%") : null),
							Price = "$" + match2.Groups["price"].Value,
							Owned = (match2.Groups["owned"].Success ? int.Parse(match2.Groups["owned"].Value, CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture) : null)
						});
					}
					else
					{
						list2.Add(text.Trim());
					}
				}
			}
			while (list.Count > 0 && list[list.Count - 1].Kind == StoreRowKind.Break)
			{
				list.RemoveAt(list.Count - 1);
			}
			if (!list.Any((StoreRow row) => row.Kind == StoreRowKind.Item))
			{
				return null;
			}
			TerminalPalette palette = TerminalLook.Palette;
			List<StoreRow> source = list.Where((StoreRow row) => row.Kind == StoreRowKind.Item).ToList();
			int width = Math.Max(12, source.Max((StoreRow row) => Visible(row.Name)));
			int width2 = Math.Max(5, source.Max((StoreRow row) => row.Price.Length));
			bool flag = source.Any((StoreRow row) => row.Sale != null);
			bool flag2 = source.Any((StoreRow row) => row.Owned != null);
			StringBuilder stringBuilder = new StringBuilder();
			Banner(stringBuilder, palette, "COMPANY STORE", null);
			stringBuilder.Append("  ").Append(Dim("BUY or INFO and an item. Add a number for more.")).Append('\n');
			stringBuilder.Append('\n');
			foreach (StoreRow item in list)
			{
				if (item.Kind == StoreRowKind.Break)
				{
					Rule(stringBuilder, "·", dim: true);
					continue;
				}
				StringBuilder stringBuilder2 = new StringBuilder("  ");
				if (item.Kind == StoreRowKind.Section)
				{
					stringBuilder2.Append(Colored(palette.Heading, PadRight(item.Name, width)));
					if (flag)
					{
						stringBuilder2.Append(' ').Append(new string(' ', 5));
					}
					stringBuilder2.Append("  ").Append(Dim(PadLeft("PRICE", width2)));
					if (flag2)
					{
						stringBuilder2.Append("  ").Append(Dim("OWNED"));
					}
				}
				else
				{
					stringBuilder2.Append(PadRight(item.Name, width));
					if (flag)
					{
						stringBuilder2.Append(' ').Append(PadLeft((item.Sale == null) ? "" : Colored(palette.Good, item.Sale), 5));
					}
					stringBuilder2.Append("  ").Append(PadLeft(Colored(palette.Money, item.Price), width2));
					if (item.Owned != null)
					{
						stringBuilder2.Append("  ").Append(PadLeft(Colored(palette.Info, item.Owned), 5));
					}
				}
				stringBuilder.Append(stringBuilder2.ToString().TrimEnd()).Append('\n');
			}
			Rule(stringBuilder, "═", dim: true);
			return stringBuilder.ToString().TrimEnd();
		}

		private static void Banner(StringBuilder text, TerminalPalette palette, string title, string note)
		{
			Rule(text, "═", dim: false);
			StringBuilder stringBuilder = new StringBuilder("  ").Append(Colored(palette.Heading, title));
			if (!string.IsNullOrEmpty(note))
			{
				stringBuilder.Append("    ").Append(Dim(note));
			}
			text.Append(stringBuilder).Append('\n');
			Rule(text, "═", dim: false);
		}

		private static void Rule(StringBuilder text, string mark, bool dim)
		{
			string text2 = string.Concat(" ", string.Concat(Enumerable.Repeat(mark, 44)));
			text.Append(dim ? Dim(text2) : Colored(TerminalLook.Palette.Heading, text2)).Append('\n');
		}

		private static bool FormatterSetting(string name)
		{
			object? obj = _formatter.GetType("TerminalFormatter.ConfigManager", throwOnError: false)?.GetProperty(name, BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
			object? obj2 = ((obj is ConfigEntryBase) ? obj : null);
			object obj3 = ((obj2 != null) ? ((ConfigEntryBase)obj2).BoxedValue : null);
			bool flag = default(bool);
			int num;
			if (obj3 is bool)
			{
				flag = (bool)obj3;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		private static string Upper(string text)
		{
			if (!string.IsNullOrEmpty(text))
			{
				return text.ToUpperInvariant();
			}
			return "NONE";
		}

		private static int Visible(string text)
		{
			if (!string.IsNullOrEmpty(text))
			{
				return Tags.Replace(text, "").Length;
			}
			return 0;
		}

		private static string PadRight(string text, int width)
		{
			return text + new string(' ', Math.Max(0, width - Visible(text)));
		}

		private static string PadLeft(string text, int width)
		{
			return new string(' ', Math.Max(0, width - Visible(text))) + text;
		}

		private static string Fit(string text, int width)
		{
			if (!string.IsNullOrEmpty(text) && text.Length > width)
			{
				return text.Substring(0, width - 1) + "…";
			}
			return text;
		}

		private static string Colored(string color, string text)
		{
			if (!string.IsNullOrEmpty(text))
			{
				return "<color=" + color + ">" + text + "</color>";
			}
			return text;
		}

		private static string Dim(string text)
		{
			return "<alpha=#99>" + text + "<alpha=#FF>";
		}
	}
	public static class MoonListApi
	{
		private static readonly List<Func<SelectableLevel, bool>> Checks = new List<Func<SelectableLevel, bool>>();

		private static bool _warned;

		public static void HideDetails(Func<SelectableLevel, bool> hidden)
		{
			if (hidden != null)
			{
				Checks.Add(hidden);
			}
		}

		internal static bool Hides(SelectableLevel level)
		{
			foreach (Func<SelectableLevel, bool> check in Checks)
			{
				try
				{
					if (check(level))
					{
						return true;
					}
				}
				catch (Exception ex)
				{
					if (!_warned)
					{
						Plugin.Log.LogWarning((object)("MoonListApi: another mod's check failed, so its moons show their details: " + ex.Message));
					}
					_warned = true;
				}
			}
			return false;
		}
	}
	internal static class PageColors
	{
		private static readonly char[] TitleBox = new char[3] { '╔', '║', '╚' };

		private static readonly Regex StoreParts = new Regex("(?<section>\\[[A-Z][A-Z ]*\\])|(?<sale>\\(?-\\d+%\\)?)|(?<price>\\$\\d+)|(?<owned>×\\d+)|(?<command>\\b(?:BUY|INFO)\\b)");

		private static readonly Regex Price = new Regex("\\$\\d+");

		internal static void Apply(Harmony h)
		{
			if (Chainloader.PluginInfos.TryGetValue("TerminalFormatter", out var value) && value.Instance != null)
			{
				Assembly assembly = ((object)value.Instance).GetType().Assembly;
				Patch(h, assembly.GetType("TerminalFormatter.Nodes.Store", throwOnError: false), "StorePostfix");
				Patch(h, assembly.GetType("TerminalFormatter.Nodes.Moons", throwOnError: false), "MoonsPostfix");
			}
		}

		private static void Patch(Harmony h, Type node, string postfix)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			MethodInfo methodInfo = ((node == null) ? null : AccessTools.Method(node, "GetNodeText", new Type[1] { typeof(TerminalNode) }, (Type[])null));
			if (methodInfo != null)
			{
				h.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(PageColors), postfix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Plugin.Log.LogWarning((object)("PageColors: TerminalFormatter has no " + (node?.Name ?? "page") + " to color"));
			}
		}

		private static void StorePostfix(ref string __result)
		{
			if (string.IsNullOrEmpty(__result) || TerminalLook.DrewModernPage)
			{
				return;
			}
			TerminalPalette palette = TerminalLook.Palette;
			string[] array = __result.Split('\n');
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = ((array[i].IndexOfAny(TitleBox) >= 0) ? Colored(palette.Heading, array[i]) : StoreParts.Replace(array[i], (Match part) => Colored((part.Groups["section"].Success || part.Groups["command"].Success) ? palette.Heading : (part.Groups["sale"].Success ? palette.Good : (part.Groups["price"].Success ? palette.Money : palette.Info)), part.Value)));
			}
			__result = string.Join("\n", array);
		}

		private static void MoonsPostfix(ref string __result)
		{
			if (!string.IsNullOrEmpty(__result) && !TerminalLook.DrewModernPage)
			{
				string money = TerminalLook.Palette.Money;
				__result = Price.Replace(__result, (Match price) => Colored(money, price.Value));
			}
		}

		private static string Colored(string color, string text)
		{
			return "<color=" + color + ">" + text + "</color>";
		}
	}
	[BepInPlugin("baconterminal", "BaconTerminal", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal const string Guid = "baconterminal";

		internal const string Version = "1.2.0";

		private const string BaconFixerGuid = "baconfixer";

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			if (Chainloader.PluginInfos.TryGetValue("baconfixer", out var value) && value.Metadata.Version.Major < 2)
			{
				Log.LogWarning((object)$"BaconFixer {value.Metadata.Version} already has these terminal extras, so BaconTerminal stays off. Update BaconFixer to 2.0.0 or later.");
				return;
			}
			Harmony h = new Harmony("baconterminal");
			Apply("WeatherMultiplierDisplay", delegate
			{
				WeatherMultiplierDisplay.Apply(h);
			});
			Apply("SortBonus", delegate
			{
				ApplySortBonus(h);
			});
			Apply("TerminalHelp", delegate
			{
				h.PatchAll(typeof(TerminalHelp));
			});
			Apply("TerminalQuality", delegate
			{
				TerminalQuality.Apply(h, ((BaseUnityPlugin)this).Config);
			});
			Apply("TerminalLook", delegate
			{
				TerminalLook.Apply(h, ((BaseUnityPlugin)this).Config);
			});
			Apply("PageColors", delegate
			{
				PageColors.Apply(h);
			});
			Apply("ModernPages", delegate
			{
				ApplyModernPages(h);
			});
			Apply("ShipScreen", delegate
			{
				h.PatchAll(typeof(ShipScreen));
			});
			Log.LogInfo((object)"BaconTerminal 1.2.0 loaded");
		}

		private static void ApplyModernPages(Harmony h)
		{
			if (Chainloader.PluginInfos.ContainsKey("mrov.TerminalUtils") && Chainloader.PluginInfos.ContainsKey("TerminalFormatter"))
			{
				PatchModernPages(h);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void PatchModernPages(Harmony h)
		{
			ModernPages.Apply(h);
		}

		private static void ApplySortBonus(Harmony h)
		{
			if (Chainloader.PluginInfos.ContainsKey("mrov.TerminalUtils") && Chainloader.PluginInfos.ContainsKey("mrov.WeatherRegistry"))
			{
				PatchSortBonus(h);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void PatchSortBonus(Harmony h)
		{
			SortBonus.Apply(h);
		}

		private static void Apply(string name, Action extra)
		{
			try
			{
				extra();
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)(name + " failed: " + ex.Message));
			}
		}
	}
	internal static class RegistryWeather
	{
		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static bool TryGet(SelectableLevel level, out string name, out string shortName, out float value, out float amount)
		{
			name = (shortName = null);
			value = (amount = 1f);
			try
			{
				Weather val = (((Object)(object)level == (Object)null) ? null : WeatherManager.GetCurrentWeather(level));
				if (val == null || WeatherManager.GetCurrentWeatherName(level, false) != val.Name)
				{
					return false;
				}
				name = val.Name;
				shortName = val.NameShort;
				value = val.ScrapValueMultiplier;
				amount = val.ScrapAmountMultiplier;
				return true;
			}
			catch
			{
				return false;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static bool TryGetColor(SelectableLevel level, out Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			color = Color.white;
			try
			{
				Weather val = (((Object)(object)level == (Object)null) ? null : WeatherManager.GetCurrentWeather(level));
				if ((Object)(object)((val != null) ? val.ColorGradient : null) == (Object)null)
				{
					return false;
				}
				color = val.Color;
				return true;
			}
			catch
			{
				return false;
			}
		}
	}
	internal static class RouteDetails
	{
		private const float ScrapValueScale = 0.4f;

		private const string CompanyLevel = "CompanyBuildingLevel";

		private const string GaletryLevel = "GaletryLevel";

		private const string CompanyHeader = "The Company // Buying at";

		private const string CompanyAndGaletryHeader = "The Company and Galetry // Buying at";

		internal static string Selling(SelectableLevel level)
		{
			if (((Object)level).name != "CompanyBuildingLevel" && ((Object)level).name != "GaletryLevel")
			{
				return null;
			}
			return $"SELLS SCRAP: buying at {Mathf.RoundToInt(StartOfRound.Instance.companyBuyingRate * 100f)}%";
		}

		internal static string NameSellingMoons(string text)
		{
			if (!HasGaletry())
			{
				return text;
			}
			return text.Replace("The Company // Buying at", "The Company and Galetry // Buying at");
		}

		internal static string SellingMoons()
		{
			if (!HasGaletry())
			{
				return "The Company";
			}
			return "The Company and Galetry";
		}

		private static bool HasGaletry()
		{
			return StartOfRound.Instance.levels.Any((SelectableLevel level) => (Object)(object)level != (Object)null && ((Object)level).name == "GaletryLevel");
		}

		internal static string Loot(SelectableLevel level, float valueBonus, float amountBonus)
		{
			if (level.spawnableScrap == null || level.maxScrap <= 0)
			{
				return null;
			}
			float num = 0f;
			float num2 = 0f;
			foreach (SpawnableItemWithRarity item in level.spawnableScrap)
			{
				if (!((Object)(object)item?.spawnableItem == (Object)null) && item.rarity > 0)
				{
					num += (float)item.rarity;
					num2 += (float)(item.rarity * (item.spawnableItem.minValue + item.spawnableItem.maxValue)) / 2f;
				}
			}
			if (num <= 0f)
			{
				return null;
			}
			float num3 = (float)(level.minScrap + level.maxScrap) / 2f * amountBonus;
			int num4 = Mathf.RoundToInt(num3 * (num2 / num) * 0.4f * valueBonus / 10f) * 10;
			return $"LOOT: about ${num4} ({Mathf.RoundToInt(num3)} items)";
		}

		internal static string DayLength(SelectableLevel level)
		{
			TimeOfDay instance = TimeOfDay.Instance;
			if ((Object)(object)instance == (Object)null || level.DaySpeedMultiplier <= 0f || instance.globalTimeSpeedMultiplier <= 0f)
			{
				return null;
			}
			if (!level.planetHasTime)
			{
				return "DAY LENGTH: no clock here";
			}
			return "DAY LENGTH: " + ((instance.totalTime - 100f - level.OffsetFromGlobalTime) / level.DaySpeedMultiplier / instance.globalTimeSpeedMultiplier / 60f).ToString("0.#", CultureInfo.InvariantCulture) + " min";
		}
	}
	internal static class SettingsRows
	{
		private sealed class Row
		{
			internal string Caption;

			internal List<string> Options;

			internal Func<int> Get;

			internal Action<int> Set;
		}

		private const float FirstRowBelowMotionBlur = -145f;

		private const float DefaultRowGap = 55f;

		private const float MinRowGap = 30f;

		private static readonly List<Row> Rows = new List<Row>();

		private static bool _patched;

		internal static void Add<T>(Harmony h, string caption, ConfigEntry<T> entry) where T : struct, Enum
		{
			Rows.Add(new Row
			{
				Caption = caption,
				Options = Enum.GetNames(typeof(T)).ToList(),
				Get = () => Convert.ToInt32(entry.Value),
				Set = delegate(int value)
				{
					entry.Value = (T)Enum.ToObject(typeof(T), value);
				}
			});
			if (!_patched)
			{
				h.PatchAll(typeof(SettingsRows));
				_patched = true;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MenuManager), "Start")]
		private static void AddToMainMenu()
		{
			AddToSettings();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(QuickMenuManager), "Start")]
		private static void AddToPauseMenu()
		{
			AddToSettings();
		}

		private static void AddToSettings()
		{
			//IL_00a3: 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_00a9: 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_00c2: 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_0130: Expected O, but got Unknown
			SettingsOption val = ((IEnumerable<SettingsOption>)Object.FindObjectsOfType<SettingsOption>(true)).FirstOrDefault((Func<SettingsOption, bool>)((SettingsOption option) => (int)option.optionType == 15));
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			float num = RowGap(val);
			for (int num2 = 0; num2 < Rows.Count; num2++)
			{
				Row spec = Rows[num2];
				GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent);
				((Object)obj).name = "BaconTerminal " + spec.Caption.TrimEnd(':');
				Object.DestroyImmediate((Object)(object)obj.GetComponent<SettingsOption>());
				RectTransform val2 = (RectTransform)obj.transform;
				val2.anchoredPosition += new Vector2(0f, -145f - (float)num2 * num);
				obj.transform.SetSiblingIndex(((Component)val).transform.GetSiblingIndex() + 1 + num2);
				Transform obj2 = obj.transform.Find("Label2");
				TMP_Text val3 = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Text>() : null);
				if ((Object)(object)val3 != (Object)null)
				{
					val3.text = spec.Caption;
				}
				TMP_Dropdown component = obj.GetComponent<TMP_Dropdown>();
				component.onValueChanged = new DropdownEvent();
				component.ClearOptions();
				component.AddOptions(spec.Options);
				component.SetValueWithoutNotify(spec.Get());
				((UnityEvent<int>)(object)component.onValueChanged).AddListener((UnityAction<int>)delegate(int value)
				{
					spec.Set(value);
				});
			}
		}

		private static float RowGap(SettingsOption source)
		{
			//IL_0044: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			SettingsOption val = ((IEnumerable<SettingsOption>)((Component)((Component)source).transform.parent).GetComponentsInChildren<SettingsOption>(true)).FirstOrDefault((Func<SettingsOption, bool>)((SettingsOption option) => (int)option.optionType == 16 && (Object)(object)((Component)option).transform.parent == (Object)(object)((Component)source).transform.parent));
			float num = (((Object)(object)val == (Object)null) ? 0f : Mathf.Abs(((RectTransform)((Component)val).transform).anchoredPosition.y - ((RectTransform)((Component)source).transform).anchoredPosition.y));
			if (!(num > 30f))
			{
				return 55f;
			}
			return num;
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "SetMapScreenInfoToCurrentLevel")]
	internal static class ShipScreen
	{
		private const float SmallestScale = 0.5f;

		private const string NameColor = "#FFFFFF";

		private const string TextColor = "#D8F0F0";

		private const string ValueColor = "#FFD24D";

		private const string AmountColor = "#8CFF8C";

		private static readonly Regex Label = new Regex("^(?<label>[A-Za-z][A-Za-z ]{0,20}:)(?<value>.*)$");

		private static readonly Regex Multipliers = new Regex("(?<value>$|\\$)x(?<valueNumber>[\\d.,]+)(?<gap>\\s+)(?<amount>▼)x(?<amountNumber>[\\d.,]+)");

		private const string NoChange = "+0%";

		[HarmonyPostfix]
		[HarmonyPriority(-100)]
		private static void Restyle(StartOfRound __instance)
		{
			try
			{
				TextMeshProUGUI screenLevelDescription = __instance.screenLevelDescription;
				if (!((Object)(object)screenLevelDescription == (Object)null) && !string.IsNullOrEmpty(((TMP_Text)screenLevelDescription).text))
				{
					Fit(screenLevelDescription);
					string text = Colored(((TMP_Text)screenLevelDescription).text, __instance.currentLevel);
					if (text != ((TMP_Text)screenLevelDescription).text)
					{
						((TMP_Text)screenLevelDescription).text = text;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("ShipScreen: couldn't restyle the ship's monitor: " + ex.Message));
			}
		}

		private static void Fit(TextMeshProUGUI screen)
		{
			if (!((TMP_Text)screen).enableAutoSizing)
			{
				((TMP_Text)screen).fontSizeMax = ((TMP_Text)screen).fontSize;
				((TMP_Text)screen).fontSizeMin = ((TMP_Text)screen).fontSize * 0.5f;
				((TMP_Text)screen).enableWordWrapping = true;
				((TMP_Text)screen).enableAutoSizing = true;
			}
		}

		private static string Colored(string text, SelectableLevel level)
		{
			string[] array = text.Split('\n');
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i].Trim().Length == 0 || array[i].Contains("<color="))
				{
					continue;
				}
				Match match = Label.Match(array[i]);
				if (!match.Success)
				{
					array[i] = Wrap("#D8F0F0", array[i]);
					continue;
				}
				string value = match.Groups["label"].Value;
				string text2 = match.Groups["value"].Value;
				string text3;
				switch (value.ToUpperInvariant())
				{
				case "ORBITING:":
					text3 = "#FFFFFF";
					break;
				case "WEATHER:":
				{
					string text4 = Regex.Replace(text2, "<[^>]*>", "").Trim();
					text3 = WeatherLook.ColorOf(level, text4);
					if (text4 == "None")
					{
						text2 = " Clear";
					}
					break;
				}
				case "MULTIPLIERS:":
					text2 = Percents(text2);
					text3 = null;
					break;
				default:
					text3 = "#D8F0F0";
					break;
				}
				array[i] = value + ((text3 == null) ? text2 : Wrap(text3, text2));
			}
			return string.Join("\n", array);
		}

		private static string Percents(string value)
		{
			return Multipliers.Replace(value, delegate(Match match)
			{
				string text = Percent(match.Groups["valueNumber"].Value);
				string text2 = Percent(match.Groups["amountNumber"].Value);
				List<string> list = new List<string>(2);
				if (text != "+0%")
				{
					list.Add(Wrap("#FFD24D", match.Groups["value"].Value + text));
				}
				if (text2 != "+0%")
				{
					list.Add(Wrap("#8CFF8C", match.Groups["amount"].Value + text2));
				}
				return (list.Count != 0) ? string.Join(match.Groups["gap"].Value, list) : Wrap("#D8F0F0", "none");
			});
		}

		private static string Percent(string multiplier)
		{
			if (!float.TryParse(multiplier.Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				return "x" + multiplier;
			}
			return ((int)Math.Round((result - 1f) * 100f, MidpointRounding.AwayFromZero)).ToString("+0;-0;+0", CultureInfo.InvariantCulture) + "%";
		}

		private static string Wrap(string color, string text)
		{
			if (!string.IsNullOrEmpty(text))
			{
				return "<color=" + color + ">" + text + "</color>";
			}
			return text;
		}
	}
	internal sealed class SortBonus : SortInfoType<SelectableLevel>
	{
		private SortBonus()
			: base("Bonus")
		{
		}

		public override List<SelectableLevel> Sort(List<SelectableLevel> inputList)
		{
			return inputList.OrderByDescending(Score).ToList();
		}

		private static float Score(SelectableLevel level)
		{
			if (!RegistryWeather.TryGet(level, out var _, out var _, out var value, out var amount))
			{
				return 1f;
			}
			return value * amount;
		}

		internal static void Apply(Harmony h)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(TerminalManager), "RegisterLocalInfoTypes", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Plugin.Log.LogWarning((object)"SortBonus: TerminalUtils layout changed, skipping");
				return;
			}
			h.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(SortBonus), "Register", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			TerminalHelp.SortBonusAdded = true;
		}

		private static void Register()
		{
			TerminalManager.SortInfoTypes["Bonus"] = new SortBonus();
		}
	}
	[HarmonyPatch(typeof(Terminal), "Start")]
	internal static class TerminalHelp
	{
		internal static bool SortBonusAdded;

		internal static bool MoonPagesAdded;

		[HarmonyPostfix]
		private static void AddToOtherPage(Terminal __instance)
		{
			string text = Text();
			if (text.Length == 0)
			{
				return;
			}
			TerminalKeyword[] allKeywords = __instance.terminalNodes.allKeywords;
			foreach (TerminalKeyword val in allKeywords)
			{
				if (!((Object)(object)val == (Object)null) && string.Equals(val.word, "other", StringComparison.OrdinalIgnoreCase))
				{
					TerminalNode specialKeywordResult = val.specialKeywordResult;
					if ((Object)(object)specialKeywordResult != (Object)null && !specialKeywordResult.displayText.Contains(text))
					{
						specialKeywordResult.displayText = specialKeywordResult.displayText.TrimEnd() + "\n\n" + text + "\n\n";
					}
					break;
				}
			}
		}

		private static string Text()
		{
			List<string> list = new List<string>();
			if (SortBonusAdded)
			{
				list.Add(">SORT BONUS\nTo list moons with the best weather bonus first. SORT NONE puts the order back.");
			}
			if (MoonPagesAdded)
			{
				list.Add(">MOON NAME\nTo see a moon's " + MoonPageLines() + ". Then CONFIRM or DENY.");
			}
			return string.Join("\n\n", list);
		}

		private static string MoonPageLines()
		{
			List<string> list = new List<string>();
			if (Chainloader.PluginInfos.ContainsKey("mrov.WeatherRegistry"))
			{
				list.Add("weather bonus");
			}
			list.Add(LevelLoaderDetails.Installed ? "likely loot and interiors" : "likely loot");
			list.Add("day length");
			list.Add("dangers");
			return string.Join(", ", list.Take(list.Count - 1)) + " and " + list.Last();
		}
	}
	internal enum TerminalTheme
	{
		Original,
		Amber,
		Ice,
		Company,
		Vapor,
		Mono
	}
	internal enum TerminalStyle
	{
		Modern,
		Compact,
		Retro,
		Classic
	}
	internal sealed class TerminalPalette
	{
		internal Color Text;

		internal Color Dark;

		internal Color Background;

		internal Color Light;

		internal string Heading = "#FFFFFF";

		internal string Money = "#FFD24D";

		internal string Good = "#8CFF8C";

		internal string Info = "#6BD9FF";

		internal string Time = "#C9A6FF";

		internal string Danger = "#FF6B6B";
	}
	internal static class TerminalLook
	{
		private sealed class Part
		{
			internal Graphic Graphic;

			internal Color Original;

			internal Func<TerminalPalette, Color> Themed;
		}

		private const float CompactSize = 0.85f;

		private const float CompactSpacing = -8f;

		private const float RetroLetters = 2f;

		private static readonly Dictionary<TerminalTheme, TerminalPalette> Palettes = new Dictionary<TerminalTheme, TerminalPalette>
		{
			{
				TerminalTheme.Original,
				new TerminalPalette()
			},
			{
				TerminalTheme.Amber,
				new TerminalPalette
				{
					Text = Rgb(1f, 0.69f, 0f),
					Dark = Rgb(0.33f, 0.2f, 0f),
					Background = Rgb(0.05f, 0.035f, 0.01f),
					Light = Rgb(1f, 0.8f, 0.55f),
					Heading = "#FFF4D6",
					Money = "#FFF0B0",
					Good = "#7DFF9E",
					Info = "#8FD3FF",
					Time = "#E0B8FF",
					Danger = "#FF5A4A"
				}
			},
			{
				TerminalTheme.Ice,
				new TerminalPalette
				{
					Text = Rgb(0.5f, 0.86f, 1f),
					Dark = Rgb(0.02f, 0.2f, 0.33f),
					Background = Rgb(0.02f, 0.035f, 0.06f),
					Light = Rgb(0.7f, 0.9f, 1f),
					Info = "#E0F7FF",
					Danger = "#FF7A7A"
				}
			},
			{
				TerminalTheme.Company,
				new TerminalPalette
				{
					Text = Rgb(1f, 0.38f, 0.15f),
					Dark = Rgb(0.33f, 0.06f, 0.02f),
					Background = Rgb(0.06f, 0.015f, 0.01f),
					Light = Rgb(1f, 0.65f, 0.5f),
					Heading = "#FFE3D6",
					Danger = "#FF9C9C"
				}
			},
			{
				TerminalTheme.Vapor,
				new TerminalPalette
				{
					Text = Rgb(1f, 0.49f, 0.91f),
					Dark = Rgb(0.25f, 0.06f, 0.33f),
					Background = Rgb(0.05f, 0.02f, 0.07f),
					Light = Rgb(0.95f, 0.7f, 1f),
					Money = "#FFE66B",
					Good = "#7DFFC8",
					Info = "#7DE3FF",
					Time = "#B9A6FF"
				}
			},
			{
				TerminalTheme.Mono,
				new TerminalPalette
				{
					Text = Rgb(0.91f, 0.91f, 0.91f),
					Dark = Rgb(0.25f, 0.25f, 0.25f),
					Background = Rgb(0.04f, 0.04f, 0.04f),
					Light = Rgb(1f, 1f, 1f)
				}
			}
		};

		private static ConfigEntry<TerminalTheme> _theme;

		private static ConfigEntry<TerminalStyle> _style;

		private static Terminal _terminal;

		private static readonly List<Part> Parts = new List<Part>();

		private static Color _caret;

		private static Color _selection;

		private static Color _light;

		private static float _fontSize;

		private static float _placeholderSize;

		private static float _lineSpacing;

		private static float _letterSpacing;

		private static FontStyles _fontStyle;

		internal static bool DrewModernPage;

		internal static TerminalPalette Palette => Palettes[(_theme != null) ? _theme.Value : TerminalTheme.Original];

		internal static bool ModernPages
		{
			get
			{
				if (_style != null)
				{
					return _style.Value != TerminalStyle.Classic;
				}
				return false;
			}
		}

		internal static void Apply(Harmony h, ConfigFile config)
		{
			_theme = config.Bind<TerminalTheme>("Terminal", "Theme", TerminalTheme.Original, "The terminal's colors: Original is the game's green, then Amber, Ice, Company, Vapor and Mono. Prices, bonuses and dangers get colors that stand out on each. It's also in the game's Settings menu.");
			_style = config.Bind<TerminalStyle>("Terminal", "Style", TerminalStyle.Modern, "How the terminal looks: Modern draws the moons list and the store as tables, with weather colors and bonus icons. Compact is Modern with smaller text, so more fits, and Retro is Modern in capitals. Classic is TerminalFormatter's own pages in the game's text. It's also in the game's Settings menu.");
			_theme.SettingChanged += delegate
			{
				Restyle();
			};
			_style.SettingChanged += delegate
			{
				Restyle();
			};
			h.PatchAll(typeof(TerminalLook));
			SettingsRows.Add<TerminalTheme>(h, "Terminal theme:", _theme);
			SettingsRows.Add<TerminalStyle>(h, "Terminal style:", _style);
		}

		private static Color Rgb(float r, float g, float b)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return new Color(r, g, b, 1f);
		}

		private static Color WithAlpha(Color color, float alpha)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_0013: Unknown result type (might be due to invalid IL or missing references)
			return new Color(color.r, color.g, color.b, alpha);
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		[HarmonyPatch(typeof(Terminal), "Start")]
		private static void ReadGameLook(Terminal __instance)
		{
			//IL_0282: 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_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			_terminal = __instance;
			Parts.Clear();
			TMP_InputField screenText = __instance.screenText;
			AddPart((Graphic)(object)screenText.textComponent, (TerminalPalette palette) => palette.Text);
			AddPart(screenText.placeholder, (TerminalPalette palette) => palette.Text);
			AddPart((Graphic)(object)__instance.topRightText, (TerminalPalette palette) => palette.Text);
			if ((Object)(object)__instance.topRightText != (Object)null)
			{
				AddPart((Graphic)(object)((Component)((TMP_Text)__instance.topRightText).transform.parent).GetComponent<Image>(), (TerminalPalette palette) => palette.Dark);
			}
			if ((Object)(object)__instance.scrollBarVertical != (Object)null)
			{
				AddPart((Graphic)(object)((Component)__instance.scrollBarVertical).GetComponent<Image>(), (TerminalPalette palette) => palette.Dark);
				AddPart((Graphic)(object)(((Object)(object)__instance.scrollBarVertical.handleRect != (Object)null) ? ((Component)__instance.scrollBarVertical.handleRect).GetComponent<Image>() : null), (TerminalPalette palette) => palette.Dark);
			}
			Transform val = (((Object)(object)__instance.terminalUIScreen != (Object)null) ? ((Component)__instance.terminalUIScreen).transform.Find("MainContainer") : null);
			if ((Object)(object)val != (Object)null)
			{
				Transform obj = val.Find("BlackCover");
				AddPart((obj != null) ? ((Component)obj).GetComponent<Graphic>() : null, (TerminalPalette palette) => palette.Background);
				Transform obj2 = val.Find("CodeBroadcastAnim/Image");
				AddPart((obj2 != null) ? ((Component)obj2).GetComponent<Graphic>() : null, (TerminalPalette palette) => palette.Dark);
				Transform obj3 = val.Find("CodeBroadcastAnim/Icon");
				AddPart((obj3 != null) ? ((Component)obj3).GetComponent<Graphic>() : null, (TerminalPalette palette) => palette.Text);
				Transform obj4 = val.Find("CodeBroadcastAnim/Text (TMP)");
				AddPart((obj4 != null) ? ((Component)obj4).GetComponent<Graphic>() : null, (TerminalPalette palette) => palette.Text);
			}
			_caret = screenText.caretColor;
			_selection = screenText.selectionColor;
			_light = (((Object)(object)__instance.terminalLight != (Object)null) ? __instance.terminalLight.color : Color.white);
			_fontSize = screenText.textComponent.fontSize;
			Graphic placeholder = screenText.placeholder;
			TMP_Text val2 = (TMP_Text)(object)((placeholder is TMP_Text) ? placeholder : null);
			_placeholderSize = ((val2 != null) ? val2.fontSize : _fontSize);
			_lineSpacing = screenText.textComponent.lineSpacing;
			_letterSpacing = screenText.textComponent.characterSpacing;
			_fontStyle = screenText.textComponent.fontStyle;
			Restyle();
		}

		private static void AddPart(Graphic graphic, Func<TerminalPalette, Color> themed)
		{
			//IL_001c: 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)
			if ((Object)(object)graphic != (Object)null)
			{
				Parts.Add(new Part
				{
					Graphic = graphic,
					Original = graphic.color,
					Themed = themed
				});
			}
		}

		private static void Restyle()
		{
			//IL_0075: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_terminal == (Object)null)
			{
				return;
			}
			try
			{
				bool flag = _theme.Value == TerminalTheme.Original;
				TerminalPalette palette = Palette;
				foreach (Part part in Parts)
				{
					if ((Object)(object)part.Graphic != (Object)null)
					{
						part.Graphic.color = (flag ? part.Original : WithAlpha(part.Themed(palette), part.Original.a));
					}
				}
				TMP_InputField screenText = _terminal.screenText;
				screenText.customCaretColor = true;
				screenText.caretColor = (flag ? _caret : WithAlpha(palette.Text, _caret.a));
				screenText.selectionColor = (flag ? _selection : WithAlpha(palette.Dark, _selection.a));
				if ((Object)(object)_terminal.terminalLight != (Object)null)
				{
					_terminal.terminalLight.color = (flag ? _light : palette.Light);
				}
				float num = 1f;
				float num2 = _lineSpacing;
				float num3 = _letterSpacing;
				FontStyles val = _fontStyle;
				switch (_style.Value)
				{
				case TerminalStyle.Compact:
					num = 0.85f;
					num2 += -8f;
					break;
				case TerminalStyle.Retro:
					val = (FontStyles)(val | 0x10);
					num3 += 2f;
					break;
				}
				TMP_Text textComponent = screenText.textComponent;
				textComponent.fontSize = _fontSize * num;
				textComponent.lineSpacing = num2;
				textComponent.characterSpacing = num3;
				textComponent.fontStyle = val;
				Graphic placeholder = screenText.placeholder;
				TMP_Text val2 = (TMP_Text)(object)((placeholder is TMP_Text) ? placeholder : null);
				if (val2 != null)
				{
					val2.fontSize = _placeholderSize * num;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("TerminalLook: couldn't restyle the terminal: " + ex.Message));
			}
		}
	}
	internal enum TerminalQualityLevel
	{
		Normal,
		High,
		Max
	}
	internal static class TerminalQuality
	{
		private const float HighScale = 1.5f;

		private static ConfigEntry<TerminalQualityLevel> _level;

		private static int _normalWidth;

		private static int _normalHeight;

		internal static void Apply(Harmony h, ConfigFile config)
		{
			bool num = !File.Exists(config.ConfigFilePath);
			_level = config.Bind<TerminalQualityLevel>("Terminal", "Quality", TerminalQualityLevel.Normal, "How sharp the terminal is drawn. Normal is the game's own size, High is 1.5 times that, and Max matches your screen's height. Higher costs more frames while the terminal is open. It's also in the game's Settings menu.");
			if (num)
			{
				CarryOverFromBaconFixer();
			}
			h.PatchAll(typeof(TerminalQuality));
			SettingsRows.Add<TerminalQualityLevel>(h, "Terminal quality:", _level);
		}

		private static void CarryOverFromBaconFixer()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			string text = Path.Combine(Paths.ConfigPath, "baconfixer.cfg");
			if (File.Exists(text))
			{
				ConfigFile val = new ConfigFile(text, false)
				{
					SaveOnConfigSet = false
				};
				_level.Value = val.Bind<TerminalQualityLevel>("Terminal", "Quality", _level.Value, (ConfigDescription)null).Value;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Terminal), "BeginUsingTerminal")]
		private static void Sharpen(Terminal __instance)
		{
			RenderTexture playerScreenTexHighRes = __instance.playerScreenTexHighRes;
			if (_normalHeight == 0)
			{
				_normalWidth = ((Texture)playerScreenTexHighRes).width;
				_normalHeight = ((Texture)playerScreenTexHighRes).height;
			}
			SetSize(playerScreenTexHighRes, ChosenScale());
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Terminal), "QuitTerminal")]
		private static void PutBackOnQuit(Terminal __instance)
		{
			PutBack(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Terminal), "Start")]
		private static void PutBackOnStart(Terminal __instance)
		{
			PutBack(__instance);
		}

		private static void PutBack(Terminal terminal)
		{
			if (_normalHeight != 0)
			{
				SetSize(terminal.playerScreenTexHighRes, 1f);
			}
		}

		private static float ChosenScale()
		{
			float num = Mathf.Max(1f, (float)Screen.height / (float)_normalHeight);
			return _level.Value switch
			{
				TerminalQualityLevel.High => Mathf.Min(1.5f, num), 
				TerminalQualityLevel.Max => num, 
				_ => 1f, 
			};
		}

		private static void SetSize(RenderTexture texture, float scale)
		{
			int num = Mathf.RoundToInt((float)_normalWidth * scale);
			int num2 = Mathf.RoundToInt((float)_normalHeight * scale);
			if (((Texture)texture).width != num || ((Texture)texture).height != num2)
			{
				texture.Release();
				((Texture)texture).width = num;
				((Texture)texture).height = num2;
			}
		}
	}
	internal static class WeatherLook
	{
		internal const string ValueIcon = "$";

		internal const string AmountIcon = "▪";

		private static readonly Dictionary<string, string> Colors = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			{ "Rainy", "#5EA8FF" },
			{ "Stormy", "#B48CFF" },
			{ "Foggy", "#B8C2CC" },
			{ "Flooded", "#3FD6C8" },
			{ "Eclipsed", "#FF4D4D" },
			{ "DustClouds", "#D9B27C" },
			{ "Dust Clouds", "#D9B27C" },
			{ "Earthquakes", "#C99A5B" },
			{ "Forsaken", "#E0405A" },
			{ "Hallowed", "#FF9A3C" },
			{ "Hurricane", "#7FD4FF" },
			{ "Minefield", "#FF7A45" },
			{ "Blackout", "#9A9AB0" },
			{ "Snowfall", "#E6F2FF" },
			{ "Blizzard", "#CFE8FF" },
			{ "Heatwave", "#FFB347" },
			{ "Toxic Smog", "#A8E05F" },
			{ "Meteor Shower", "#FFC857" },
			{ "Solar Flare", "#FFE066" }
		};

		internal static string Colored(SelectableLevel level, string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return name;
			}
			return "<color=" + ColorOf(level, name) + ">" + name + "</color>";
		}

		internal static string ColorOf(SelectableLevel level, string name)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			string[] array = name.Split('+', '>', '/');
			foreach (string text in array)
			{
				if (Colors.TryGetValue(text.Trim(), out var value))
				{
					return value;
				}
			}
			if (Chainloader.PluginInfos.ContainsKey("mrov.WeatherRegistry") && RegistryWeather.TryGetColor(level, out var color))
			{
				return "#" + ColorUtility.ToHtmlStringRGB(color);
			}
			return TerminalLook.Palette.Danger;
		}

		internal static string BonusIcons(float value, float amount)
		{
			TerminalPalette palette = TerminalLook.Palette;
			List<string> list = new List<string>(2);
			int num = Percent(value);
			int num2 = Percent(amount);
			if (num != 0)
			{
				list.Add(string.Format("<color={0}>{1}{2:+0;-0}%</color>", palette.Money, "$", num));
			}
			if (num2 != 0)
			{
				list.Add(string.Format("<color={0}>{1}{2:+0;-0}%</color>", palette.Info, "▪", num2));
			}
			return string.Join(" ", list);
		}

		private static int Percent(float multiplier)
		{
			return (int)Math.Round((multiplier - 1f) * 100f, MidpointRounding.AwayFromZero);
		}
	}
	internal static class WeatherMultiplierDisplay
	{
		private static readonly Dictionary<string, string> Info = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			{ "Rainy", "Mud slows you down, watch for quicksand." },
			{ "Foggy", "Thick fog, very low visibility outside." },
			{ "Stormy", "Lightning strikes metal items outside." },
			{ "Flooded", "Water rises during the day, can drown." },
			{ "Eclipsed", "Many more enemies spawn from the start." },
			{ "DustClouds", "Dust storm, low visibility outside." },
			{ "Dust Clouds", "Dust storm, low visibility outside." },
			{ "Earthquakes", "Roof collapses inside crush players." },
			{ "Forsaken", "Blood rain. Wail inside, Emma at 2PM." },
			{ "Hallowed", "Scrap heads bite for 99, new enemies." },
			{ "Hurricane", "Falling trees deal 50 and knock back." },
			{ "Minefield", "Beeping mines outside. Blasts can kill." }
		};

		private const int LongWeatherName = 16;

		private const string GameRulesGuid = "bacongamerules";

		private static MethodInfo _resolveRoute;

		private static MethodInfo _resolveRouteAfter;

		private static bool _weatherRegistry;

		private static bool _bonusesInList;

		private const int ModernLabelWidth = 13;

		private const string ModernValueIndent = "7.5em";

		private static readonly string ModernInfoTitle = "<alpha=#99> ═══ MOON INFO " + new string('═', 32) + "<alpha=#FF>";

		internal static void Apply(Harmony h)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			_weatherRegistry = Chainloader.PluginInfos.ContainsKey("mrov.WeatherRegistry");
			if (_weatherRegistry && Chainloader.PluginInfos.TryGetValue("mrov.TerminalUtils", out var value) && value.Instance != null)
			{
				Type type = ((object)value.Instance).GetType().Assembly.GetType("TerminalUtils.Utils.GetWeatherName", throwOnError: false);
				MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "GetWeather", new Type[2]
				{
					typeof(SelectableLevel),
					typeof(bool)
				}, (Type[])null));
				if (methodInfo != null)
				{
					h.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(WeatherMultiplierDisplay), "WeatherNamePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					_bonusesInList = true;
				}
			}
			if (Chainloader.PluginInfos.TryGetValue("TerminalFormatter", out var value2) && value2.Instance != null)
			{
				Assembly assembly = ((object)value2.Instance).GetType().Assembly;
				_resolveRoute = PatchRoutePage(h, assembly.GetType("TerminalFormatter.Nodes.Route", throwOnError: false), "RoutePostfix");
				_resolveRouteAfter = PatchRoutePage(h, assembly.GetType("TerminalFormatter.Nodes.RouteAfter", throwOnError: false), "RouteAfterPostfix");
				TerminalHelp.MoonPagesAdded = _resolveRoute != null || _resolveRouteAfter != null;
				Type type2 = assembly.GetType("TerminalFormatter.Nodes.Moons", throwOnError: false);
				MethodInfo methodInfo2 = ((type2 == null) ? null : AccessTools.Method(type2, "GetNodeText", new Type[1] { typeof(TerminalNode) }, (Type[])null));
				if (methodInfo2 != null)
				{
					h.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(WeatherMultiplierDisplay), "MoonsPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			if (TerminalHelp.MoonPagesAdded || _bonusesInList)
			{
				Plugin.Log.LogInfo((object)(_weatherRegistry ? "WeatherMultiplierDisplay: weather multipliers + info shown in terminal" : "WeatherMultiplierDisplay: moon info shown in terminal, without weather bonuses because WeatherRegistry isn't installed"));
			}
		}

		private static MethodInfo PatchRoutePage(Harmony h, Type t, string postfix)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			if (t == null)
			{
				return null;
			}
			MethodInfo methodInfo = AccessTools.Method(t, "GetNodeText", new Type[1] { typeof(TerminalNode) }, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(t, "ResolveNodeIntoRoute", new Type[1] { typeof(TerminalNode) }, (Type[])null);
			if (methodInfo == null || methodInfo2 == null)
			{
				return null;
			}
			h.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(WeatherMultiplierDisplay), postfix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			return methodInfo2;
		}

		private static string F(float v)
		{
			return v.ToString("0.##", CultureInfo.InvariantCulture);
		}

		private static bool NotOne(float v)
		{
			return Math.Abs(v - 1f) > 0.001f;
		}

		private static float GameRulesFactor(string property)
		{
			if (!Chainloader.PluginInfos.TryGetValue("bacongamerules", out var value) || value.Instance == null)
			{
				return 1f;
			}
			object obj = (((object)value.Instance).GetType().Assembly.GetType("BaconGameRules.GameSetup", throwOnError: false)?.GetProperty(property, BindingFlags.Static | BindingFlags.Public))?.GetValue(null);
			if (obj is float)
			{
				return (float)obj;
			}
			return 1f;
		}

		private static bool TodaysWeather(SelectableLevel level, out string name, out float value, out float amount)
		{
			string shortName;
			if (_weatherRegistry)
			{
				return RegistryWeather.TryGet(level, out name, out shortName, out value, out amount);
			}
			name = ((object)Unsafe.As<LevelWeatherType, LevelWeatherType>(ref level.currentWeather)/*cast due to .constrained prefix*/).ToString();
			value = (amount = 1f);
			return true;
		}

		internal static string BonusText(float value, float amount)
		{
			List<string> list = new List<string>(2);
			AddPercent(list, "value", value);
			AddPercent(list, "items", amount);
			return string.Join(" ", list);
		}

		private static void AddPercent(List<string> parts, string label, float multiplier)
		{
			int num = (int)Math.Round((multiplier - 1f) * 100f, MidpointRounding.AwayFromZero);
			if (num != 0)
			{
				parts.Add(label + num.ToString("+0;-0", CultureInfo.InvariantCulture) + "%");
			}
		}

		private static void WeatherNamePostfix(SelectableLevel level, ref string __result)
		{
			try
			{
				if (!string.IsNullOrEmpty(__result) && RegistryWeather.TryGet(level, out var _, out var shortName, out var value, out var amount))
				{
					string text = WeatherLook.Colored(level, (__result.Length >= 16) ? shortName : __result);
					if (TerminalLook.ModernPages)
					{
						string text2 = WeatherLook.BonusIcons(value, amount);
						__result = ((text2.Length > 0) ? (text + " " + text2) : text);
						return;
					}
					string text3 = BonusText(value, amount);
					__result = ((text3.Length > 0) ? (text + " <size=70%><color=" + TerminalLook.Palette.Good + ">" + text3 + "</color></size>") : text);
				}
			}
			catch
			{
			}
		}

		private static void MoonsPostfix(ref string __result)
		{
			if (TerminalLook.DrewModernPage)
			{
				return;
			}
			__result = RouteDetails.NameSellingMoons(__result);
			if (_bonusesInList)
			{
				int num = __result.IndexOf("Buying at", StringComparison.Ordinal);
				int num2 = ((num < 0) ? (-1) : __result.IndexOf('\n', num));
				string text = (TerminalHelp.SortBonusAdded ? " Type SORT BONUS for the best-paying moons." : "");
				if (num2 >= 0)
				{
					__result = __result.Insert(num2 + 1, " <size=70%>Weather bonus: value = what scrap sells for, items = how much spawns." + text + "</size>\n");
				}
			}
		}

		private static void RoutePostfix(object __instance, TerminalNode node, ref string __result)
		{
			AppendInfo(__instance, _resolveRoute, node, ref __result);
		}

		private static void RouteAfterPostfix(object __instance, TerminalNode node, ref string __result)
		{
			AppendInfo(__instance, _resolveRouteAfter, node, ref __result);
		}

		private static void AppendInfo(object instance, MethodInfo resolve, TerminalNode node, ref string text)
		{
			try
			{
				if (resolve == null || string.IsNullOrEmpty(text))
				{
					return;
				}
				object? obj = resolve.Invoke(instance, new object[1] { node });
				SelectableLevel val = ((Route)(((obj is Route) ? obj : null)?)).Level;
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				int num;
				if (TodaysWeather(val, out var name, out var value, out var amount))
				{
					num = ((!string.Equals(name, "None", StringComparison.OrdinalIgnoreCase)) ? 1 : 0);
					if (num != 0)
					{
						goto IL_0073;
					}
				}
				else
				{
					num = 0;
				}
				value = (amount = 1f);
				goto IL_0073;
				IL_0073:
				List<string> list = new List<string>();
				if (num != 0 && _weatherRegistry)
				{
					if (NotOne(value) || NotOne(amount))
					{
						List<string> list2 = new List<string>();
						if (NotOne(value))
						{
							list2.Add("items worth x" + F(value));
						}
						if (NotOne(amount))
						{
							list2.Add("x" + F(amount) + " more items");
						}
						list.Add(Colored(TerminalLook.Palette.Good, "SCRAP BONUS: " + string.Join(", ", list2)));
					}
					else
					{
						list.Add(Colored(TerminalLook.Palette.Good, "SCRAP BONUS: none"));
					}
				}
				list.Add(Colored(TerminalLook.Palette.Good, RouteDetails.Selling(val)));
				if (val.spawnEnemiesAndScrap)
				{
					list.Add(Colored(TerminalLook.Palette.Money, RouteDetails.Loot(val, value * GameRulesFactor("ScrapValueFactor"), amount * GameRulesFactor("ScrapAmountFactor"))));
					if (LevelLoaderDetails.Installed)
					{
						list.Add(Colored(TerminalLook.Palette.Info, LevelLoaderDetails.Interiors(val)));
					}
				}
				list.Add(Colored(TerminalLook.Palette.Time, RouteDetails.DayLength(val)));
				if (num != 0)
				{
					list.Add(Colored(TerminalLook.Palette.Danger, DangerLine(name)));
				}
				list.RemoveAll(string.IsNullOrEmpty);
				if (list.Count > 0 && TerminalLook.ModernPages)
				{
					list.Insert(0, ModernInfoTitle);
				}
				if (list.Count > 0)
				{
					text = text.TrimEnd() + "\n\n" + string.Join("\n", list) + "\n\n";
				}
			}
			catch
			{
			}
		}

		private static string DangerLine(string weatherName)
		{
			List<string> list = (from part in weatherName.Split('+', '>')
				select part.Trim()).Where(Info.ContainsKey).ToList();
			if (list.Count == 0)
			{
				return null;
			}
			return "DANGER: " + ((list.Count == 1) ? Info[list[0]] : string.Join(" ", list.Select((string part) => part + ": " + Info[part])));
		}

		private static string Colored(string color, string line)
		{
			int num = line?.IndexOf(':') ?? (-1);
			if (num < 0)
			{
				return line;
			}
			if (TerminalLook.ModernPages)
			{
				return "  <color=" + color + ">" + line.Substring(0, num).PadRight(13) + "</color><indent=7.5em>" + line.Substring(num + 1).TrimStart() + "</indent>";
			}
			return "<color=" + color + ">" + line.Substring(0, num + 1) + "</color>" + line.Substring(num + 1);
		}
	}
}