Decompiled source of SilksongLoadoutRandomizer v1.0.2

SilksongLoadoutRandomizer.dll

Decompiled 10 minutes ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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 GlobalSettings;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[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("SilksongLoadoutRandomizer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Silksong Loadout Randomizer Plugin")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+865996ea05058b45c810cbab155a37f5e97e62be")]
[assembly: AssemblyProduct("SilksongLoadoutRandomizer")]
[assembly: AssemblyTitle("SilksongLoadoutRandomizer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SilksongLoadoutRandomizer
{
	[HarmonyPatch(typeof(HealthManager))]
	public static class BossKillPatch
	{
		private static readonly (string sceneName, string goName)[] BossPatterns = new(string, string)[52]
		{
			("Tut_03", "Mossbone Mother"),
			("Weave_03", "Mossbone Mother A"),
			("Weave_03", "Mossbone Mother B"),
			("Bone_05", "Bone Beast"),
			("Bone_East_12", "Lace Boss1"),
			("Bone_East_08", "SG_head"),
			("Ant_19", "Bone Flyer Giant"),
			("Greymoor_08", "Vampire Gnat"),
			("Greymoor_05", "Vampire Gnat"),
			("Shellwood_18", "Splinter Queen"),
			("Bone_15", "Skull King"),
			("Bonetown", "Skull King"),
			("Coral_11", "Driller A"),
			("Belltown_Shrine", "Spinner Boss"),
			("Coral_Judge_Arena", "Last Judge"),
			("Organ_01", "Phantom"),
			("Cog_Dancers", "Dancer A"),
			("Cog_Dancers", "Dancer B"),
			("Library_13", "Trobbio"),
			("Bone_East_08", "Bone Flyer Giant"),
			("Ward_02", "Conductor Boss"),
			("Dust_Chef", "Roachkeeper Chef (1)"),
			("Coral_29", "Zap Core Enemy"),
			("Coral_27", "Coral Conch Driller Giant Solo"),
			("Slab_16b", "Slab Fly Broodmother"),
			("Hang_17b", "Song Knight"),
			("Shadow_18", "Swamp Shaman"),
			("Slab_10b", "First Weaver"),
			("Library_09", "Garmond Fighter"),
			("Greymoor_08", "Mapper Spar NPC"),
			("Song_Tower_01", "Lace Boss2 New"),
			("Cradle_03", "Silk Boss"),
			("Dock_09", "Dock Guard Slasher"),
			("Dock_09", "Dock Guard Thrower"),
			("Bone_Steel_Servant", "Abyss Mass"),
			("wisp02", "WispPyreEffigy"),
			("Bellway_Centipede_Arena", "Giant Centipede Head"),
			("Bellway_Centipede_Arena", "Giant Centipede Butt"),
			("Peak_07", "Pinstress Boss"),
			("Library_13", "Tormented Trobbio"),
			("Coral_33", "Garmond Black Threaded Fighter"),
			("Crawl_10", "Blue Assistant"),
			("Room_CrowCourt_02", "Crawfather"),
			("Memory_Coral_Tower", "Coral King"),
			("Memory_Ant_Queen", "Hunter Queen Boss"),
			("Bone_East_18b", "Bone Hunter Trapper"),
			("Shellwood_22", "Seth"),
			("Shellwood_11b_Memory", "Flower Queen Boss"),
			("Clover_19", "Cloverstag White Boss"),
			("Clover_10", "Dancer A"),
			("Coral_39", "Coral Warrior Grey"),
			("Abyss_Cocoon", "Lost Lace Boss")
		};

		private static bool IsBoss(GameObject go)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			string text = ((Object)go).name.Replace("(Clone)", "");
			(string, string)[] bossPatterns = BossPatterns;
			for (int i = 0; i < bossPatterns.Length; i++)
			{
				(string, string) tuple = bossPatterns[i];
				if (text == tuple.Item2)
				{
					Scene sceneByName = SceneManager.GetSceneByName(tuple.Item1);
					if (((Scene)(ref sceneByName)).isLoaded)
					{
						return true;
					}
				}
			}
			return false;
		}

		[HarmonyPatch("Die")]
		[HarmonyPatch(new Type[]
		{
			typeof(float?),
			typeof(AttackTypes),
			typeof(NailElements),
			typeof(GameObject),
			typeof(bool),
			typeof(float),
			typeof(bool),
			typeof(bool)
		})]
		[HarmonyPostfix]
		public static void Postfix_Die(HealthManager __instance)
		{
			if (!Plugin.IsModEnabled.Value || !Plugin.RandomizeOnBossKill.Value || !IsBoss(((Component)__instance).gameObject))
			{
				return;
			}
			bool flag = false;
			HealthManager[] array = Object.FindObjectsOfType<HealthManager>();
			foreach (HealthManager val in array)
			{
				if ((Object)(object)val != (Object)(object)__instance && val.hp > 0 && IsBoss(((Component)val).gameObject))
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				Plugin.Logger.LogInfo((object)("Boss " + ((Object)((Component)__instance).gameObject).name + " was defeated and no other bosses remain! Triggering randomizer..."));
				Randomizer.RandomizeLoadout();
			}
			else
			{
				Plugin.Logger.LogInfo((object)("Boss " + ((Object)((Component)__instance).gameObject).name + " was defeated, but other boss entities are still alive (duo fight). Waiting..."));
			}
		}
	}
	public static class LoadoutManager
	{
		public static readonly List<string> AllCrestNames = new List<string> { "Reaper", "Wanderer", "Warrior", "Witch", "Toolmaster", "Spell", "Hunter", "Hunter_v2", "Hunter_v3" };
	}
	[BepInPlugin("SilksongLoadoutRandomizer", "SilksongLoadoutRandomizer", "1.0.2")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		public static ConfigEntry<bool> IsModEnabled;

		public static ConfigEntry<bool> RandomizeOnBenchRest;

		public static ConfigEntry<bool> RandomizeOnBossKill;

		public static ConfigEntry<KeyboardShortcut> RandomizeKeybind;

		public static ConfigEntry<bool> IncludeCrests;

		public static ConfigEntry<bool> RandomizeHunterTier;

		public static ConfigEntry<bool> IncludeCursedCrest;

		public static ConfigEntry<bool> IncludeSilkSkills;

		public static ConfigEntry<bool> IncludeRedTools;

		public static ConfigEntry<bool> IncludeBlueTools;

		public static ConfigEntry<bool> IncludeYellowTools;

		public static ConfigEntry<bool> GiveAllCrests;

		public static ConfigEntry<bool> GiveAllSlots;

		public static ConfigEntry<bool> GiveAllSilkSkills;

		public static ConfigEntry<bool> GiveAllRedTools;

		public static ConfigEntry<bool> GiveAllBlueTools;

		public static ConfigEntry<bool> GiveAllYellowTools;

		private bool _wasAtBench;

		private bool _notifiedStartup;

		private void Awake()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Expected O, but got Unknown
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Expected O, but got Unknown
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Expected O, but got Unknown
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Expected O, but got Unknown
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Expected O, but got Unknown
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Expected O, but got Unknown
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Expected O, but got Unknown
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Expected O, but got Unknown
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Expected O, but got Unknown
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Expected O, but got Unknown
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_044e: Expected O, but got Unknown
			//IL_0485: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Harmony.CreateAndPatchAll(typeof(SaveGamePatch), "SilksongLoadoutRandomizer");
			Harmony.CreateAndPatchAll(typeof(BossKillPatch), "SilksongLoadoutRandomizer");
			IsModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Enable Randomizer", true, new ConfigDescription("Turn the loadout randomizer on or off.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 100
				}
			}));
			RandomizeOnBenchRest = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Randomize On Bench Rest", true, new ConfigDescription("If enabled, your loadout is randomized every time you rest at a bench.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 90
				}
			}));
			RandomizeOnBossKill = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Randomize On Boss Kill", false, new ConfigDescription("If enabled, your loadout is randomized every time you defeat a boss.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 85
				}
			}));
			RandomizeKeybind = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1. General", "Randomize Keybind", new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>()), new ConfigDescription("Press this key to instantly randomize your loadout at any time.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 80
				}
			}));
			IncludeCrests = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Crests", "Randomize Crests", true, new ConfigDescription("Should crests be randomized?", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 80
				}
			}));
			RandomizeHunterTier = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Crests", "Randomize Hunter Tier", false, new ConfigDescription("If true, allows lower tiers of the Hunter Crest to be chosen even if you have unlocked a higher tier.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 75
				}
			}));
			IncludeCursedCrest = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Crests", "Include Cursed Crest", false, new ConfigDescription("If true, the Cursed Crest can be chosen when crests are randomized.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 70
				}
			}));
			IncludeSilkSkills = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Silk Skills", "Randomize Silk Skills", true, new ConfigDescription("Should Silk Skills be randomized?", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 60
				}
			}));
			IncludeRedTools = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Tools", "Randomize Red Tools", true, new ConfigDescription("Should Red Tools be randomized?", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 50
				}
			}));
			IncludeBlueTools = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Tools", "Randomize Blue Tools", true, new ConfigDescription("Should Blue Tools be randomized?", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 40
				}
			}));
			IncludeYellowTools = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Tools", "Randomize Yellow Tools", true, new ConfigDescription("Should Yellow Tools be randomized?", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 30
				}
			}));
			GiveAllCrests = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Unlocks", "Unlock All Crests", false, new ConfigDescription("Automatically gives the player all Crests.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 20
				}
			}));
			GiveAllSlots = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Unlocks", "Unlock All Slots", false, new ConfigDescription("Automatically unlocks all memory locket slots on all crests.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 19
				}
			}));
			GiveAllSilkSkills = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Unlocks", "Unlock All Silk Skills", false, new ConfigDescription("Automatically gives the player all Silk Skills.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 18
				}
			}));
			GiveAllRedTools = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Unlocks", "Unlock All Red Tools", false, new ConfigDescription("Automatically gives the player all Red Tools.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 17
				}
			}));
			GiveAllBlueTools = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Unlocks", "Unlock All Blue Tools", false, new ConfigDescription("Automatically gives the player all Blue Tools.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 16
				}
			}));
			GiveAllYellowTools = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Unlocks", "Unlock All Yellow Tools", false, new ConfigDescription("Automatically gives the player all Yellow Tools.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 15
				}
			}));
			((BaseUnityPlugin)this).Config.SettingChanged += delegate
			{
				Randomizer.ScrubIllegitimateItems();
				if ((Object)(object)HeroController.instance != (Object)null)
				{
					HeroController.instance.UpdateSilkCursed();
				}
			};
			Logger.LogInfo((object)"Plugin SilksongLoadoutRandomizer is loaded and configured!");
		}

		private void Update()
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)HeroController.instance != (Object)null && PlayerData.instance != null && (Object)(object)GameManager.instance != (Object)null && GameManager.instance.IsGameplayScene())
			{
				if (!_notifiedStartup)
				{
					_notifiedStartup = true;
					_wasAtBench = PlayerData.instance.atBench;
					if (IsModEnabled.Value)
					{
						Randomizer.ShowNotification("Loadout Randomizer Enabled");
					}
				}
				bool atBench = PlayerData.instance.atBench;
				if (atBench && !_wasAtBench && IsModEnabled.Value && RandomizeOnBenchRest.Value)
				{
					Logger.LogInfo((object)"Hornet sat at a bench! Triggering randomizer...");
					Randomizer.RandomizeLoadout();
				}
				_wasAtBench = atBench;
				if (IsModEnabled.Value)
				{
					KeyboardShortcut value = RandomizeKeybind.Value;
					if (((KeyboardShortcut)(ref value)).IsDown())
					{
						Logger.LogInfo((object)"Randomizer keybind pressed! Triggering randomizer...");
						Randomizer.RandomizeLoadout();
					}
				}
			}
			else if ((Object)(object)HeroController.instance == (Object)null || (Object)(object)GameManager.instance == (Object)null || !GameManager.instance.IsGameplayScene())
			{
				_notifiedStartup = false;
			}
		}
	}
	public sealed class ConfigurationManagerAttributes
	{
		public Action<ConfigEntryBase> CustomDrawer;

		public object Browsable;

		public bool? HideDefaultButton;

		public int? Order;
	}
	public static class Randomizer
	{
		public static void RandomizeLoadout()
		{
			if (Plugin.IsModEnabled.Value)
			{
				Plugin.Logger.LogInfo((object)"Triggering Loadout Randomization...");
				ToolCrest val = null;
				if (Plugin.IncludeCrests.Value)
				{
					val = RandomizeCrest();
				}
				if ((Object)(object)val == (Object)null)
				{
					val = ToolItemManager.GetCrestByName(PlayerData.instance.CurrentCrestID);
				}
				if ((Object)(object)val != (Object)null)
				{
					RandomizeToolsAndSkills(val);
				}
				if ((Object)(object)HeroController.instance != (Object)null)
				{
					HeroController.instance.UpdateSilkCursed();
				}
				Plugin.Logger.LogInfo((object)"Loadout successfully randomized!");
				ShowNotification("Loadout Randomized");
			}
		}

		public static void ShowNotification(string message)
		{
			try
			{
				Sprite sprite = null;
				ToolItem toolByName = ToolItemManager.GetToolByName("Magnetite Dice");
				if ((Object)(object)toolByName != (Object)null)
				{
					sprite = ((SavedItem)toolByName).GetPopupIcon();
				}
				CollectableUIMsg.Spawn((ICollectableUIMsgItem)(object)new RandomizerNotificationItem(message, sprite), (CollectableUIMsg)null, false);
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)("Failed to spawn UI notification: " + ex.Message));
			}
		}

		public static void ScrubIllegitimateItems()
		{
			if (PlayerData.instance == null)
			{
				return;
			}
			Plugin.Logger.LogInfo((object)"Scrubbing illegitimate items from active loadout...");
			ToolCrest crestByName = ToolItemManager.GetCrestByName(PlayerData.instance.CurrentCrestID);
			if ((Object)(object)crestByName == (Object)(object)Gameplay.CursedCrest || (Object)(object)crestByName == (Object)null || !crestByName.IsUnlocked)
			{
				string text = "Hunter";
				foreach (string allCrestName in LoadoutManager.AllCrestNames)
				{
					ToolCrest crestByName2 = ToolItemManager.GetCrestByName(allCrestName);
					if ((Object)(object)crestByName2 != (Object)null && crestByName2.IsUnlocked)
					{
						if (allCrestName == "Hunter_v3")
						{
							text = allCrestName;
							break;
						}
						if (allCrestName == "Hunter_v2" && text == "Hunter")
						{
							text = allCrestName;
						}
						else if (!allCrestName.StartsWith("Hunter"))
						{
							text = allCrestName;
							break;
						}
					}
				}
				ToolItemManager.SetEquippedCrest(text);
			}
			PlayerData.instance.IsCurrentCrestTemp = false;
			List<string> validNames = ((SerializableNamedList<Data, NamedData>)(object)PlayerData.instance.ToolEquips).GetValidNames((Func<Data, bool>)null);
			foreach (string allCrestName2 in LoadoutManager.AllCrestNames)
			{
				if (validNames == null || !validNames.Contains(allCrestName2))
				{
					continue;
				}
				List<ToolItem> equippedToolsForCrest = ToolItemManager.GetEquippedToolsForCrest(allCrestName2);
				if (equippedToolsForCrest == null)
				{
					continue;
				}
				List<string> list = new List<string>();
				bool flag = false;
				for (int i = 0; i < equippedToolsForCrest.Count; i++)
				{
					ToolItem val = equippedToolsForCrest[i];
					if ((Object)(object)val != (Object)null && val.IsUnlockedNotHidden)
					{
						list.Add(val.name);
						continue;
					}
					list.Add("");
					if ((Object)(object)val != (Object)null)
					{
						flag = true;
					}
				}
				if (flag)
				{
					ToolItemManager.SetEquippedTools(allCrestName2, list);
				}
			}
			ToolItemManager.SendEquippedChangedEvent(true);
		}

		public static List<ToolCrest> GetAvailableCrestsPool()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			List<ToolCrest> list = new List<ToolCrest>();
			foreach (string allCrestName in LoadoutManager.AllCrestNames)
			{
				ToolCrest crestByName = ToolItemManager.GetCrestByName(allCrestName);
				if (!((Object)(object)crestByName != (Object)null) || (!crestByName.IsUnlocked && !Plugin.GiveAllCrests.Value))
				{
					continue;
				}
				if (PlayerData.instance != null)
				{
					List<string> validNames = ((SerializableNamedList<Data, NamedData>)(object)PlayerData.instance.ToolEquips).GetValidNames((Func<Data, bool>)null);
					if (validNames == null || !validNames.Contains(allCrestName))
					{
						if (!Plugin.GiveAllCrests.Value)
						{
							continue;
						}
						((SerializableNamedList<Data, NamedData>)(object)PlayerData.instance.ToolEquips).SetData(allCrestName, crestByName.SaveData);
					}
				}
				list.Add(crestByName);
			}
			if (!Plugin.RandomizeHunterTier.Value)
			{
				bool num = list.Exists((ToolCrest c) => c.name == "Hunter_v3");
				bool flag = list.Exists((ToolCrest c) => c.name == "Hunter_v2");
				if (num)
				{
					list.RemoveAll((ToolCrest c) => c.name == "Hunter" || c.name == "Hunter_v2");
				}
				else if (flag)
				{
					list.RemoveAll((ToolCrest c) => c.name == "Hunter");
				}
			}
			if (Plugin.IncludeCursedCrest.Value && (Object)(object)Gameplay.CursedCrest != (Object)null)
			{
				list.Add(Gameplay.CursedCrest);
			}
			return list;
		}

		private static ToolCrest RandomizeCrest()
		{
			List<ToolCrest> availableCrestsPool = GetAvailableCrestsPool();
			if (availableCrestsPool.Count > 0)
			{
				ToolCrest obj = availableCrestsPool[Random.Range(0, availableCrestsPool.Count)];
				if (obj.name != PlayerData.instance.CurrentCrestID)
				{
					PlayerData.instance.PreviousCrestID = PlayerData.instance.CurrentCrestID;
				}
				ToolItemManager.SetEquippedCrest(obj.name);
				bool isCurrentCrestTemp = (Object)(object)obj == (Object)(object)Gameplay.CursedCrest;
				PlayerData.instance.IsCurrentCrestTemp = isCurrentCrestTemp;
				return obj;
			}
			return null;
		}

		private static void RandomizeToolsAndSkills(ToolCrest crest)
		{
			List<string> list = GenerateRandomLoadoutForCrest(crest);
			ToolItemManager.SetEquippedTools(crest.name, list);
			ToolItemManager.SendEquippedChangedEvent(false);
			Plugin.Logger.LogInfo((object)("[Randomizer] Successfully equipped Crest: " + crest.name));
			Plugin.Logger.LogInfo((object)"[Randomizer] Equipped Tools:");
			for (int i = 0; i < list.Count; i++)
			{
				string arg = (string.IsNullOrEmpty(list[i]) ? "[EMPTY]" : list[i]);
				Plugin.Logger.LogInfo((object)$"  - Slot {i + 1}: {arg}");
			}
		}

		public static List<string> GenerateRandomLoadoutForCrest(ToolCrest crest)
		{
			//IL_0041: 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)
			//IL_0185: 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_0061: Invalid comparison between Unknown and I4
			//IL_00e3: 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_007c: Invalid comparison between Unknown and I4
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Invalid comparison between Unknown and I4
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Invalid comparison between Unknown and I4
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Invalid comparison between Unknown and I4
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Invalid comparison between Unknown and I4
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Invalid comparison between Unknown and I4
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Invalid comparison between Unknown and I4
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Invalid comparison between Unknown and I4
			List<ToolItem> list = new List<ToolItem>();
			List<ToolItem> list2 = new List<ToolItem>();
			List<ToolItem> list3 = new List<ToolItem>();
			List<ToolItem> list4 = new List<ToolItem>();
			foreach (ToolItem allTool in ToolItemManager.GetAllTools())
			{
				bool flag = allTool.IsUnlockedNotHidden;
				if (!flag)
				{
					if ((int)allTool.Type == 0 && Plugin.GiveAllRedTools.Value)
					{
						flag = true;
					}
					else if ((int)allTool.Type == 1 && Plugin.GiveAllBlueTools.Value)
					{
						flag = true;
					}
					else if ((int)allTool.Type == 2 && Plugin.GiveAllYellowTools.Value)
					{
						flag = true;
					}
					else if ((int)allTool.Type == 3 && Plugin.GiveAllSilkSkills.Value)
					{
						flag = true;
					}
				}
				if (flag && !allTool.name.Replace(" ", "").Replace("_", "").Equals("Extractor", StringComparison.OrdinalIgnoreCase))
				{
					if ((int)allTool.Type == 0 && Plugin.IncludeRedTools.Value)
					{
						list.Add(allTool);
					}
					else if ((int)allTool.Type == 1 && Plugin.IncludeBlueTools.Value)
					{
						list2.Add(allTool);
					}
					else if ((int)allTool.Type == 2 && Plugin.IncludeYellowTools.Value)
					{
						list3.Add(allTool);
					}
					else if ((int)allTool.Type == 3 && Plugin.IncludeSilkSkills.Value)
					{
						list4.Add(allTool);
					}
				}
			}
			List<string> list5 = new List<string>();
			Data saveData = crest.SaveData;
			for (int i = 0; i < crest.Slots.Length; i++)
			{
				bool flag2 = Plugin.GiveAllSlots.Value || !crest.Slots[i].IsLocked;
				if (!flag2 && saveData.Slots != null && i < saveData.Slots.Count && saveData.Slots[i].IsUnlocked)
				{
					flag2 = true;
				}
				if (!flag2)
				{
					list5.Add("");
					continue;
				}
				SlotInfo val = crest.Slots[i];
				ToolItem val2 = null;
				if ((int)val.Type == 0 && list.Count > 0)
				{
					int index = Random.Range(0, list.Count);
					val2 = list[index];
					list.RemoveAt(index);
				}
				else if ((int)val.Type == 1 && list2.Count > 0)
				{
					int index2 = Random.Range(0, list2.Count);
					val2 = list2[index2];
					list2.RemoveAt(index2);
				}
				else if ((int)val.Type == 2 && list3.Count > 0)
				{
					int index3 = Random.Range(0, list3.Count);
					val2 = list3[index3];
					list3.RemoveAt(index3);
				}
				else if ((int)val.Type == 3 && list4.Count > 0)
				{
					int index4 = Random.Range(0, list4.Count);
					val2 = list4[index4];
					list4.RemoveAt(index4);
				}
				if ((Object)(object)val2 != (Object)null)
				{
					list5.Add(val2.name);
				}
				else
				{
					list5.Add("");
				}
			}
			return list5;
		}
	}
	public class RandomizerNotificationItem : ICollectableUIMsgItem, IUIMsgPopupItem
	{
		private Sprite _sprite;

		private string _name;

		public RandomizerNotificationItem(string name, Sprite sprite)
		{
			_name = name;
			_sprite = sprite;
		}

		public Sprite GetUIMsgSprite()
		{
			return _sprite;
		}

		public string GetUIMsgName()
		{
			return _name;
		}

		public float GetUIMsgIconScale()
		{
			return 1f;
		}

		public bool HasUpgradeIcon()
		{
			return false;
		}

		public Object GetRepresentingObject()
		{
			return null;
		}
	}
	[HarmonyPatch(typeof(GameManager), "SaveGame", new Type[]
	{
		typeof(int),
		typeof(Action<bool>),
		typeof(bool),
		typeof(AutoSaveName)
	})]
	public static class SaveGamePatch
	{
		private static string _backedUpCrestId;

		private static bool _backedUpIsTemp;

		private static Dictionary<string, List<string>> _backedUpToolCrests;

		[HarmonyPrefix]
		public static void Prefix(ref Action<bool> __1)
		{
			if (PlayerData.instance == null)
			{
				return;
			}
			Plugin.Logger.LogInfo((object)"Intercepting GameManager.SaveGameData. Scrubbing randomized loadout from save data...");
			_backedUpCrestId = PlayerData.instance.CurrentCrestID;
			_backedUpIsTemp = PlayerData.instance.IsCurrentCrestTemp;
			_backedUpToolCrests = new Dictionary<string, List<string>>();
			List<string> validNames = ((SerializableNamedList<Data, NamedData>)(object)PlayerData.instance.ToolEquips).GetValidNames((Func<Data, bool>)null);
			foreach (string allCrestName in LoadoutManager.AllCrestNames)
			{
				if (validNames == null || !validNames.Contains(allCrestName))
				{
					continue;
				}
				List<ToolItem> equippedToolsForCrest = ToolItemManager.GetEquippedToolsForCrest(allCrestName);
				if (equippedToolsForCrest == null)
				{
					continue;
				}
				List<string> list = new List<string>();
				foreach (ToolItem item in equippedToolsForCrest)
				{
					list.Add(((Object)(object)item != (Object)null) ? item.name : "");
				}
				_backedUpToolCrests[allCrestName] = list;
			}
			ToolCrest crestByName = ToolItemManager.GetCrestByName(_backedUpCrestId);
			if ((Object)(object)crestByName == (Object)(object)Gameplay.CursedCrest || (Object)(object)crestByName == (Object)null || !crestByName.IsUnlocked)
			{
				string text = "Hunter";
				foreach (string allCrestName2 in LoadoutManager.AllCrestNames)
				{
					ToolCrest crestByName2 = ToolItemManager.GetCrestByName(allCrestName2);
					if ((Object)(object)crestByName2 != (Object)null && crestByName2.IsUnlocked)
					{
						if (allCrestName2 == "Hunter_v3")
						{
							text = allCrestName2;
							break;
						}
						if (allCrestName2 == "Hunter_v2" && text == "Hunter")
						{
							text = allCrestName2;
						}
						else if (!allCrestName2.StartsWith("Hunter"))
						{
							text = allCrestName2;
							break;
						}
					}
				}
				ToolItemManager.SetEquippedCrest(text);
			}
			PlayerData.instance.IsCurrentCrestTemp = false;
			foreach (string allCrestName3 in LoadoutManager.AllCrestNames)
			{
				if (validNames == null || !validNames.Contains(allCrestName3))
				{
					continue;
				}
				List<ToolItem> equippedToolsForCrest2 = ToolItemManager.GetEquippedToolsForCrest(allCrestName3);
				if (equippedToolsForCrest2 == null)
				{
					continue;
				}
				List<string> list2 = new List<string>();
				bool flag = false;
				for (int i = 0; i < equippedToolsForCrest2.Count; i++)
				{
					ToolItem val = equippedToolsForCrest2[i];
					if ((Object)(object)val != (Object)null)
					{
						if (!val.IsUnlockedNotHidden)
						{
							list2.Add("");
							flag = true;
						}
						else
						{
							list2.Add(val.name);
						}
					}
					else
					{
						list2.Add("");
					}
				}
				if (flag)
				{
					ToolItemManager.SetEquippedTools(allCrestName3, list2);
				}
			}
			Action<bool> originalCallback = __1;
			__1 = delegate(bool result)
			{
				Plugin.Logger.LogInfo((object)"Save background thread complete! Restoring randomized loadout to memory...");
				if (PlayerData.instance != null)
				{
					ToolItemManager.SetEquippedCrest(_backedUpCrestId);
					PlayerData.instance.IsCurrentCrestTemp = _backedUpIsTemp;
					foreach (KeyValuePair<string, List<string>> backedUpToolCrest in _backedUpToolCrests)
					{
						ToolItemManager.SetEquippedTools(backedUpToolCrest.Key, backedUpToolCrest.Value);
					}
					ToolItemManager.SendEquippedChangedEvent(true);
				}
				if (originalCallback != null)
				{
					originalCallback(result);
				}
			};
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "SilksongLoadoutRandomizer";

		public const string PLUGIN_NAME = "SilksongLoadoutRandomizer";

		public const string PLUGIN_VERSION = "1.0.2";
	}
}