Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SilksongLoadoutRandomizer v1.0.2
SilksongLoadoutRandomizer.dll
Decompiled 10 minutes agousing 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"; } }