Decompiled source of RouteRandom v1.3.2

RouteRandom.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RouteRandom.Helpers;
using TMPro;
using UnityEngine;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("RouteRandom")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Route Random adds a couple commands for routing to a random moon, including modded moons. 'route random' will get a random moon. 'route randomfilterweather' will get a random moon, filtering out disallowed weathers")]
[assembly: AssemblyFileVersion("1.3.2.0")]
[assembly: AssemblyInformationalVersion("1.3.2+b39d9e3de8ab4e532a843dadf969a9865daf1154")]
[assembly: AssemblyProduct("RouteRandom")]
[assembly: AssemblyTitle("RouteRandom")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 RouteRandom
{
	[BepInPlugin("stormytuna.RouteRandom", "RouteRandom", "1.3.2")]
	public class RouteRandomBase : BaseUnityPlugin
	{
		public const string ModGuid = "stormytuna.RouteRandom";

		public const string ModName = "RouteRandom";

		public const string ModVersion = "1.3.2";

		public static readonly ManualLogSource Log = Logger.CreateLogSource("stormytuna.RouteRandom");

		private readonly Harmony harmony = new Harmony("stormytuna.RouteRandom");

		public static ConfigEntry<bool> ConfigAllowMildWeather;

		public static ConfigEntry<bool> ConfigAllowDustCloudsWeather;

		public static ConfigEntry<bool> ConfigAllowRainyWeather;

		public static ConfigEntry<bool> ConfigAllowStormyWeather;

		public static ConfigEntry<bool> ConfigAllowFoggyWeather;

		public static ConfigEntry<bool> ConfigAllowFloodedWeather;

		public static ConfigEntry<bool> ConfigAllowEclipsedWeather;

		public static ConfigEntry<bool> ConfigAllowCostlyPlanets;

		public static ConfigEntry<bool> ConfigRemoveCostOfCostlyPlanets;

		public static ConfigEntry<bool> ConfigSkipConfirmation;

		public static ConfigEntry<bool> ConfigDifferentPlanetEachTime;

		public static ConfigEntry<bool> ConfigHidePlanet;

		private void Awake()
		{
			Log.LogInfo((object)"RouteRandom has awoken!");
			LoadConfigs();
			harmony.PatchAll();
		}

		private void LoadConfigs()
		{
			ConfigAllowMildWeather = ((BaseUnityPlugin)this).Config.Bind<bool>("Allowed Weathers", "AllowMildWeather", true, "Whether or not to allow the 'Mild' weather to be chosen by the 'route randomfilterweather' command");
			ConfigAllowDustCloudsWeather = ((BaseUnityPlugin)this).Config.Bind<bool>("Allowed Weathers", "AllowDustCloudsWeather", false, "Whether or not to allow the 'Dust Clouds' weather to be chosen by the 'route randomfilterweather' command");
			ConfigAllowRainyWeather = ((BaseUnityPlugin)this).Config.Bind<bool>("Allowed Weathers", "AllowRainyWeather", false, "Whether or not to allow the 'Rainy' weather to be chosen by the 'route randomfilterweather' command");
			ConfigAllowStormyWeather = ((BaseUnityPlugin)this).Config.Bind<bool>("Allowed Weathers", "AllowStormyWeather", false, "Whether or not to allow the 'Stormy' weather to be chosen by the 'route randomfilterweather' command");
			ConfigAllowFoggyWeather = ((BaseUnityPlugin)this).Config.Bind<bool>("Allowed Weathers", "AllowFoggyWeather", false, "Whether or not to allow the 'Foggy' weather to be chosen by the 'route randomfilterweather' command");
			ConfigAllowFloodedWeather = ((BaseUnityPlugin)this).Config.Bind<bool>("Allowed Weathers", "AllowFloodedWeather", false, "Whether or not to allow the 'Flooded' weather to be chosen by the 'route randomfilterweather' command");
			ConfigAllowEclipsedWeather = ((BaseUnityPlugin)this).Config.Bind<bool>("Allowed Weathers", "AllowEclipsedWeather", false, "Whether or not to allow the 'Eclipsed' weather to be chosen by the 'route randomfilterweather' command");
			ConfigAllowCostlyPlanets = ((BaseUnityPlugin)this).Config.Bind<bool>("Costly Planets", "AllowCostlyPlanets", false, "Whether or not to allow costly planets (85-Rend, 7-Dine, 8-Titan). NOTE: You will still be prompted to pay the fee to fly there, enable the MakeCostlyPlanetsFree option to avoid that");
			ConfigRemoveCostOfCostlyPlanets = ((BaseUnityPlugin)this).Config.Bind<bool>("Costly Planets", "RemoveCostOfCostlyPlanets", false, "Whether or not to remove the cost of costly planets when they're chosen randomly and allows them to be chosen even when AllowCostlyPlanets is false");
			ConfigSkipConfirmation = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SkipConfirmation", false, "Whether or not to skip the confirmation screen when using 'route random' or 'route randomwithweather' commands");
			ConfigDifferentPlanetEachTime = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DifferentPlanetEachTime", false, "Prevents 'route random' and 'route randomwithweather' commands from choosing the same planet you're on");
			ConfigHidePlanet = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "HidePlanet", false, "Hides the planet you get randomly routed to, both in the terminal response and at the helm. NOTE: This will ALWAYS hide the orbited planet (even when selected manually) and will skip the confirmation screen");
		}
	}
}
namespace RouteRandom.Patches
{
	[HarmonyPatch(typeof(StartOfRound))]
	public class StartOfRoundPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("SetMapScreenInfoToCurrentLevel")]
		public static void HideMapScreenInfo(StartOfRound __instance, VideoPlayer ___screenLevelVideoReel, TextMeshProUGUI ___screenLevelDescription)
		{
			if (!(((Object)__instance.currentLevel).name == "CompanyBuildingLevel") && RouteRandomBase.ConfigHidePlanet.Value)
			{
				((TMP_Text)___screenLevelDescription).text = "Orbiting: [REDACTED]\nPopulation: Unknown\nConditions: Unknown\nFauna: Unknown\nWeather: Unknown";
				((Behaviour)___screenLevelVideoReel).enabled = false;
				___screenLevelVideoReel.clip = null;
				((Component)___screenLevelVideoReel).gameObject.SetActive(false);
				___screenLevelVideoReel.Stop();
			}
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	public class TerminalPatch
	{
		private static readonly TerminalNode noSuitablePlanetsNode = new TerminalNode
		{
			name = "NoSuitablePlanets",
			displayText = "\nNo suitable planets found.\nConsider route random.\n\n\n",
			clearPreviousText = true
		};

		private static readonly TerminalNode hidePlanetHackNode = new TerminalNode
		{
			name = "HidePlanetHack",
			displayText = "\nRouting autopilot to [REDACTED].\nYour new balance is [playerCredits].\n\nPlease enjoy your flight.\n\n\n",
			clearPreviousText = true
		};

		private static TerminalKeyword routeKeyword;

		private static TerminalKeyword randomKeyword;

		private static TerminalKeyword randomFilterWeatherKeyword;

		private static CompatibleNoun routeRandomCompatibleNoun;

		private static CompatibleNoun routeRandomFilterWeatherCompatibleNoun;

		private static readonly Random rand = new Random();

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		public static void AddNewTerminalWords(Terminal __instance)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00be: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_00fc: Expected O, but got Unknown
			try
			{
				routeKeyword = __instance.GetKeyword("Route");
				randomKeyword = new TerminalKeyword
				{
					word = "random",
					name = "Random",
					defaultVerb = routeKeyword,
					compatibleNouns = Array.Empty<CompatibleNoun>()
				};
				randomFilterWeatherKeyword = new TerminalKeyword
				{
					word = "randomfilterweather",
					name = "RandomFilterWeather",
					defaultVerb = routeKeyword,
					compatibleNouns = Array.Empty<CompatibleNoun>()
				};
				routeRandomCompatibleNoun = new CompatibleNoun
				{
					noun = randomKeyword,
					result = new TerminalNode
					{
						name = "routeRandom",
						buyRerouteToMoon = -1,
						terminalOptions = Array.Empty<CompatibleNoun>()
					}
				};
				routeRandomFilterWeatherCompatibleNoun = new CompatibleNoun
				{
					noun = randomFilterWeatherKeyword,
					result = new TerminalNode
					{
						name = "routeRandomFilterWeather",
						buyRerouteToMoon = -1,
						terminalOptions = Array.Empty<CompatibleNoun>()
					}
				};
				TerminalKeyword keyword = __instance.GetKeyword("Moons");
				TerminalNode specialKeywordResult = keyword.specialKeywordResult;
				specialKeywordResult.displayText += "* Random   //   Routes you to a random moon, regardless of weather conditions\n* RandomFilterWeather   //   Routes you to a random moon, filtering out disallowed weather conditions\n\n";
				__instance.AddKeywords(randomKeyword, randomFilterWeatherKeyword);
				__instance.AddCompatibleNounsToKeyword("Route", routeRandomCompatibleNoun, routeRandomFilterWeatherCompatibleNoun);
			}
			catch (Exception ex)
			{
				RouteRandomBase.Log.LogError((object)"Failed to add Terminal keywords and compatible nouns!");
				RouteRandomBase.Log.LogError((object)ex);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("ParsePlayerSentence")]
		public static TerminalNode RouteToRandomPlanet(TerminalNode __result, Terminal __instance)
		{
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			if (__result == null || __instance == null)
			{
				RouteRandomBase.Log.LogInfo((object)$"Terminal node was null? ({__result == null})");
				RouteRandomBase.Log.LogInfo((object)$"Terminal was null? ({__instance == null})");
				return __result;
			}
			bool flag = ((Object)__result).name == "routeRandom";
			bool flag2 = ((Object)__result).name == "routeRandomFilterWeather";
			if (!flag && !flag2)
			{
				RouteRandomBase.Log.LogInfo((object)("Didn't choose random or randomfilterweather (chose " + ((Object)__result).name + ")"));
				return __result;
			}
			List<CompatibleNoun> list = routeKeyword.compatibleNouns.Where((CompatibleNoun noun) => noun.ResultIsRealMoon() && noun.ResultIsAffordable()).Distinct(new CompatibleNounComparer()).ToList();
			RouteRandomBase.Log.LogInfo((object)$"Moons before filtering: {list.Count}");
			if (flag2)
			{
				foreach (CompatibleNoun item in list.ToList())
				{
					TerminalNode nodeAfterConfirmation = item.result.GetNodeAfterConfirmation();
					SelectableLevel val = StartOfRound.Instance.levels[nodeAfterConfirmation.buyRerouteToMoon];
					if (!WeatherIsAllowed(val.currentWeather))
					{
						list.Remove(item);
					}
				}
				RouteRandomBase.Log.LogInfo((object)$"Moons after filtering weather: {list.Count}");
			}
			if (RouteRandomBase.ConfigDifferentPlanetEachTime.Value)
			{
				list.RemoveAll((CompatibleNoun rpn) => rpn.result.GetNodeAfterConfirmation().NodeRoutesToCurrentOrbitedMoon());
				RouteRandomBase.Log.LogInfo((object)$"Moons after filtering orbited moon: {list.Count}");
			}
			if (list.Count <= 0)
			{
				RouteRandomBase.Log.LogInfo((object)"No suitable moons found D:");
				return noSuitablePlanetsNode;
			}
			TerminalNode val2 = rand.NextFromCollection(list).result;
			RouteRandomBase.Log.LogInfo((object)("Chosen moon: " + ((Object)val2).name));
			if (RouteRandomBase.ConfigRemoveCostOfCostlyPlanets.Value)
			{
				if (TerminalHelper.TryMakeRouteMoonNodeFree(val2, out var freeMoonNode))
				{
					val2 = freeMoonNode;
				}
				RouteRandomBase.Log.LogInfo((object)"Made moon free!");
			}
			if (RouteRandomBase.ConfigHidePlanet.Value)
			{
				TerminalNode nodeAfterConfirmation2 = val2.GetNodeAfterConfirmation();
				hidePlanetHackNode.buyRerouteToMoon = nodeAfterConfirmation2.buyRerouteToMoon;
				hidePlanetHackNode.itemCost = ((!RouteRandomBase.ConfigRemoveCostOfCostlyPlanets.Value) ? nodeAfterConfirmation2.itemCost : 0);
				RouteRandomBase.Log.LogInfo((object)"Hidden moon!");
				return hidePlanetHackNode;
			}
			return RouteRandomBase.ConfigSkipConfirmation.Value ? val2.GetNodeAfterConfirmation() : val2;
		}

		private static bool WeatherIsAllowed(LevelWeatherType weatherType)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected I4, but got Unknown
			if (1 == 0)
			{
			}
			bool result = (weatherType - -1) switch
			{
				0 => RouteRandomBase.ConfigAllowMildWeather.Value, 
				1 => RouteRandomBase.ConfigAllowDustCloudsWeather.Value, 
				2 => RouteRandomBase.ConfigAllowRainyWeather.Value, 
				3 => RouteRandomBase.ConfigAllowStormyWeather.Value, 
				4 => RouteRandomBase.ConfigAllowFoggyWeather.Value, 
				5 => RouteRandomBase.ConfigAllowFloodedWeather.Value, 
				6 => RouteRandomBase.ConfigAllowEclipsedWeather.Value, 
				_ => false, 
			};
			if (1 == 0)
			{
			}
			return result;
		}
	}
	internal class CompatibleNounComparer : EqualityComparer<CompatibleNoun>
	{
		public override bool Equals(CompatibleNoun x, CompatibleNoun y)
		{
			return x != null && ((Object)x.result).name.Equals((y != null) ? ((Object)y.result).name : null, StringComparison.InvariantCultureIgnoreCase);
		}

		public override int GetHashCode(CompatibleNoun obj)
		{
			return ((object)obj.result).GetHashCode();
		}
	}
}
namespace RouteRandom.Helpers
{
	public static class RandomHelper
	{
		public static TSource NextFromCollection<TSource>(this Random rand, List<TSource> collection)
		{
			int index = rand.Next(collection.Count);
			return collection[index];
		}
	}
	public static class TerminalHelper
	{
		public static TerminalKeyword GetKeyword(this Terminal terminal, string keywordName)
		{
			return terminal.terminalNodes.allKeywords.First((TerminalKeyword kw) => ((Object)kw).name == keywordName);
		}

