Decompiled source of ToxcsMoonOfTheDay v1.0.0

ToxcsMoonOfTheDay.dll

Decompiled 5 hours 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.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.AI;

[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("ToxcsMoonOfTheDay")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A mod that adds daily & weekly seeded moons to the game.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ToxcsMoonOfTheDay")]
[assembly: AssemblyTitle("ToxcsMoonOfTheDay")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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 ToxcsMoonOfTheDay
{
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Toxc.MoonOfTheDay";

		public const string PLUGIN_NAME = "ToxcsMoonOfTheDay";

		public const string PLUGIN_VERSION = "1.0.0";
	}
	[BepInPlugin("Toxc.MoonOfTheDay", "ToxcsMoonOfTheDay", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private enum SeedMode
		{
			None,
			Daily,
			Weekly
		}

		private readonly struct CustomRoute
		{
			public int SourceIndex { get; }

			public LevelWeatherType WeatherType { get; }

			public SeedMode SeedMode { get; }

			public CustomRoute(int sourceIndex, LevelWeatherType weatherType, SeedMode seedMode)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				SourceIndex = sourceIndex;
				WeatherType = weatherType;
				SeedMode = seedMode;
			}
		}

		private readonly struct WeatherState
		{
			public bool OverrideWeather { get; }

			public LevelWeatherType OverrideWeatherType { get; }

			public LevelWeatherType CurrentWeather { get; }

			public RandomWeatherWithVariables[] RandomWeathers { get; }

			public WeatherState(bool overrideWeather, LevelWeatherType overrideWeatherType, LevelWeatherType currentWeather, RandomWeatherWithVariables[] randomWeathers)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				OverrideWeather = overrideWeather;
				OverrideWeatherType = overrideWeatherType;
				CurrentWeather = currentWeather;
				RandomWeathers = randomWeathers;
			}
		}

		public const string DailyMoonName = "Daily Moon";

		public const string WeeklyMoonName = "Weekly Moon";

		internal static ManualLogSource Logger;

		private Harmony _harmony;

		private bool _isPatched;

		private static readonly Dictionary<int, CustomRoute> CustomRoutes = new Dictionary<int, CustomRoute>();

		private static readonly Dictionary<SelectableLevel, WeatherState> OriginalWeatherStates = new Dictionary<SelectableLevel, WeatherState>();

		private static SeedMode _activeSeedMode = SeedMode.None;

		public static Plugin Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			PatchAll();
			Logger.LogInfo((object)"Plugin Toxc.MoonOfTheDay (v1.0.0) is loaded!");
		}

		public void PatchAll()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			if (_isPatched)
			{
				Logger.LogWarning((object)"Already patched!");
				return;
			}
			Logger.LogDebug((object)"Patching...");
			_harmony = new Harmony("Toxc.MoonOfTheDay");
			_harmony.PatchAll();
			_isPatched = true;
			Logger.LogDebug((object)"Patched!");
		}

		public void UnpatchAll()
		{
			if (!_isPatched)
			{
				Logger.LogWarning((object)"Not patched!");
				return;
			}
			Logger.LogDebug((object)"Unpatching...");
			_harmony.UnpatchSelf();
			_isPatched = false;
			Logger.LogDebug((object)"Unpatched!");
		}

		public static int GetDailySeed()
		{
			return (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalDays;
		}

		public static int GetWeeklySeed()
		{
			return (int)Math.Floor((float)(int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalDays / 7f);
		}

		public static bool IsCustomMoon(SelectableLevel moon)
		{
			string planetName = moon.PlanetName;
			if (planetName == "Daily Moon" || planetName == "Weekly Moon")
			{
				return true;
			}
			return false;
		}

		private static SelectableLevel GetCustomMoon(SelectableLevel[] moons, int levelID, bool isDailyElseWeekly = true)
		{
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			Random random = new Random(isDailyElseWeekly ? GetDailySeed() : GetWeeklySeed());
			SelectableLevel[] array = moons.Where((SelectableLevel moon) => moon.levelID != 3 && !IsCustomMoon(moon)).ToArray();
			SelectableLevel val = array.OrderBy((SelectableLevel m) => m.levelID).ToArray()[random.Next(0, array.Length)];
			int num = Array.IndexOf(moons, val);
			SelectableLevel val2 = Object.Instantiate<SelectableLevel>(val);
			((Object)val2).name = (isDailyElseWeekly ? "Daily Moon" : "Weekly Moon");
			val2.PlanetName = (isDailyElseWeekly ? "Daily Moon" : "Weekly Moon");
			val2.LevelDescription = "This moon looks familiar...";
			val2.riskLevel = "???";
			val2.levelID = levelID;
			val2.randomWeathers = Array.Empty<RandomWeatherWithVariables>();
			val2.overrideWeather = true;
			LevelWeatherType val3 = (val2.currentWeather = (val2.overrideWeatherType = Enum.GetValues(typeof(LevelWeatherType)).Cast<LevelWeatherType>().ToArray()[random.Next(0, Enum.GetValues(typeof(LevelWeatherType)).Length)]));
			CustomRoutes[levelID] = new CustomRoute(num, val3, isDailyElseWeekly ? SeedMode.Daily : SeedMode.Weekly);
			Logger.LogDebug((object)$"{val2.PlanetName} route index {levelID} maps to {val.PlanetName} at index {num} with {val3} weather.");
			return val2;
		}

		public static SelectableLevel[] WithCustomMoons(SelectableLevel[] moons)
		{
			List<SelectableLevel> list = moons.Where((SelectableLevel moon) => !IsCustomMoon(moon)).ToList();
			SelectableLevel customMoon = GetCustomMoon(list.ToArray(), list.Count);
			SelectableLevel customMoon2 = GetCustomMoon(list.ToArray(), list.Count + 1, isDailyElseWeekly: false);
			list.Add(customMoon);
			list.Add(customMoon2);
			Logger.LogDebug((object)$"Daily moon level index: {customMoon.levelID}; weekly moon level index: {customMoon2.levelID}");
			return list.ToArray();
		}

		public static bool TryResolveCustomRoute(StartOfRound startOfRound, ref int levelID)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			RestoreWeatherState(startOfRound);
			if (!CustomRoutes.TryGetValue(levelID, out var value))
			{
				_activeSeedMode = SeedMode.None;
				return false;
			}
			_activeSeedMode = value.SeedMode;
			levelID = value.SourceIndex;
			if (value.SourceIndex < 0 || value.SourceIndex >= startOfRound.levels.Length)
			{
				Logger.LogError((object)$"Custom route resolved to invalid level index {value.SourceIndex}.");
				return false;
			}
			ApplyWeatherOverride(startOfRound.levels[value.SourceIndex], value.WeatherType);
			Logger.LogDebug((object)$"Resolved custom route to {startOfRound.levels[value.SourceIndex].PlanetName} at index {value.SourceIndex}.");
			return true;
		}

		public static void SetSeedForActiveRoute(StartOfRound startOfRound)
		{
			switch (_activeSeedMode)
			{
			case SeedMode.Daily:
				Logger.LogDebug((object)("Setting daily seed for " + startOfRound.currentLevel.PlanetName + "..."));
				startOfRound.overrideRandomSeed = true;
				startOfRound.overrideSeedNumber = GetDailySeed();
				return;
			case SeedMode.Weekly:
				Logger.LogDebug((object)("Setting weekly seed for " + startOfRound.currentLevel.PlanetName + "..."));
				startOfRound.overrideRandomSeed = true;
				startOfRound.overrideSeedNumber = GetWeeklySeed();
				return;
			}
			if ((Object)(object)startOfRound.currentLevel != (Object)null)
			{
				Logger.LogDebug((object)("Not setting seed for " + startOfRound.currentLevel.PlanetName + "..."));
			}
			startOfRound.overrideRandomSeed = false;
		}

		private static void ApplyWeatherOverride(SelectableLevel level, LevelWeatherType weatherType)
		{
			//IL_0048: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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)
			if (!OriginalWeatherStates.ContainsKey(level))
			{
				OriginalWeatherStates[level] = new WeatherState(level.overrideWeather, level.overrideWeatherType, level.currentWeather, level.randomWeathers);
			}
			level.randomWeathers = Array.Empty<RandomWeatherWithVariables>();
			level.overrideWeather = true;
			level.overrideWeatherType = weatherType;
			level.currentWeather = weatherType;
		}

		private static void RestoreWeatherState(StartOfRound startOfRound)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			KeyValuePair<SelectableLevel, WeatherState>[] array = OriginalWeatherStates.ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				KeyValuePair<SelectableLevel, WeatherState> keyValuePair = array[i];
				if (!startOfRound.levels.Contains(keyValuePair.Key))
				{
					OriginalWeatherStates.Remove(keyValuePair.Key);
					continue;
				}
				keyValuePair.Key.overrideWeather = keyValuePair.Value.OverrideWeather;
				keyValuePair.Key.overrideWeatherType = keyValuePair.Value.OverrideWeatherType;
				keyValuePair.Key.currentWeather = keyValuePair.Value.CurrentWeather;
				keyValuePair.Key.randomWeathers = keyValuePair.Value.RandomWeathers;
				OriginalWeatherStates.Remove(keyValuePair.Key);
			}
		}
	}
}
namespace ToxcsMoonOfTheDay.Patches
{
	public static class PatchRoundManagerHelpers
	{
		public static Vector3 SeededInsideUnitSphere(ref Random random)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			Vector3 result = default(Vector3);
			do
			{
				((Vector3)(ref result))..ctor((float)(random.NextDouble() * 2.0 - 1.0), (float)(random.NextDouble() * 2.0 - 1.0), (float)(random.NextDouble() * 2.0 - 1.0));
			}
			while (((Vector3)(ref result)).sqrMagnitude > 1f);
			return result;
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	public class PatchRoundManager
	{
		[HarmonyPatch("GetRandomNavMeshPositionInRadiusSpherical")]
		[HarmonyPrefix]
		public static bool GetRandomNavMeshPositionInRadiusSpherical(ref RoundManager __instance, ref Vector3 __result, Vector3 pos, float radius = 10f, NavMeshHit navHit = default(NavMeshHit))
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = PatchRoundManagerHelpers.SeededInsideUnitSphere(ref __instance.LevelRandom) * radius + pos;
			NavMeshHit val2 = default(NavMeshHit);
			__result = (NavMesh.SamplePosition(val, ref val2, radius, -1) ? ((NavMeshHit)(ref val2)).position : val);
			return false;
		}

