using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GlobalSettings; using InControl; using UnityEngine; using UnityEngine.UI; [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("CrestWheel")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: AssemblyInformationalVersion("1.1.1")] [assembly: AssemblyProduct("CrestWheel")] [assembly: AssemblyTitle("CrestWheel")] [assembly: AssemblyVersion("1.1.1.0")] namespace CrestWheel; public enum ControllerActivationButton { Disabled, LeftStickButton, RightStickButton, DPadUp, DPadDown, DPadLeft, DPadRight, LeftTrigger, RightTrigger, LeftBumper, RightBumper, Action1, Action2, Action3, Action4, Action5, Action6, Action7, Action8, Action9, Action10, Action11, Action12, Back, Start, Select, Options, Pause, Menu, View, Share, Home, Plus, Minus, Create, Capture, TouchPadButton, Paddle1, Paddle2, Paddle3, Paddle4, Command, LeftCommand, RightCommand } public enum ControllerSelectionInput { RightStick, LeftStick, DPad, None } internal enum ActivationSource { None, Controller, Keyboard } [BepInPlugin("moriko.silksong.crestwheel", "Crest Wheel", "1.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class CrestWheelPlugin : BaseUnityPlugin { public const string PluginGuid = "moriko.silksong.crestwheel"; public const string PluginName = "Crest Wheel"; public const string PluginVersion = "1.1.1"; private const float OpeningAnimationDuration = 0.25f; private static readonly string[] FixedCrestSlotNames = new string[7] { "Hunter", "Wanderer", "Reaper", "Warrior", "Toolmaster", "Witch", "Spell" }; private static readonly FieldInfo InputActionsField = typeof(InputHandler).GetField("inputActions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo InputBlockersField = typeof(HeroController).GetField("inputBlockers", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo HeroRendererField = typeof(HeroController).GetField("renderer", BindingFlags.Instance | BindingFlags.NonPublic); private readonly List entries = new List(); private ConfigEntry enabledConfig; private ConfigEntry controllerActivationButtonConfig; private ConfigEntry controllerSelectionInputConfig; private ConfigEntry activationHoldDurationConfig; private ConfigEntry deadzoneConfig; private ConfigEntry keyboardActivationKeyConfig; private ConfigEntry keyboardUpKeyConfig; private ConfigEntry keyboardDownKeyConfig; private ConfigEntry keyboardLeftKeyConfig; private ConfigEntry keyboardRightKeyConfig; private ConfigEntry keyboardCancelKeyConfig; private ConfigEntry wheelScaleConfig; private ConfigEntry backgroundDimConfig; private ConfigEntry settingsRevisionConfig; private RandomizerCompatibility randomizer; private CrestWheelView view; private HeroController blockedHero; private InputDevice activationDevice; private InputControl activationControl; private ActivationSource activationSource; private bool isOpen; private bool isActivationPending; private bool hasAimed; private int selectedIndex; private int equippedIndex; private float openProgress; private float activationHeldTime; private bool keyboardActivationPressed; private bool keyboardActivationWasPressed; private bool keyboardActivationWasReleased; private bool keyboardCancelPressed; private bool keyboardCancelWasPressed; internal static CrestWheelPlugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Expected O, but got Unknown //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Expected O, but got Unknown //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Invalid comparison between Unknown and I4 //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Invalid comparison between Unknown and I4 //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Invalid comparison between Unknown and I4 //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Invalid comparison between Unknown and I4 //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Invalid comparison between Unknown and I4 Instance = this; Log = ((BaseUnityPlugin)this).Logger; enabledConfig = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Enable the crest wheel."); controllerActivationButtonConfig = ((BaseUnityPlugin)this).Config.Bind("Controller", "Activation Button", ControllerActivationButton.LeftStickButton, "Controller button held to open the wheel and released to equip. Set Disabled for keyboard-only use."); activationHoldDurationConfig = ((BaseUnityPlugin)this).Config.Bind("Controller", "Hold Duration", 0f, new ConfigDescription("How many seconds the configured controller button or keyboard key must be held before the wheel begins opening. Set to 0 for immediate opening.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); controllerSelectionInputConfig = ((BaseUnityPlugin)this).Config.Bind("Controller", "Selection Input", ControllerSelectionInput.RightStick, "Controller input used to aim around the wheel."); deadzoneConfig = ((BaseUnityPlugin)this).Config.Bind("Controller", "Selection Deadzone", 0.45f, new ConfigDescription("How far an analog selection stick must move before a crest is selected.", (AcceptableValueBase)(object)new AcceptableValueRange(0.15f, 0.9f), Array.Empty())); keyboardActivationKeyConfig = ((BaseUnityPlugin)this).Config.Bind("Keyboard", "Activation Key", (Key)4, "Keyboard key held to open the wheel and released to equip. Set None to disable keyboard activation."); keyboardUpKeyConfig = ((BaseUnityPlugin)this).Config.Bind("Keyboard", "Selection Up", (Key)58, "Keyboard key used to aim upward."); keyboardDownKeyConfig = ((BaseUnityPlugin)this).Config.Bind("Keyboard", "Selection Down", (Key)54, "Keyboard key used to aim downward."); keyboardLeftKeyConfig = ((BaseUnityPlugin)this).Config.Bind("Keyboard", "Selection Left", (Key)36, "Keyboard key used to aim left."); keyboardRightKeyConfig = ((BaseUnityPlugin)this).Config.Bind("Keyboard", "Selection Right", (Key)39, "Keyboard key used to aim right."); keyboardCancelKeyConfig = ((BaseUnityPlugin)this).Config.Bind("Keyboard", "Cancel Key", (Key)13, "Keyboard key that closes the wheel without switching. Set None to rely on the game's normal cancel binding."); wheelScaleConfig = ((BaseUnityPlugin)this).Config.Bind("Appearance", "Wheel Scale", 1f, new ConfigDescription("Scale of the crest wheel.", (AcceptableValueBase)(object)new AcceptableValueRange(0.65f, 1.5f), Array.Empty())); backgroundDimConfig = ((BaseUnityPlugin)this).Config.Bind("Appearance", "Background Dimming", 0.24f, new ConfigDescription("Opacity of the screen dim behind the wheel.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 0.8f), Array.Empty())); settingsRevisionConfig = ((BaseUnityPlugin)this).Config.Bind("Internal", "Settings Revision", 0, "Tracks one-time migrations of development-build defaults."); if (settingsRevisionConfig.Value < 1) { if (Mathf.Approximately(backgroundDimConfig.Value, 0.42f)) { backgroundDimConfig.Value = 0.24f; } settingsRevisionConfig.Value = 1; ((BaseUnityPlugin)this).Config.Save(); } if (settingsRevisionConfig.Value < 2) { if ((int)keyboardActivationKeyConfig.Value == 8 && (int)keyboardUpKeyConfig.Value == 85 && (int)keyboardDownKeyConfig.Value == 86 && (int)keyboardLeftKeyConfig.Value == 83 && (int)keyboardRightKeyConfig.Value == 84) { keyboardActivationKeyConfig.Value = (Key)4; keyboardUpKeyConfig.Value = (Key)58; keyboardDownKeyConfig.Value = (Key)54; keyboardLeftKeyConfig.Value = (Key)36; keyboardRightKeyConfig.Value = (Key)39; } settingsRevisionConfig.Value = 2; ((BaseUnityPlugin)this).Config.Save(); } randomizer = new RandomizerCompatibility(((BaseUnityPlugin)this).Logger); if (InputActionsField == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Crest Wheel could not locate InputHandler.inputActions; the game's normal menu-cancel binding will be unavailable, but configured wheel bindings will still work."); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Crest Wheel 1.1.1 loaded. Controller: " + $"{controllerActivationButtonConfig.Value} + " + $"{controllerSelectionInputConfig.Value}; keyboard: " + $"{keyboardActivationKeyConfig.Value} + " + $"{keyboardUpKeyConfig.Value}/" + $"{keyboardLeftKeyConfig.Value}/" + $"{keyboardDownKeyConfig.Value}/" + $"{keyboardRightKeyConfig.Value}; " + $"hold duration: {GetActivationHoldDuration():0.00}s.")); } private void Update() { //IL_010b: Unknown result type (might be due to invalid IL or missing references) RefreshKeyboardState(); HeroActions heroActions = GetHeroActions(); if (!enabledConfig.Value) { CloseWheel(); return; } if (!isOpen) { InputDevice device; InputControl control; if (!CanOpenNow()) { CancelPendingActivation(); } else if (isActivationPending) { if (WasActivationReleased() || !IsActivationPressed()) { CancelPendingActivation(); return; } activationHeldTime += Time.unscaledDeltaTime; if (activationHeldTime >= GetActivationHoldDuration()) { isActivationPending = false; activationHeldTime = 0f; if (!TryOpenWheel()) { ClearActivationSource(); } } } else if (TryGetPressedControllerActivation(out device, out control)) { BeginActivation(ActivationSource.Controller, device, control); } else if (keyboardActivationWasPressed) { BeginActivation(ActivationSource.Keyboard, null, null); } return; } openProgress = Mathf.MoveTowards(openProgress, 1f, Time.unscaledDeltaTime / 0.25f); view?.SetOpenProgress(openProgress); if (!CanRemainOpen()) { CloseWheel(); return; } UpdateSelection(GetSelectionInput()); if (keyboardCancelWasPressed || WasNativeCancelPressed(heroActions)) { CloseWheel(); } else if (WasActivationReleased() || !IsActivationPressed()) { if (openProgress >= 1f && hasAimed) { ConfirmSelection(); } else { CloseWheel(); } } } private void RefreshKeyboardState() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) bool flag = keyboardActivationPressed; ConfigEntry obj = keyboardActivationKeyConfig; keyboardActivationPressed = IsKeyboardKeyPressed((Key)((obj != null) ? ((int)obj.Value) : 0)); keyboardActivationWasPressed = keyboardActivationPressed && !flag; keyboardActivationWasReleased = !keyboardActivationPressed && flag; bool flag2 = keyboardCancelPressed; ConfigEntry obj2 = keyboardCancelKeyConfig; keyboardCancelPressed = IsKeyboardKeyPressed((Key)((obj2 != null) ? ((int)obj2.Value) : 0)); keyboardCancelWasPressed = keyboardCancelPressed && !flag2; } private static bool IsKeyboardKeyPressed(Key key) { //IL_0000: 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) if ((int)key == 0) { return false; } try { return InputManager.KeyboardProvider != null && InputManager.KeyboardProvider.GetKeyIsPressed(key); } catch { return false; } } private void BeginActivation(ActivationSource source, InputDevice device, InputControl control) { activationSource = source; activationDevice = device; activationControl = control; activationHeldTime = 0f; if (GetActivationHoldDuration() <= 0f) { if (!TryOpenWheel()) { ClearActivationSource(); } } else { isActivationPending = true; } } private bool TryGetPressedControllerActivation(out InputDevice device, out InputControl control) { //IL_0007: 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_000d: 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) device = null; control = null; InputControlType controllerActivationControlType = GetControllerActivationControlType(); if ((int)controllerActivationControlType == 0) { return false; } try { InputDevice activeDevice = InputManager.ActiveDevice; if (activeDevice == null) { return false; } InputControl val = activeDevice[controllerActivationControlType]; if (val == null || !((OneAxisInputControl)val).WasPressed) { return false; } device = activeDevice; control = val; return true; } catch { return false; } } private InputControlType GetControllerActivationControlType() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) ControllerActivationButton controllerActivationButton = controllerActivationButtonConfig?.Value ?? ControllerActivationButton.LeftStickButton; if (controllerActivationButton == ControllerActivationButton.Disabled) { return (InputControlType)0; } if (!Enum.TryParse(controllerActivationButton.ToString(), out InputControlType result)) { return (InputControlType)5; } return result; } private Vector2 GetSelectionInput() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0078: Unknown result type (might be due to invalid IL or missing references) Vector2 keyboardSelectionInput = GetKeyboardSelectionInput(); Vector2 result = Vector2.zero; try { InputDevice val = activationDevice ?? InputManager.ActiveDevice; if (val != null) { result = (Vector2)((controllerSelectionInputConfig?.Value ?? ControllerSelectionInput.RightStick) switch { ControllerSelectionInput.LeftStick => val.LeftStick.Vector, ControllerSelectionInput.DPad => val.DPad.Vector, ControllerSelectionInput.None => Vector2.zero, _ => val.RightStick.Vector, }); } } catch { result = Vector2.zero; } if (!(((Vector2)(ref keyboardSelectionInput)).sqrMagnitude >= ((Vector2)(ref result)).sqrMagnitude)) { return result; } return keyboardSelectionInput; } private Vector2 GetKeyboardSelectionInput() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) float num = 0f; float num2 = 0f; ConfigEntry obj = keyboardLeftKeyConfig; if (IsKeyboardKeyPressed((Key)((obj == null) ? 36 : ((int)obj.Value)))) { num -= 1f; } ConfigEntry obj2 = keyboardRightKeyConfig; if (IsKeyboardKeyPressed((Key)((obj2 == null) ? 39 : ((int)obj2.Value)))) { num += 1f; } ConfigEntry obj3 = keyboardDownKeyConfig; if (IsKeyboardKeyPressed((Key)((obj3 == null) ? 54 : ((int)obj3.Value)))) { num2 -= 1f; } ConfigEntry obj4 = keyboardUpKeyConfig; if (IsKeyboardKeyPressed((Key)((obj4 == null) ? 58 : ((int)obj4.Value)))) { num2 += 1f; } return new Vector2(num, num2); } private static bool WasNativeCancelPressed(HeroActions actions) { try { return actions != null && ((OneAxisInputControl)actions.MenuCancel).WasPressed; } catch { return false; } } private void LateUpdate() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (isOpen && (Object)(object)blockedHero != (Object)null) { view?.SetWorldCenter(GetHeroCenter(blockedHero)); } } private void OnDisable() { CloseWheel(); } private void OnDestroy() { CloseWheel(); view?.Dispose(); view = null; if (Instance == this) { Instance = null; Log = null; } } private bool TryOpenWheel() { //IL_011c: Unknown result type (might be due to invalid IL or missing references) if (isOpen || !CanOpenNow()) { return false; } try { BuildFixedCrestSlots(); if (entries.Count != FixedCrestSlotNames.Length) { return false; } PlayerData instance = PlayerData.instance; equippedIndex = FindEntryIndex(instance.CurrentCrestID); if (equippedIndex < 0 || !entries[equippedIndex].IsOwned) { return false; } selectedIndex = equippedIndex; hasAimed = false; openProgress = 0f; blockedHero = HeroController.instance; blockedHero.AddInputBlocker((object)this); blockedHero.move_input = 0f; blockedHero.vertical_input = 0f; if (view == null) { view = new CrestWheelView(); } view.Show(entries, equippedIndex, selectedIndex, hasAimed: false, wheelScaleConfig.Value, backgroundDimConfig.Value); view.SetWorldCenter(GetHeroCenter(blockedHero)); isOpen = true; return true; } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Could not open the crest wheel: {arg}"); ReleaseInputBlocker(); ClearActivationSource(); view?.Hide(); entries.Clear(); isOpen = false; return false; } } private void UpdateSelection(Vector2 input) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp(deadzoneConfig.Value, 0.15f, 0.9f); if (((Vector2)(ref input)).sqrMagnitude < num * num || entries.Count == 0) { if (hasAimed) { hasAimed = false; view?.SetSelection(selectedIndex, equippedIndex, hasAimed: false); } return; } int num2 = Mathf.RoundToInt(Mathf.Repeat(90f - Mathf.Atan2(input.y, input.x) * 57.29578f, 360f) / (360f / (float)entries.Count)) % entries.Count; bool num3 = num2 != selectedIndex || !hasAimed; selectedIndex = num2; hasAimed = true; if (num3) { view?.SetSelection(selectedIndex, equippedIndex, hasAimed: true); } } private void ConfirmSelection() { if (isOpen) { ToolCrest val = ((hasAimed && selectedIndex >= 0 && selectedIndex < entries.Count && entries[selectedIndex].IsOwned) ? entries[selectedIndex].Crest : null); CloseWheel(); if ((Object)(object)val != (Object)null) { TryEquipCrest(val); } } } private void CloseWheel() { isOpen = false; isActivationPending = false; view?.Hide(); NeutralizeHeroAxes(blockedHero); ReleaseInputBlocker(); entries.Clear(); hasAimed = false; openProgress = 0f; activationHeldTime = 0f; ClearActivationSource(); } private void CancelPendingActivation() { isActivationPending = false; activationHeldTime = 0f; ClearActivationSource(); } private void ClearActivationSource() { activationSource = ActivationSource.None; activationDevice = null; activationControl = null; } private float GetActivationHoldDuration() { return Mathf.Clamp(activationHoldDurationConfig?.Value ?? 0f, 0f, 5f); } private bool TryEquipCrest(ToolCrest requestedCrest) { if ((Object)(object)requestedCrest == (Object)null || !CanRemainOpen()) { return false; } string name = requestedCrest.name; BuildFixedCrestSlots(); int num = FindEntryIndex(name); if (num < 0 || !entries[num].IsOwned || randomizer.IsSwitchBlocked()) { return false; } ToolCrest crest = entries[num].Crest; PlayerData instance = PlayerData.instance; HeroController instance2 = HeroController.instance; if ((Object)(object)crest == (Object)null || instance == null || (Object)(object)instance2 == (Object)null) { return false; } if (string.Equals(instance.CurrentCrestID, crest.name, StringComparison.Ordinal)) { return true; } try { ToolItemManager.SetEquippedCrest(crest.name); instance.IsCurrentCrestTemp = false; ToolItemManager.RefreshEquippedState(); ToolItemManager.SendEquippedChangedEvent(true); randomizer.AfterCrestEquipped(); NeutralizeHeroAxes(instance2); bool num2 = string.Equals(instance.CurrentCrestID, crest.name, StringComparison.Ordinal); if (num2) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Equipped crest from wheel: " + crest.name)); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Crest switch was rejected: " + crest.name)); } return num2; } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Could not equip crest '{crest.name}': {arg}"); return false; } } private void BuildFixedCrestSlots() { entries.Clear(); randomizer.RefreshSnapshot(); List allCrests = ToolItemManager.GetAllCrests(); if (allCrests == null) { return; } List[] array = new List[FixedCrestSlotNames.Length]; for (int i = 0; i < array.Length; i++) { array[i] = new List(); } foreach (ToolCrest item in allCrests) { if (!((Object)(object)item == (Object)null) && !string.IsNullOrEmpty(item.name) && !IsTemporarySpecialCrest(item)) { int fixedCrestSlotIndex = GetFixedCrestSlotIndex(item.name); if (fixedCrestSlotIndex >= 0) { array[fixedCrestSlotIndex].Add(item); } } } string currentCrestId = PlayerData.instance?.CurrentCrestID; for (int j = 0; j < FixedCrestSlotNames.Length; j++) { ToolCrest crest = ChooseCrestForFixedSlot(array[j], currentCrestId); entries.Add(new CrestEntry(crest, FixedCrestSlotNames[j], j, IsCrestSelectable(crest, currentCrestId))); } } private ToolCrest ChooseCrestForFixedSlot(List candidates, string currentCrestId) { if (candidates == null || candidates.Count == 0) { return null; } ToolCrest val = null; ToolCrest val2 = null; ToolCrest val3 = null; for (int i = 0; i < candidates.Count; i++) { ToolCrest val4 = candidates[i]; if (!((Object)(object)val4 == (Object)null)) { if (string.Equals(val4.name, currentCrestId, StringComparison.Ordinal)) { return val4; } if (IsCrestSelectable(val4, currentCrestId)) { val = val4; } if ((Object)(object)val2 == (Object)null && val4.IsBaseVersion) { val2 = val4; } if ((Object)(object)val3 == (Object)null && val4.IsVisible && !val4.IsHidden) { val3 = val4; } } } return val ?? val2 ?? val3 ?? candidates[0]; } private bool IsCrestSelectable(ToolCrest crest, string currentCrestId) { if ((Object)(object)crest == (Object)null || crest.IsHidden || !crest.IsUnlocked) { return false; } bool flag = string.Equals(crest.name, currentCrestId, StringComparison.Ordinal); if (crest.IsVisible || flag) { return randomizer.IsCrestOwned(crest); } return false; } private static bool IsTemporarySpecialCrest(ToolCrest crest) { if ((Object)(object)crest == (Object)null) { return false; } try { if (crest == Gameplay.CursedCrest || crest == Gameplay.CloaklessCrest) { return true; } } catch { } string text = crest.name ?? string.Empty; if (text.IndexOf("Cloakless", StringComparison.OrdinalIgnoreCase) < 0) { return text.IndexOf("Cursed", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private int FindEntryIndex(string crestName) { int fixedCrestSlotIndex = GetFixedCrestSlotIndex(crestName); if (fixedCrestSlotIndex < 0 || fixedCrestSlotIndex >= entries.Count) { return -1; } if (entries[fixedCrestSlotIndex].FixedSlotIndex != fixedCrestSlotIndex) { return -1; } return fixedCrestSlotIndex; } private static int GetFixedCrestSlotIndex(string crestName) { if (string.IsNullOrEmpty(crestName)) { return -1; } if (crestName.StartsWith("Hunter", StringComparison.OrdinalIgnoreCase)) { return 0; } for (int i = 1; i < FixedCrestSlotNames.Length; i++) { if (string.Equals(FixedCrestSlotNames[i], crestName, StringComparison.OrdinalIgnoreCase)) { return i; } } return -1; } private bool CanOpenNow() { if (CanUseWheelRuntime() && (Object)(object)HeroController.instance != (Object)null) { return !HeroController.instance.IsInputBlocked(); } return false; } private bool CanRemainOpen() { if (CanUseWheelRuntime()) { return !HasForeignInputBlocker(); } return false; } private bool CanUseWheelRuntime() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 try { GameManager silentInstance = GameManager.SilentInstance; HeroController instance = HeroController.instance; PlayerData instance2 = PlayerData.instance; return (Object)(object)silentInstance != (Object)null && (int)silentInstance.GameState == 4 && silentInstance.IsGameplayScene() && (Object)(object)instance != (Object)null && instance.CanTakeControl() && instance2 != null && !instance2.IsCurrentCrestTemp && !instance2.IsAnyCursed && !ToolItemManager.IsCursed && !ToolItemManager.IsInCutscene && !ToolItemManager.IsChangingActiveState && !randomizer.IsSwitchBlocked(); } catch { return false; } } private bool HasForeignInputBlocker() { HeroController instance = HeroController.instance; if ((Object)(object)instance == (Object)null || InputBlockersField == null) { return false; } try { if (!(InputBlockersField.GetValue(instance) is IEnumerable enumerable)) { return false; } foreach (object item in enumerable) { Object val = (Object)((item is Object) ? item : null); if ((val == null || !(val == (Object)null)) && item != null && item != this) { return true; } } } catch { } return false; } private static HeroActions GetHeroActions() { try { GameManager silentInstance = GameManager.SilentInstance; InputHandler val = ((silentInstance != null) ? silentInstance.inputHandler : null); return (HeroActions)(((Object)(object)val == (Object)null || InputActionsField == null) ? null : /*isinst with value type is only supported in some contexts*/); } catch { return null; } } private bool WasActivationReleased() { if (activationSource == ActivationSource.Keyboard) { return keyboardActivationWasReleased; } if (activationSource != ActivationSource.Controller) { return false; } try { return activationControl != null && ((OneAxisInputControl)activationControl).WasReleased; } catch { return false; } } private bool IsActivationPressed() { if (activationSource == ActivationSource.Keyboard) { return keyboardActivationPressed; } if (activationSource != ActivationSource.Controller) { return false; } try { return activationControl != null && ((OneAxisInputControl)activationControl).IsPressed; } catch { return false; } } private static Vector3 GetHeroCenter(HeroController hero) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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) //IL_0046: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hero == (Object)null) { return Vector3.zero; } try { Bounds bounds = hero.Bounds; Vector3 center = ((Bounds)(ref bounds)).center; object? obj = HeroRendererField?.GetValue(hero); Renderer val = (Renderer)((obj is Renderer) ? obj : null); if ((Object)(object)val != (Object)null) { bounds = val.bounds; if (((Bounds)(ref bounds)).size.y > 0f) { bounds = val.bounds; center.y = ((Bounds)(ref bounds)).center.y; } } return center; } catch { return ((Component)hero).transform.position + Vector3.up; } } private static void NeutralizeHeroAxes(HeroController hero) { if ((Object)(object)hero == (Object)null) { return; } try { hero.move_input = 0f; hero.vertical_input = 0f; } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("Could not neutralize input after crest wheel: " + ex.Message)); } } } private void ReleaseInputBlocker() { if ((Object)(object)blockedHero == (Object)null) { return; } try { blockedHero.RemoveInputBlocker((object)this); } catch { } finally { blockedHero = null; } } } internal sealed class CrestEntry { internal ToolCrest Crest { get; } internal string InternalName { get; } internal string SlotName { get; } internal int FixedSlotIndex { get; } internal bool IsOwned { get; } internal Sprite Sprite { get { if ((Object)(object)Crest == (Object)null) { return null; } if (!((Object)(object)Crest.CrestSilhouette != (Object)null)) { return Crest.CrestSprite; } return Crest.CrestSilhouette; } } internal CrestEntry(ToolCrest crest, string slotName, int fixedSlotIndex, bool isOwned) { Crest = crest; InternalName = ((crest != null) ? crest.name : null) ?? slotName ?? string.Empty; SlotName = slotName ?? InternalName; FixedSlotIndex = fixedSlotIndex; IsOwned = isOwned; } } internal sealed class CrestWheelView : IDisposable { private static readonly Color NormalIcon = new Color(0.58f, 0.56f, 0.52f, 0.92f); private static readonly Color EquippedIcon = new Color(0.8f, 0.74f, 0.6f, 1f); private static readonly Color SelectedIcon = new Color(0.95f, 0.87f, 0.76f, 1f); private static readonly Color LockedIcon = new Color(0.36f, 0.37f, 0.39f, 0.46f); private static readonly Color LockedHoveredIcon = new Color(0.46f, 0.47f, 0.49f, 0.68f); private readonly List iconRoots = new List(); private readonly List iconImages = new List(); private readonly List entries = new List(); private GameObject canvasObject; private GameObject wheelObject; private RectTransform canvasRect; private RectTransform wheelRect; private CanvasGroup canvasGroup; private Image dimImage; private RadialRingGraphic ringGraphic; private float configuredScale = 1f; internal void Show(IReadOnlyList sourceEntries, int equippedIndex, int selectedIndex, bool hasAimed, float scale, float dimAmount) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) EnsureCanvas(); entries.Clear(); for (int i = 0; i < sourceEntries.Count; i++) { entries.Add(sourceEntries[i]); } configuredScale = Mathf.Clamp(scale, 0.65f, 1.5f); ((Graphic)dimImage).color = new Color(0.008f, 0.006f, 0.012f, Mathf.Clamp(dimAmount, 0f, 0.8f)); BuildIcons(); ringGraphic.Configure(entries, selectedIndex, equippedIndex, hasAimed); SetSelection(selectedIndex, equippedIndex, hasAimed); canvasGroup.alpha = 0f; wheelObject.transform.localScale = Vector3.one * configuredScale * 0.94f; canvasObject.SetActive(true); } internal void SetWorldCenter(Vector3 worldCenter) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_008f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)canvasObject == (Object)null || !canvasObject.activeSelf || (Object)(object)canvasRect == (Object)null || (Object)(object)wheelRect == (Object)null) { return; } Camera val = GameCameras.SilentInstance?.mainCamera ?? Camera.main; if (!((Object)(object)val == (Object)null)) { Vector3 val2 = val.WorldToScreenPoint(worldCenter); Vector2 anchoredPosition = default(Vector2); if (!(val2.z <= 0f) && RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, Vector2.op_Implicit(val2), (Camera)null, ref anchoredPosition)) { wheelRect.anchoredPosition = anchoredPosition; } } } internal void SetSelection(int selectedIndex, int equippedIndex, bool hasAimed) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) if (entries.Count != 0 && selectedIndex >= 0 && selectedIndex < entries.Count) { ringGraphic.Configure(entries, selectedIndex, equippedIndex, hasAimed); for (int i = 0; i < iconRoots.Count; i++) { bool flag = hasAimed && i == selectedIndex; bool flag2 = i == equippedIndex; bool isOwned = entries[i].IsOwned; iconRoots[i].transform.localScale = Vector3.one * (flag ? (isOwned ? 1.08f : 1.03f) : 1f); ((Behaviour)iconImages[i]).enabled = (Object)(object)iconImages[i].sprite != (Object)null; ((Graphic)iconImages[i]).color = ((!isOwned) ? (flag ? LockedHoveredIcon : LockedIcon) : (flag ? SelectedIcon : (flag2 ? EquippedIcon : NormalIcon))); } } } internal void SetOpenProgress(float progress) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)canvasObject == (Object)null) && canvasObject.activeSelf) { float num = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01(progress)); canvasGroup.alpha = num; wheelObject.transform.localScale = Vector3.one * configuredScale * Mathf.Lerp(0.94f, 1f, num); } } internal void Hide() { if ((Object)(object)canvasObject != (Object)null) { canvasObject.SetActive(false); } } public void Dispose() { if ((Object)(object)canvasObject != (Object)null) { Object.Destroy((Object)(object)canvasObject); canvasObject = null; } } private void EnsureCanvas() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: 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_0219: Expected O, but got Unknown //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)canvasObject != (Object)null)) { canvasObject = new GameObject("CrestWheel.Canvas", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(CanvasGroup) }); Object.DontDestroyOnLoad((Object)(object)canvasObject); canvasRect = canvasObject.GetComponent(); Canvas component = canvasObject.GetComponent(); component.renderMode = (RenderMode)0; component.sortingOrder = 32000; CanvasScaler component2 = canvasObject.GetComponent(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1920f, 1080f); component2.screenMatchMode = (ScreenMatchMode)0; component2.matchWidthOrHeight = 0.5f; canvasGroup = canvasObject.GetComponent(); canvasGroup.interactable = false; canvasGroup.blocksRaycasts = false; dimImage = CreateImage("Dim", canvasObject.transform, null); StretchToParent(((Graphic)dimImage).rectTransform); wheelObject = new GameObject("Wheel", new Type[1] { typeof(RectTransform) }); wheelRect = wheelObject.GetComponent(); ((Transform)wheelRect).SetParent(canvasObject.transform, false); wheelRect.anchorMin = new Vector2(0.5f, 0.5f); wheelRect.anchorMax = new Vector2(0.5f, 0.5f); wheelRect.pivot = new Vector2(0.5f, 0.5f); wheelRect.sizeDelta = new Vector2(480f, 480f); wheelRect.anchoredPosition = Vector2.zero; GameObject val = new GameObject("Segments", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(RadialRingGraphic) }); RectTransform component3 = val.GetComponent(); ((Transform)component3).SetParent((Transform)(object)wheelRect, false); component3.anchorMin = new Vector2(0.5f, 0.5f); component3.anchorMax = new Vector2(0.5f, 0.5f); component3.pivot = new Vector2(0.5f, 0.5f); component3.sizeDelta = new Vector2(440f, 440f); component3.anchoredPosition = Vector2.zero; ringGraphic = val.GetComponent(); ((Graphic)ringGraphic).raycastTarget = false; canvasObject.SetActive(false); } } private void BuildIcons() { //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < iconRoots.Count; i++) { if ((Object)(object)iconRoots[i] != (Object)null) { iconRoots[i].SetActive(false); Object.Destroy((Object)(object)iconRoots[i]); } } iconRoots.Clear(); iconImages.Clear(); int count = entries.Count; if (count != 0) { float num = 176f; float num2 = Mathf.Clamp(MathF.PI * 2f * num / (float)count * 0.34f, 42f, 60f); RectTransform component = wheelObject.GetComponent(); Vector2 anchoredPosition = default(Vector2); for (int j = 0; j < count; j++) { float num3 = (90f - (float)j * (360f / (float)count)) * (MathF.PI / 180f); ((Vector2)(ref anchoredPosition))..ctor(Mathf.Cos(num3) * num, Mathf.Sin(num3) * num); GameObject val = new GameObject("Crest " + entries[j].InternalName, new Type[1] { typeof(RectTransform) }); RectTransform component2 = val.GetComponent(); ((Transform)component2).SetParent((Transform)(object)component, false); component2.anchorMin = new Vector2(0.5f, 0.5f); component2.anchorMax = new Vector2(0.5f, 0.5f); component2.pivot = new Vector2(0.5f, 0.5f); component2.sizeDelta = new Vector2(num2 + 8f, num2 + 8f); component2.anchoredPosition = anchoredPosition; Image val2 = CreateImage("Icon", (Transform)(object)component2, entries[j].Sprite); SetCenteredRect(((Graphic)val2).rectTransform, num2, num2, Vector2.zero); val2.preserveAspect = true; ((Behaviour)val2).enabled = (Object)(object)val2.sprite != (Object)null; iconRoots.Add(val); iconImages.Add(val2); } } } private static Image CreateImage(string name, Transform parent, Sprite sprite) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); ((Transform)val.GetComponent()).SetParent(parent, false); Image component = val.GetComponent(); component.sprite = sprite; ((Graphic)component).raycastTarget = false; return component; } private static void StretchToParent(RectTransform rect) { //IL_0001: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.offsetMin = Vector2.zero; rect.offsetMax = Vector2.zero; } private static void SetCenteredRect(RectTransform rect, float width, float height, Vector2 position) { //IL_000b: 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) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = new Vector2(0.5f, 0.5f); rect.anchorMax = new Vector2(0.5f, 0.5f); rect.pivot = new Vector2(0.5f, 0.5f); rect.sizeDelta = new Vector2(width, height); rect.anchoredPosition = position; } } public sealed class RadialRingGraphic : MaskableGraphic { private int segmentCount; private int selectedIndex; private int equippedIndex; private bool hasSelection; private bool[] ownedSlots = Array.Empty(); internal void Configure(IReadOnlyList entries, int selected, int equipped, bool selectionActive) { segmentCount = entries?.Count ?? 0; selectedIndex = selected; equippedIndex = equipped; hasSelection = selectionActive; if (ownedSlots.Length != segmentCount) { ownedSlots = new bool[segmentCount]; } for (int i = 0; i < segmentCount; i++) { ownedSlots[i] = entries[i].IsOwned; } ((Graphic)this).SetVerticesDirty(); } protected override void OnPopulateMesh(VertexHelper vertexHelper) { //IL_0011: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) vertexHelper.Clear(); if (segmentCount <= 0) { return; } Rect pixelAdjustedRect = ((Graphic)this).GetPixelAdjustedRect(); Vector2 center = ((Rect)(ref pixelAdjustedRect)).center; float num = Mathf.Min(((Rect)(ref pixelAdjustedRect)).width, ((Rect)(ref pixelAdjustedRect)).height) * 0.47f; float num2 = num - 62f; float num3 = 360f / (float)segmentCount; float num4 = Mathf.Min(1.25f, num3 * 0.035f); int curveSteps = Mathf.Clamp(Mathf.CeilToInt(num3 / 3.5f), 8, 64); for (int i = 0; i < segmentCount; i++) { bool flag = i < ownedSlots.Length && ownedSlots[i]; bool flag2 = hasSelection && i == selectedIndex; bool num5 = i == equippedIndex; Color32 color = Color32.op_Implicit(flag ? (flag2 ? new Color(0.25f, 0.055f, 0.075f, 0.9f) : new Color(0.035f, 0.032f, 0.04f, 0.8f)) : (flag2 ? new Color(0.065f, 0.065f, 0.075f, 0.62f) : new Color(0.018f, 0.018f, 0.023f, 0.46f))); float num6 = 90f - (float)i * num3; float startDegrees = num6 - num3 * 0.5f + num4 * 0.5f; float endDegrees = num6 + num3 * 0.5f - num4 * 0.5f; AddArcStrip(vertexHelper, center, num2, num, startDegrees, endDegrees, curveSteps, color); if (num5 && flag) { float num7 = Mathf.Min(22f, num3 * 0.28f); int curveSteps2 = Mathf.Clamp(Mathf.CeilToInt(num7 / 2.5f), 4, 12); AddArcStrip(vertexHelper, center, num2 + 3f, num2 + 7f, num6 - num7 * 0.5f, num6 + num7 * 0.5f, curveSteps2, Color32.op_Implicit(new Color(0.76f, 0.68f, 0.52f, 0.92f))); } } } private static void AddArcStrip(VertexHelper vertexHelper, Vector2 center, float innerRadius, float outerRadius, float startDegrees, float endDegrees, int curveSteps, Color32 color) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_0056: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0073: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) int currentVertCount = vertexHelper.currentVertCount; Vector2 val = default(Vector2); for (int i = 0; i <= curveSteps; i++) { float num = Mathf.Lerp(startDegrees, endDegrees, (float)i / (float)curveSteps) * (MathF.PI / 180f); ((Vector2)(ref val))..ctor(Mathf.Cos(num), Mathf.Sin(num)); UIVertex simpleVert = UIVertex.simpleVert; simpleVert.color = color; simpleVert.position = Vector2.op_Implicit(center + val * innerRadius); vertexHelper.AddVert(simpleVert); UIVertex simpleVert2 = UIVertex.simpleVert; simpleVert2.color = color; simpleVert2.position = Vector2.op_Implicit(center + val * outerRadius); vertexHelper.AddVert(simpleVert2); } for (int j = 0; j < curveSteps; j++) { int num2 = currentVertCount + j * 2; int num3 = num2 + 1; int num4 = num2 + 2; int num5 = num2 + 3; vertexHelper.AddTriangle(num2, num3, num5); vertexHelper.AddTriangle(num2, num5, num4); } } } internal sealed class RandomizerCompatibility { internal const string RandomizerGuid = "moriko.silksong.randomizer"; private readonly ManualLogSource log; private bool initialized; private bool randomizerDetected; private bool available; private bool initializationWarningLogged; private bool invocationWarningLogged; private PropertyInfo saveStateInstanceProperty; private MethodInfo isRandomizedMethod; private FieldInfo receivedItemsField; private object crestItemType; private PropertyInfo cursedCrestActiveProperty; private MethodInfo removeUnreceivedSilkspearMethod; private object snapshotSaveState; private bool snapshotStateKnown; private bool snapshotCrestsRandomized; private HashSet snapshotReceivedItems = new HashSet(StringComparer.OrdinalIgnoreCase); internal RandomizerCompatibility(ManualLogSource log) { this.log = log; } internal void RefreshSnapshot() { EnsureInitialized(); snapshotSaveState = null; snapshotStateKnown = false; snapshotCrestsRandomized = false; snapshotReceivedItems.Clear(); if (!available) { return; } try { snapshotSaveState = saveStateInstanceProperty.GetValue(null); if (snapshotSaveState == null) { return; } snapshotCrestsRandomized = (bool)isRandomizedMethod.Invoke(snapshotSaveState, new object[1] { crestItemType }); snapshotStateKnown = true; if (!snapshotCrestsRandomized || !(receivedItemsField.GetValue(snapshotSaveState) is IEnumerable enumerable)) { return; } foreach (object item in enumerable) { if (item is string text && !string.IsNullOrEmpty(text)) { snapshotReceivedItems.Add(text); } } } catch (Exception ex) { LogInvocationWarning("could not read crest ownership", ex); snapshotSaveState = null; snapshotStateKnown = false; snapshotCrestsRandomized = false; snapshotReceivedItems.Clear(); } } internal bool IsCrestOwned(ToolCrest crest) { if ((Object)(object)crest == (Object)null) { return true; } string randomizerItemName = GetRandomizerItemName(crest.name); if (randomizerItemName == null) { return true; } if (randomizerDetected && (!available || !snapshotStateKnown)) { return false; } if (!snapshotCrestsRandomized) { return true; } return snapshotReceivedItems.Contains(randomizerItemName); } internal bool IsSwitchBlocked() { EnsureInitialized(); if (!available || cursedCrestActiveProperty == null) { return false; } try { return (bool)cursedCrestActiveProperty.GetValue(null); } catch (Exception ex) { LogInvocationWarning("could not read Cursed Crest state", ex); return false; } } internal void AfterCrestEquipped() { EnsureInitialized(); if (!randomizerDetected || removeUnreceivedSilkspearMethod == null) { return; } try { removeUnreceivedSilkspearMethod.Invoke(null, null); } catch (Exception ex) { LogInvocationWarning("could not clean unreceived Silk Spear loadouts", ex); } } private void EnsureInitialized() { if (initialized || !Chainloader.PluginInfos.TryGetValue("moriko.silksong.randomizer", out var value)) { return; } randomizerDetected = true; if ((Object)(object)((value != null) ? value.Instance : null) == (Object)null) { return; } initialized = true; try { Assembly assembly = ((object)value.Instance).GetType().Assembly; Type type = assembly.GetType("SilksongRandomizer.SaveState", throwOnError: true); Type type2 = assembly.GetType("SilksongRandomizer.ItemType", throwOnError: true); Type type3 = assembly.GetType("SilksongRandomizer.TrapManager", throwOnError: false); Type type4 = assembly.GetType("SilksongRandomizer.Patches.ToolPatches", throwOnError: false); saveStateInstanceProperty = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public); isRandomizedMethod = type.GetMethod("IsRandomized", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { type2 }, null); receivedItemsField = type.GetField("receivedItems", BindingFlags.Instance | BindingFlags.Public); crestItemType = Enum.Parse(type2, "Crest"); cursedCrestActiveProperty = type3?.GetProperty("IsCursedCrestActive", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); removeUnreceivedSilkspearMethod = type4?.GetMethod("RemoveUnreceivedSilkspearFromCrests", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); available = saveStateInstanceProperty != null && isRandomizedMethod != null && receivedItemsField != null && crestItemType != null; if (available) { log.LogInfo((object)"Silksong Randomizer compatibility enabled."); } else { LogInitializationWarning("the installed randomizer did not expose the expected state members"); } } catch (Exception ex) { available = false; LogInitializationWarning(ex.Message); } } private static string GetRandomizerItemName(string internalName) { if (string.IsNullOrEmpty(internalName)) { return null; } if (internalName.StartsWith("Hunter", StringComparison.OrdinalIgnoreCase)) { return "Crest: Hunter"; } switch (internalName) { case "Warrior": return "Crest: Beast"; case "Toolmaster": return "Crest: Architect"; case "Spell": return "Crest: Shaman"; case "Wanderer": case "Reaper": case "Witch": return "Crest: " + internalName; default: return null; } } private void LogInitializationWarning(string reason) { if (!initializationWarningLogged) { initializationWarningLogged = true; log.LogWarning((object)("Silksong Randomizer compatibility fell back to native crest state: " + reason)); } } private void LogInvocationWarning(string operation, Exception ex) { if (!invocationWarningLogged) { invocationWarningLogged = true; log.LogWarning((object)("Silksong Randomizer compatibility " + operation + ": " + ex.Message)); } } }