using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using GlobalSettings; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("try")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("try")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e83d6efb-7c27-4742-a9b2-b3dd8d0888d5")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] [BepInPlugin("com.yourname.crestkeydirs5", "Crest Key + Directions V5", "1.7")] public class CrestKeyDirectionsV5 : BaseUnityPlugin { private static class ReflectionCache { public static FieldInfo fi_cState; public static FieldInfo fi_attacking; public static FieldInfo fi_upAttacking; public static FieldInfo fi_downAttacking; public static FieldInfo fi_nailCharging; public static FieldInfo fi_dashing; public static FieldInfo fi_backDashing; public static FieldInfo fi_isDashStabBouncing; public static FieldInfo fi_cState_canControl; public static FieldInfo fi_hero_acceptingInput; public static FieldInfo fi_hero_controlRelinquished; public static MethodInfo mi_AddInvincibleTime; public static FieldInfo fi_invincibleTimer; public static MethodInfo mi_ResetAttacksDash; public static MethodInfo mi_ResetAttacks; public static void Initialize(HeroController heroInstance) { if (!((Object)(object)heroInstance == (Object)null)) { Type typeFromHandle = typeof(HeroController); fi_cState = AccessTools.Field(typeFromHandle, "cState"); Type type = fi_cState?.FieldType; if (type != null) { fi_attacking = AccessTools.Field(type, "attacking"); fi_upAttacking = AccessTools.Field(type, "upAttacking"); fi_downAttacking = AccessTools.Field(type, "downAttacking"); fi_nailCharging = AccessTools.Field(type, "nailCharging"); fi_dashing = AccessTools.Field(type, "dashing"); fi_backDashing = AccessTools.Field(type, "backDashing"); fi_cState_canControl = AccessTools.Field(type, "canControl"); } fi_isDashStabBouncing = AccessTools.Field(typeFromHandle, "isDashStabBouncing"); fi_hero_acceptingInput = AccessTools.Field(typeFromHandle, "acceptingInput"); fi_hero_controlRelinquished = AccessTools.Field(typeFromHandle, "controlRelinquished"); mi_AddInvincibleTime = typeFromHandle.GetMethod("AddInvincibleTime", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); fi_invincibleTimer = typeFromHandle.GetField("invincibleTimer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); mi_ResetAttacksDash = AccessTools.Method(typeFromHandle, "ResetAttacksDash", new Type[0], (Type[])null); mi_ResetAttacks = AccessTools.Method(typeFromHandle, "ResetAttacks", new Type[1] { typeof(bool) }, (Type[])null); } } } private static class InputAdapter { private static FieldInfo fi_inputHandler; private static FieldInfo fi_inputActions; private static object cachedInputActions; private static string[] possibleActionNames = new string[4] { "quickMap", "dreamNail", "inventory", "cast" }; private static PropertyInfo pi_ActionIsPressed; private static PropertyInfo pi_ActionWasPressed; private static object targetActionObject; public static void Initialize(HeroController hero) { try { fi_inputHandler = AccessTools.Field(typeof(HeroController), "inputHandler"); object obj = fi_inputHandler?.GetValue(hero); if (obj == null) { return; } fi_inputActions = AccessTools.Field(obj.GetType(), "inputActions"); cachedInputActions = fi_inputActions?.GetValue(obj); if (cachedInputActions == null) { return; } Type type = cachedInputActions.GetType(); string[] array = possibleActionNames; foreach (string text in array) { FieldInfo fieldInfo = AccessTools.Field(type, text); if (!(fieldInfo != null)) { continue; } targetActionObject = fieldInfo.GetValue(cachedInputActions); if (targetActionObject != null) { Type type2 = targetActionObject.GetType(); pi_ActionIsPressed = AccessTools.Property(type2, "IsPressed"); pi_ActionWasPressed = AccessTools.Property(type2, "WasPressed"); ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("[InputAdapter] Hooked into game action: " + text)); } break; } } } catch (Exception ex) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogError((object)("[InputAdapter] Init Failed: " + ex.Message)); } } } public static bool IsTauntDown() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(KeyboardBindingCache.Taunt)) { return true; } if (pi_ActionWasPressed != null && targetActionObject != null) { try { if ((bool)pi_ActionWasPressed.GetValue(targetActionObject, null)) { return true; } } catch { } } if (Input.GetKeyDown((KeyCode)334) || Input.GetKeyDown((KeyCode)335) || Input.GetKeyDown((KeyCode)333)) { return true; } return false; } public static bool IsTauntUp() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyUp(KeyboardBindingCache.Taunt)) { return true; } if (Input.GetKeyUp((KeyCode)334) || Input.GetKeyUp((KeyCode)335) || Input.GetKeyUp((KeyCode)333)) { return true; } return false; } public static bool IsTauntHeld() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKey(KeyboardBindingCache.Taunt)) { return true; } if (pi_ActionIsPressed != null && targetActionObject != null) { try { if ((bool)pi_ActionIsPressed.GetValue(targetActionObject, null)) { return true; } } catch { } } if (Input.GetKey((KeyCode)334) || Input.GetKey((KeyCode)335) || Input.GetKey((KeyCode)333)) { return true; } return false; } public static int GetCombinedDirMask(bool justDown) { //IL_005d: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) int num = 0; if (justDown) { if (Input.GetKeyDown(KeyboardBindingCache.Up)) { num |= 1; } if (Input.GetKeyDown(KeyboardBindingCache.Down)) { num |= 2; } if (Input.GetKeyDown(KeyboardBindingCache.Left)) { num |= 4; } if (Input.GetKeyDown(KeyboardBindingCache.Right)) { num |= 8; } } else { if (Input.GetKey(KeyboardBindingCache.Up)) { num |= 1; } if (Input.GetKey(KeyboardBindingCache.Down)) { num |= 2; } if (Input.GetKey(KeyboardBindingCache.Left)) { num |= 4; } if (Input.GetKey(KeyboardBindingCache.Right)) { num |= 8; } } float axisRaw = Input.GetAxisRaw("Horizontal"); float axisRaw2 = Input.GetAxisRaw("Vertical"); if (axisRaw2 > 0.5f) { num |= 1; } if (axisRaw2 < -0.5f) { num |= 2; } if (axisRaw < -0.5f) { num |= 4; } if (axisRaw > 0.5f) { num |= 8; } return num; } } private static class KeyboardBindingCache { public static KeyCode Taunt { get; private set; } = (KeyCode)118; public static KeyCode Up { get; private set; } = (KeyCode)273; public static KeyCode Down { get; private set; } = (KeyCode)274; public static KeyCode Left { get; private set; } = (KeyCode)276; public static KeyCode Right { get; private set; } = (KeyCode)275; public static void Initialize() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_006f: 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) Taunt = ParseKeyCode(ReadKeyString("KeyTaunt", "V"), (KeyCode)118); Up = ParseKeyCode(ReadKeyString("KeyUp", "UpArrow"), (KeyCode)273); Down = ParseKeyCode(ReadKeyString("KeyDown", "DownArrow"), (KeyCode)274); Left = ParseKeyCode(ReadKeyString("KeyLeft", "LeftArrow"), (KeyCode)276); Right = ParseKeyCode(ReadKeyString("KeyRight", "RightArrow"), (KeyCode)275); } private static string ReadKeyString(string prefKey, string fallback) { try { Type type = AccessTools.TypeByName("Platform"); if (type != null) { object obj = AccessTools.Property(type, "Current")?.GetValue(null) ?? AccessTools.Field(type, "Current")?.GetValue(null) ?? AccessTools.Field(type, "current")?.GetValue(null); if (obj != null) { object obj2 = AccessTools.Property(obj.GetType(), "LocalSharedData")?.GetValue(obj, null) ?? AccessTools.Field(obj.GetType(), "LocalSharedData")?.GetValue(obj) ?? AccessTools.Field(obj.GetType(), "localSharedData")?.GetValue(obj); if (obj2 != null) { Type type2 = obj2.GetType(); MethodInfo method = type2.GetMethod("GetString", new Type[2] { typeof(string), typeof(string) }); if (method != null) { return (string)method.Invoke(obj2, new object[2] { prefKey, fallback }); } } } } } catch { } return PlayerPrefs.GetString(prefKey, fallback); } private static KeyCode ParseKeyCode(string s, KeyCode fallback) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: 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_009b: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(s)) { return fallback; } s = s.Trim(); switch (s.ToLowerInvariant()) { case "up": return (KeyCode)273; case "down": return (KeyCode)274; case "left": return (KeyCode)276; case "right": return (KeyCode)275; case "esc": return (KeyCode)27; case "enter": return (KeyCode)13; default: { if (s.Length == 1 && char.IsLetter(s[0]) && Enum.TryParse(s.ToUpperInvariant(), ignoreCase: true, out KeyCode result)) { return result; } if (s.Length == 1 && char.IsDigit(s[0])) { return (KeyCode)(48 + (s[0] - 48)); } if (s.Length == 2 && (s[0] | 0x20) == 100 && char.IsDigit(s[1])) { return (KeyCode)(48 + (s[1] - 48)); } if (Enum.TryParse(s, ignoreCase: true, out KeyCode result2)) { return result2; } return fallback; } } } } public static ManualLogSource Log; private const float LONG_PRESS_THRESHOLD = 0.2f; private const float SPECIAL_PRESS_THRESHOLD = 3f; private const float COOLDOWN_SECONDS = 0.3f; private const float IFRAME_SECONDS = 0.1f; public const string QUEEN_CREST_ID = "Yen"; private static float nextSwapTime = 0f; private static float mainKeyDownTime = -1f; private static int lastChosenDirMask = 0; private static bool swappedThisPress = false; private static bool specialTriggeredThisPress = false; private static int lastTriggeredDirMask = 0; private static bool lastTriggeredLong = false; private static HeroController hero; private static bool hasQueuedSwap = false; private static string queuedTargetName = null; private static string queuedReason = null; private static int queuedEarliestFrame = -1; private static bool queuedFromCombat = false; private static bool isApplyingSwap = false; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; Harmony.CreateAndPatchAll(typeof(CrestKeyDirectionsV5), (string)null); Harmony.CreateAndPatchAll(typeof(BenchReplenishPatch), (string)null); KeyboardBindingCache.Initialize(); Log.LogInfo((object)"CrestKeyDirectionsV5 loaded (Gamepad Ready). Target Queen ID: Yen"); } private void Update() { if ((Object)(object)hero == (Object)null) { hero = HeroController.instance; } if ((Object)(object)hero == (Object)null || hero.playerData == null) { return; } TryConsumeQueuedSwap(); bool flag = InputAdapter.IsTauntDown(); bool flag2 = InputAdapter.IsTauntHeld(); bool flag3 = InputAdapter.IsTauntUp(); if (flag) { mainKeyDownTime = Time.time; ResetPressState(); } if (flag3 || (mainKeyDownTime > 0f && !flag2)) { if (mainKeyDownTime > 0f) { mainKeyDownTime = -1f; ResetPressState(); } } else { if (!flag2) { return; } if (mainKeyDownTime < 0f) { mainKeyDownTime = Time.time; } int combinedDirMask = InputAdapter.GetCombinedDirMask(justDown: false); int combinedDirMask2 = InputAdapter.GetCombinedDirMask(justDown: true); int num = ChooseDirection(combinedDirMask, combinedDirMask2); float num2 = Time.time - mainKeyDownTime; if (num == 0 && !specialTriggeredThisPress && num2 >= 3f) { HandleSpecial3SecSwap(); specialTriggeredThisPress = true; nextSwapTime = Time.time + 0.3f; } else if (num != 0 && !(Time.time < nextSwapTime)) { bool flag4 = num2 >= 0.2f; bool flag5 = num != lastTriggeredDirMask; bool flag6 = !flag5 && flag4 != lastTriggeredLong; if (flag5 || (!swappedThisPress && flag6)) { PerformDirectionalSwap(num, flag4); } } } } private void ResetPressState() { lastChosenDirMask = 0; lastTriggeredDirMask = 0; lastTriggeredLong = false; swappedThisPress = false; specialTriggeredThisPress = false; } private void HandleSpecial3SecSwap() { string currentCrestID = hero.playerData.CurrentCrestID; string name = Gameplay.CursedCrest.name; string text = "Cloakless Crest"; if ((Object)(object)Gameplay.CloaklessCrest != (Object)null) { text = Gameplay.CloaklessCrest.name; } string targetName = ((currentCrestID == name) ? text : name); RequestSwap(targetName, "SPECIAL_3S"); } private void PerformDirectionalSwap(int dirMask, bool isLong) { string currentCrestID = hero.playerData.CurrentCrestID; string text = ResolveDirectionTarget(currentCrestID, dirMask, isLong); if (!string.IsNullOrEmpty(text) && !(text == currentCrestID)) { RequestSwap(text, isLong ? "LONG" : "SHORT"); lastTriggeredDirMask = dirMask; lastTriggeredLong = isLong; swappedThisPress = true; nextSwapTime = Time.time + 0.3f; } } private static void RequestSwap(string targetName, string reason) { if (!string.IsNullOrEmpty(targetName) && !((Object)(object)hero == (Object)null) && hero.playerData != null) { if (IsSafeToSwapNow()) { ApplySwapNow(targetName, reason); return; } hasQueuedSwap = true; queuedTargetName = targetName; queuedReason = reason; queuedEarliestFrame = Time.frameCount + 1; queuedFromCombat = queuedFromCombat || IsCombatLikeActive(); } } private static void TryConsumeQueuedSwap() { if (!hasQueuedSwap || (Object)(object)hero == (Object)null || hero.playerData == null || Time.frameCount < queuedEarliestFrame || !IsSafeToSwapNow()) { return; } string currentCrestID = hero.playerData.CurrentCrestID; if (string.IsNullOrEmpty(queuedTargetName) || queuedTargetName == currentCrestID) { hasQueuedSwap = false; queuedFromCombat = false; return; } if (queuedFromCombat) { ForceClearCombatStateLight(); } ApplySwapNow(queuedTargetName, (queuedReason ?? "QUEUED") + (queuedFromCombat ? "_LIGHTCLR" : "_FAST")); hasQueuedSwap = false; queuedFromCombat = false; } private static bool IsSafeToSwapNow() { try { if (ReflectionCache.fi_cState == null && (Object)(object)hero != (Object)null) { ReflectionCache.Initialize(hero); InputAdapter.Initialize(hero); } object obj = ReflectionCache.fi_cState?.GetValue(hero); if (obj != null) { bool flag = GetCachedBool(obj, ReflectionCache.fi_attacking) || GetCachedBool(obj, ReflectionCache.fi_upAttacking) || GetCachedBool(obj, ReflectionCache.fi_downAttacking); bool cachedBool = GetCachedBool(obj, ReflectionCache.fi_nailCharging); bool flag2 = GetCachedBool(obj, ReflectionCache.fi_dashing) || GetCachedBool(obj, ReflectionCache.fi_backDashing); if (flag || cachedBool || flag2) { return false; } } if (GetCachedBool(hero, ReflectionCache.fi_isDashStabBouncing)) { return false; } bool flag3 = true; if (obj != null && ReflectionCache.fi_cState_canControl != null) { flag3 &= GetCachedBool(obj, ReflectionCache.fi_cState_canControl); } if (ReflectionCache.fi_hero_acceptingInput != null) { flag3 &= (bool)ReflectionCache.fi_hero_acceptingInput.GetValue(hero); } if (ReflectionCache.fi_hero_controlRelinquished != null) { flag3 &= !(bool)ReflectionCache.fi_hero_controlRelinquished.GetValue(hero); } return flag3; } catch { return false; } } private static bool IsCombatLikeActive() { try { if (ReflectionCache.fi_cState == null && (Object)(object)hero != (Object)null) { ReflectionCache.Initialize(hero); } object obj = ReflectionCache.fi_cState?.GetValue(hero); if (obj != null) { bool flag = GetCachedBool(obj, ReflectionCache.fi_attacking) || GetCachedBool(obj, ReflectionCache.fi_upAttacking) || GetCachedBool(obj, ReflectionCache.fi_downAttacking); bool cachedBool = GetCachedBool(obj, ReflectionCache.fi_nailCharging); bool flag2 = GetCachedBool(obj, ReflectionCache.fi_dashing) || GetCachedBool(obj, ReflectionCache.fi_backDashing); if (flag || cachedBool || flag2) { return true; } } if (GetCachedBool(hero, ReflectionCache.fi_isDashStabBouncing)) { return true; } } catch { } return false; } private static bool GetCachedBool(object obj, FieldInfo fi) { if (obj == null || fi == null) { return false; } return (bool)fi.GetValue(obj); } private static void ForceClearCombatStateLight() { try { ReflectionCache.mi_ResetAttacksDash?.Invoke(hero, null); } catch { } try { if (ReflectionCache.mi_ResetAttacks != null) { ReflectionCache.mi_ResetAttacks.Invoke(hero, new object[1] { true }); } else { ReflectionCache.mi_ResetAttacksDash?.Invoke(hero, null); } } catch { } queuedEarliestFrame = Mathf.Max(queuedEarliestFrame, Time.frameCount + 1); } private static void ApplySwapNow(string targetName, string reason) { if (isApplyingSwap) { return; } isApplyingSwap = true; try { ToolCrest crestByName = ToolItemManager.GetCrestByName(targetName); if (!((Object)(object)crestByName == (Object)null)) { int silk = hero.playerData.silk; ApplyInvincibilitySafe(0.1f); hero.ResetAllCrestState(); ToolItemManager.SetEquippedCrest(crestByName.name); ToolItemManager.SendEquippedChangedEvent(true); hero.playerData.silk = silk; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("Swapped -> " + crestByName.name + " [" + reason + "]")); } } } finally { isApplyingSwap = false; } } private static string ResolveDirectionTarget(string current, int dir, bool isLong) { string name = Gameplay.ToolmasterCrest.name; string secondary = "Yen"; string name2 = Gameplay.SpellCrest.name; string bestHunterName = GetBestHunterName(); string name3 = Gameplay.ReaperCrest.name; string name4 = Gameplay.WarriorCrest.name; string name5 = Gameplay.WandererCrest.name; string name6 = Gameplay.WitchCrest.name; return dir switch { 1 => ToggleLogic(current, isLong, name, secondary), 2 => ToggleLogic(current, isLong, name2, bestHunterName), 4 => ToggleLogic(current, isLong, name3, name4), 8 => ToggleLogic(current, isLong, name5, name6), _ => null, }; } private static string ToggleLogic(string current, bool isLong, string primary, string secondary) { if (isLong) { return (current == secondary) ? primary : secondary; } return (current == primary) ? secondary : primary; } private static int ChooseDirection(int heldMask, int downMask) { if (BitCount(downMask) == 1) { lastChosenDirMask = downMask; return downMask; } if (BitCount(heldMask) == 1) { lastChosenDirMask = heldMask; return heldMask; } if (heldMask != 0 && lastChosenDirMask != 0 && (heldMask & lastChosenDirMask) != 0) { return lastChosenDirMask; } return 0; } private static int BitCount(int x) { int num = 0; while (x != 0) { x &= x - 1; num++; } return num; } private static string GetBestHunterName() { try { if ((Object)(object)Gameplay.HunterCrest3 != (Object)null && Gameplay.HunterCrest3.IsUnlocked) { return Gameplay.HunterCrest3.name; } } catch { } try { if ((Object)(object)Gameplay.HunterCrest2 != (Object)null && Gameplay.HunterCrest2.IsUnlocked) { return Gameplay.HunterCrest2.name; } } catch { } return Gameplay.HunterCrest.name; } private static void ApplyInvincibilitySafe(float seconds) { if (seconds <= 0f || (Object)(object)hero == (Object)null) { return; } try { if (ReflectionCache.mi_AddInvincibleTime == null) { ReflectionCache.Initialize(hero); } if (ReflectionCache.mi_AddInvincibleTime != null) { ReflectionCache.mi_AddInvincibleTime.Invoke(hero, new object[1] { seconds }); } else if (ReflectionCache.fi_invincibleTimer != null) { float num = (float)ReflectionCache.fi_invincibleTimer.GetValue(hero); ReflectionCache.fi_invincibleTimer.SetValue(hero, Mathf.Max(num, seconds)); } } catch { } } [HarmonyPatch(typeof(HeroController), "Awake")] [HarmonyPostfix] private static void HeroAwakePostfix(HeroController __instance) { hero = __instance; ReflectionCache.Initialize(hero); InputAdapter.Initialize(hero); } } [HarmonyPatch(typeof(ToolItemManager), "TryReplenishTools")] public static class BenchReplenishPatch { private static bool isLoopingRefills; public static bool Prefix(ref bool doReplenish, ReplenishMethod method) { //IL_017c: Unknown result type (might be due to invalid IL or missing references) if (isLoopingRefills) { return true; } if (((object)(ReplenishMethod)(ref method)).ToString().IndexOf("Bench", StringComparison.OrdinalIgnoreCase) < 0) { return true; } doReplenish = true; try { isLoopingRefills = true; HeroController instance = HeroController.instance; if ((Object)(object)instance == (Object)null || instance.playerData == null) { return true; } string currentCrestID = instance.playerData.CurrentCrestID; List list = new List { Gameplay.ToolmasterCrest.name, "Yen", Gameplay.SpellCrest.name, Gameplay.HunterCrest.name, Gameplay.ReaperCrest.name, Gameplay.WarriorCrest.name, Gameplay.WandererCrest.name, Gameplay.WitchCrest.name }; foreach (string item in list) { ToolCrest crestByName = ToolItemManager.GetCrestByName(item); if (!((Object)(object)crestByName == (Object)null) && crestByName.IsUnlocked && !crestByName.IsHidden && !(crestByName.name == currentCrestID)) { instance.ResetAllCrestState(); ToolItemManager.SetEquippedCrest(crestByName.name); ToolItemManager.TryReplenishTools(true, method); } } instance.ResetAllCrestState(); ToolItemManager.SetEquippedCrest(currentCrestID); ToolItemManager.SendEquippedChangedEvent(true); return true; } finally { isLoopingRefills = false; } } }