		[HarmonyPatch("GetRandomNavMeshPositionInRadius")]
		[HarmonyPrefix]
		public static bool GetRandomNavMeshPositionInRadius(ref RoundManager __instance, ref Vector3 __result, Vector3 pos, float radius = 10f, NavMeshHit navHit = default(NavMeshHit))
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			float num = ((Vector3)(ref pos))[1];
			Vector3 val = PatchRoundManagerHelpers.SeededInsideUnitSphere(ref __instance.LevelRandom) * radius + pos;
			((Vector3)(ref val))[1] = num;
			NavMeshHit val2 = default(NavMeshHit);
			if (NavMesh.SamplePosition(val, ref val2, radius, -1))
			{
				__result = ((NavMeshHit)(ref val2)).position;
				return false;
			}
			Debug.Log((object)"Unable to get random nav mesh position in radius! Returning old pos");
			__result = val;
			return false;
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	public class PatchStartOfRound
	{
		[HarmonyPatch("ChangeLevel")]
		[HarmonyPrefix]
		public static void ResolveCustomRoute(StartOfRound __instance, ref int levelID)
		{
			Plugin.TryResolveCustomRoute(__instance, ref levelID);
		}

		[HarmonyPatch("StartGame")]
		[HarmonyPrefix]
		public static void SetSeed(StartOfRound __instance)
		{
			if (!((Object)(object)__instance.currentLevel == (Object)null))
			{
				Plugin.SetSeedForActiveRoute(__instance);
			}
		}

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void InsertMoons(StartOfRound __instance)
		{
			Plugin.Logger.LogDebug((object)"Inserting moons in StartOfRound...");
			StartOfRound instance = StartOfRound.Instance;
			instance.levels = Plugin.WithCustomMoons(instance.levels);
		}
	}
	internal static class PatchTerminalHelpers
	{
		public static void AddTerminalCommand(ref Terminal terminal, SelectableLevel moonToAdd)
		{
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Expected O, but got Unknown
			Plugin.Logger.LogDebug((object)("Adding terminal command for " + moonToAdd.PlanetName + "..."));
			TerminalKeyword val = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => ((Object)keyword).name == "Confirm");
			TerminalKeyword denyKeyword = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => ((Object)keyword).name == "Deny");
			TerminalKeyword val2 = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => ((Object)keyword).name == "Route");
			TerminalNode result = val2.compatibleNouns.First().result.terminalOptions.First((CompatibleNoun opt) => (Object)(object)opt.noun == (Object)(object)denyKeyword).result;
			TerminalKeyword val3 = ScriptableObject.CreateInstance<TerminalKeyword>();
			((Object)val3).name = GetKWNameForMoon(moonToAdd);
			val3.word = GetKWWordforMoon(moonToAdd);
			val3.defaultVerb = val2;
			val3.compatibleNouns = Array.Empty<CompatibleNoun>();
			TerminalNode val4 = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)val4).name = GetTravelNodeNameForMoon(moonToAdd);
			val4.displayText = "Routing autopilot to " + moonToAdd.PlanetName + ".\n\nPlease enjoy your flight.";
			val4.clearPreviousText = true;
			val4.buyRerouteToMoon = moonToAdd.levelID;
			TerminalNode val5 = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)val5).name = GetKWNameForMoon(moonToAdd);
			val5.displayText = "The company has detected a rogue planet. It might not be available for long. Do you want to go there?\n\nIt is currently [currentPlanetTime] on this moon.\n\nPlease CONFIRM or DENY.\n\n";
			val5.clearPreviousText = true;
			val5.displayPlanetInfo = moonToAdd.levelID;
			val5.buyRerouteToMoon = -2;
			val5.overrideOptions = true;
			val5.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2]
			{
				new CompatibleNoun(denyKeyword, result),
				new CompatibleNoun(val, val4)
			};
			List<TerminalKeyword> list = terminal.terminalNodes.allKeywords.ToList();
			list.Add(val3);
			terminal.terminalNodes.allKeywords = list.ToArray();
			List<CompatibleNoun> list2 = val2.compatibleNouns.ToList();
			list2.Add(new CompatibleNoun(val3, val5));
			val2.compatibleNouns = list2.ToArray();
			TerminalNode specialKeywordResult = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => ((Object)keyword).name == "Moons").specialKeywordResult;
			specialKeywordResult.displayText = specialKeywordResult.displayText + "* " + moonToAdd.PlanetName + " [planetTime]\n";
			Plugin.Logger.LogDebug((object)("Added terminal command for " + moonToAdd.PlanetName + "."));
		}

		public static string GetKWNameForMoon(SelectableLevel moon)
		{
			return "KW" + moon.PlanetName.ToLower().Replace(" ", "-");
		}

		public static string GetKWWordforMoon(SelectableLevel moon)
		{
			return moon.PlanetName.ToLower().Replace(" ", "-");
		}

		public static string GetTravelNodeNameForMoon(SelectableLevel moon)
		{
			return "Travel" + moon.PlanetName.ToLower().Replace(" ", "-");
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	public class PatchTerminal
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void InsertMoons(Terminal __instance)
		{
			Plugin.Logger.LogDebug((object)"Inserting moons in Terminal...");
			__instance.moonsCatalogueList = Plugin.WithCustomMoons(__instance.moonsCatalogueList);
		}

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void AddTerminalCommands(Terminal __instance)
		{
			SelectableLevel dailyMoon = __instance.moonsCatalogueList.First((SelectableLevel moon) => moon.PlanetName == "Daily Moon");
			SelectableLevel moonToAdd = __instance.moonsCatalogueList.First((SelectableLevel moon) => moon.PlanetName == "Weekly Moon");
			if (__instance.terminalNodes.allKeywords.Any((TerminalKeyword keyword) => ((Object)keyword).name == PatchTerminalHelpers.GetKWNameForMoon(dailyMoon)))
			{
				Plugin.Logger.LogDebug((object)"Terminal nodes have already been modified.");
				return;
			}
			Plugin.Logger.LogDebug((object)"Modifying terminal nodes...");
			PatchTerminalHelpers.AddTerminalCommand(ref __instance, dailyMoon);
			PatchTerminalHelpers.AddTerminalCommand(ref __instance, moonToAdd);
			TerminalNode specialKeywordResult = __instance.terminalNodes.allKeywords.First((TerminalKeyword keyword) => ((Object)keyword).name == "Moons").specialKeywordResult;
			specialKeywordResult.displayText += "\n";
		}
	}
}