		public static TerminalNode GetNodeAfterConfirmation(this TerminalNode node)
		{
			return node.terminalOptions.First((CompatibleNoun cn) => ((Object)cn.noun).name == "Confirm").result;
		}

		public static bool NodeRoutesToCurrentOrbitedMoon(this TerminalNode node)
		{
			return (Object)(object)StartOfRound.Instance.levels[node.buyRerouteToMoon] == (Object)(object)StartOfRound.Instance.currentLevel;
		}

		public static void AddKeyword(this Terminal terminal, TerminalKeyword newKeyword)
		{
			terminal.terminalNodes.allKeywords = CollectionExtensions.AddToArray<TerminalKeyword>(terminal.terminalNodes.allKeywords, newKeyword);
		}

		public static void AddKeywords(this Terminal terminal, params TerminalKeyword[] newKeywords)
		{
			foreach (TerminalKeyword newKeyword in newKeywords)
			{
				terminal.AddKeyword(newKeyword);
			}
		}

		public static void AddCompatibleNounToKeyword(this Terminal terminal, string keywordName, CompatibleNoun newCompatibleNoun)
		{
			TerminalKeyword val = ((IEnumerable<TerminalKeyword>)terminal.terminalNodes.allKeywords).FirstOrDefault((Func<TerminalKeyword, bool>)((TerminalKeyword kw) => ((Object)kw).name == keywordName)) ?? throw new ArgumentException("Failed to find keyword with name " + keywordName);
			val.compatibleNouns = CollectionExtensions.AddToArray<CompatibleNoun>(val.compatibleNouns, newCompatibleNoun);
		}

