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 CrestWheel v1.1.1
CrestWheel.dll
Decompiled 19 hours agousing 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<CrestEntry> entries = new List<CrestEntry>(); private ConfigEntry<bool> enabledConfig; private ConfigEntry<ControllerActivationButton> controllerActivationButtonConfig; private ConfigEntry<ControllerSelectionInput> controllerSelectionInputConfig; private ConfigEntry<float> activationHoldDurationConfig; private ConfigEntry<float> deadzoneConfig; private ConfigEntry<Key> keyboardActivationKeyConfig; private ConfigEntry<Key> keyboardUpKeyConfig; private ConfigEntry<Key> keyboardDownKeyConfig; private ConfigEntry<Key> keyboardLeftKeyConfig; private ConfigEntry<Key> keyboardRightKeyConfig; private ConfigEntry<Key> keyboardCancelKeyConfig; private ConfigEntry<float> wheelScaleConfig; private ConfigEntry<float> backgroundDimConfig; private ConfigEntry<int> 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<bool>("General", "Enabled", true, "Enable the crest wheel."); controllerActivationButtonConfig = ((BaseUnityPlugin)this).Config.Bind<ControllerActivationButton>("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<float>("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<float>(0f, 5f), Array.Empty<object>())); controllerSelectionInputConfig = ((BaseUnityPlugin)this).Config.Bind<ControllerSelectionInput>("Controller", "Selection Input", ControllerSelectionInput.RightStick, "Controller input used to aim around the wheel."); deadzoneConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Controller", "Selection Deadzone", 0.45f, new ConfigDescription("How far an analog selection stick must move before a crest is selected.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.15f, 0.9f), Array.Empty<object>())); keyboardActivationKeyConfig = ((BaseUnityPlugin)this).Config.Bind<Key>("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<Key>("Keyboard", "Selection Up", (Key)58, "Keyboard key used to aim upward."); keyboardDownKeyConfig = ((BaseUnityPlugin)this).Config.Bind<Key>("Keyboard", "Selection Down", (Key)54, "Keyboard key used to aim downward."); keyboardLeftKeyConfig = ((BaseUnityPlugin)this).Config.Bind<Key>("Keyboard", "Selection Left", (Key)36, "Keyboard key used to aim left."); keyboardRightKeyConfig = ((BaseUnityPlugin)this).Config.Bind<Key>("Keyboard", "Selection Right", (Key)39, "Keyboard key used to aim right."); keyboardCancelKeyConfig = ((BaseUnityPlugin)this).Config.Bind<Key>("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<float>("Appearance", "Wheel Scale", 1f, new ConfigDescription("Scale of the crest wheel.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.65f, 1.5f), Array.Empty<object>())); backgroundDimConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Background Dimming", 0.24f, new ConfigDescription("Opacity of the screen dim behind the wheel.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.8f), Array.Empty<object>())); settingsRevisionConfig = ((BaseUnityPlugin)this).Config.Bind<int>("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<Key> obj = keyboardActivationKeyConfig; keyboardActivationPressed = IsKeyboardKeyPressed((Key)((obj != null) ? ((int)obj.Value) : 0)); keyboardActivationWasPressed = keyboardActivationPressed && !flag; keyboardActivationWasReleased = !keyboardActivationPressed && flag; bool flag2 = keyboardCancelPressed; ConfigEntry<Key> 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<InputControlType>(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<Key> obj = keyboardLeftKeyConfig; if (IsKeyboardKeyPressed((Key)((obj == null) ? 36 : ((int)obj.Value)))) { num -= 1f; } ConfigEntry<Key> obj2 = keyboardRightKeyConfig; if (IsKeyboardKeyPressed((Key)((obj2 == null) ? 39 : ((int)obj2.Value)))) { num += 1f; } ConfigEntry<Key> obj3 = keyboardDownKeyConfig; if (IsKeyboardKeyPressed((Key)((obj3 == null) ? 54 : ((int)obj3.Value)))) { num2 -= 1f; } ConfigEntry<Key> 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<ToolCrest> allCrests = ToolItemManager.GetAllCrests(); if (allCrests == null) { return; } List<ToolCrest>[] array = new List<ToolCrest>[FixedCrestSlotNames.Length]; for (int i = 0; i < array.Length; i++) { array[i] = new List<ToolCrest>(); } 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<ToolCrest> 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<GameObject> iconRoots = new List<GameObject>(); private readonly List<Image> iconImages = new List<Image>(); private readonly List<CrestEntry> entries = new List<CrestEntry>(); 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<CrestEntry> 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<RectTransform>(); Canvas component = canvasObject.GetComponent<Canvas>(); component.renderMode = (RenderMode)0; component.sortingOrder = 32000; CanvasScaler component2 = canvasObject.GetComponent<CanvasScaler>(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1920f, 1080f); component2.screenMatchMode = (ScreenMatchMode)0; component2.matchWidthOrHeight = 0.5f; canvasGroup = canvasObject.GetComponent<CanvasGroup>(); 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<RectTransform>(); ((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<RectTransform>(); ((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<RadialRingGraphic>(); ((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<RectTransform>(); 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<RectTransform>(); ((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<RectTransform>()).SetParent(parent, false); Image component = val.GetComponent<Image>(); 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<bool>(); internal void Configure(IReadOnlyList<CrestEntry> 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<string> snapshotReceivedItems = new HashSet<string>(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)); } } }