		public static void AddCompatibleNounsToKeyword(this Terminal terminal, string keywordName, params CompatibleNoun[] newCompatibleNouns)
		{
			foreach (CompatibleNoun newCompatibleNoun in newCompatibleNouns)
			{
				terminal.AddCompatibleNounToKeyword(keywordName, newCompatibleNoun);
			}
		}

		public static bool ResultIsRealMoon(this CompatibleNoun compatibleNoun)
		{
			return compatibleNoun.result.buyRerouteToMoon == -2;
		}

		public static bool ResultIsAffordable(this CompatibleNoun compatibleNoun)
		{
			return compatibleNoun.result.itemCost <= 0 || RouteRandomBase.ConfigAllowCostlyPlanets.Value || RouteRandomBase.ConfigRemoveCostOfCostlyPlanets.Value;
		}

		public static bool TryMakeRouteMoonNodeFree(TerminalNode routeMoonNode, out TerminalNode freeMoonNode)
		{
			//IL_0071: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Expected O, but got Unknown
			CompatibleNoun val = ((IEnumerable<CompatibleNoun>)routeMoonNode.terminalOptions).FirstOrDefault((Func<CompatibleNoun, bool>)((CompatibleNoun node) => ((Object)node.noun).name == "Confirm"));
			CompatibleNoun val2 = ((IEnumerable<CompatibleNoun>)routeMoonNode.terminalOptions).FirstOrDefault((Func<CompatibleNoun, bool>)((CompatibleNoun node) => ((Object)node.noun).name == "Deny"));
			if (val == null || val2 == null)
			{
				freeMoonNode = null;
				return false;
			}
			TerminalNode result = new TerminalNode
			{
				name = ((Object)val.result).name + "Free",
				buyRerouteToMoon = val.result.buyRerouteToMoon,
				clearPreviousText = true,
				displayText = val.result.displayText,
				itemCost = 0
			};
			TerminalNode val3 = new TerminalNode();
			((Object)val3).name = ((Object)routeMoonNode).name + "Free";
			val3.buyRerouteToMoon = -2;
			val3.clearPreviousText = true;
			val3.displayPlanetInfo = routeMoonNode.displayPlanetInfo;
			val3.displayText = routeMoonNode.displayText;
			val3.itemCost = 0;
			val3.overrideOptions = true;
			val3.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2]
			{
				val2,
				new CompatibleNoun
				{
					noun = val.noun,
					result = result
				}
			};
			freeMoonNode = val3;
			return true;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}