Decompiled source of LegacyoftheAbyss v1.0.6
LegacyoftheAbyss.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Logging; using GlobalEnums; using GlobalSettings; using HarmonyLib; using InControl; using LegacyoftheAbyss.Shade; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using TMPro; using TeamCherry.Localization; using TeamCherry.NestedFadeGroup; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("LegacyoftheAbyss.Tests")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public static class HornetInput { private static InputHandler? FindHandler() { try { InputHandler unsafeInstance = ManagerSingleton<InputHandler>.UnsafeInstance; if ((Object)(object)unsafeInstance != (Object)null) { return unsafeInstance; } } catch { } try { GameManager instance = GameManager.instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.inputHandler != (Object)null) { return instance.inputHandler; } } catch { } try { return Object.FindFirstObjectByType<InputHandler>(); } catch { try { return Object.FindAnyObjectByType<InputHandler>(); } catch { } } return null; } public static void ApplyKeyboardDefaults(bool disableController) { ModConfig instance = ModConfig.Instance; instance.hornetKeyboardEnabled = true; instance.hornetControllerEnabled = !disableController; InputHandler val = FindHandler(); if ((Object)(object)val == (Object)null) { return; } try { val.ResetDefaultKeyBindings(); ApplyLeftSideLayout(val); } catch { } } public static void ApplyControllerDefaults() { ModConfig instance = ModConfig.Instance; instance.hornetKeyboardEnabled = false; instance.hornetControllerEnabled = true; InputHandler val = FindHandler(); if ((Object)(object)val == (Object)null) { return; } try { val.ResetDefaultControllerButtonBindings(); } catch { } } private static void ApplyLeftSideLayout(InputHandler handler) { //IL_002c: 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_0057: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)handler == (Object)null) { return; } GameManager instance = GameManager.instance; GameSettings val = (((Object)(object)instance != (Object)null) ? instance.gameSettings : null); if (val != null) { Key val2 = (Key)76; val.jumpKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)41; val.attackKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)5; val.dashKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)52; val.castKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)40; val.superDashKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)53; val.dreamNailKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)66; val.quickMapKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)27; val.inventoryKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)28; val.inventoryMapKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)29; val.inventoryJournalKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)30; val.inventoryToolsKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)31; val.inventoryQuestsKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)42; val.quickCastKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)38; val.tauntKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)58; val.upKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)54; val.downKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)36; val.leftKey = ((object)(Key)(ref val2)).ToString(); val2 = (Key)39; val.rightKey = ((object)(Key)(ref val2)).ToString(); try { val.SaveKeyboardSettings(); } catch { } } HeroActions inputActions = handler.inputActions; if (inputActions != null) { Bind(inputActions.Jump, (Key)76); Bind(inputActions.Attack, (Key)41); Bind(inputActions.Dash, (Key)5); Bind(inputActions.Cast, (Key)52); Bind(inputActions.SuperDash, (Key)40); Bind(inputActions.DreamNail, (Key)53); Bind(inputActions.QuickMap, (Key)66); Bind(inputActions.OpenInventory, (Key)27); Bind(inputActions.OpenInventoryMap, (Key)28); Bind(inputActions.OpenInventoryJournal, (Key)29); Bind(inputActions.OpenInventoryTools, (Key)30); Bind(inputActions.OpenInventoryQuests, (Key)31); Bind(inputActions.QuickCast, (Key)42); Bind(inputActions.Taunt, (Key)38); Bind(inputActions.Up, (Key)58); Bind(inputActions.Down, (Key)54); Bind(inputActions.Left, (Key)36); Bind(inputActions.Right, (Key)39); } static void Bind(PlayerAction action, Key key) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected I4, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown if (action != null) { action.ClearBindings(); action.AddBinding((BindingSource)new KeyBindingSource((Key[])(object)new Key[1] { (Key)(int)key })); } } } } public class SimpleHUD : MonoBehaviour { private Sprite[] _slashFramesCache; private AudioSource sfxSource; private List<AudioClip> shadeHurtCandidates; private int shadeHurtIdx; private AudioClip pinnedHurtSingle; private AudioClip pinnedHurtDouble; private PlayerData playerData; private Image[] maskImages; private readonly HashSet<Image> animatingMaskImages = new HashSet<Image>(); private Sprite maskSprite; private Sprite hivebloodMaskSprite; private readonly Color missingMaskColor = new Color(0.2f, 0.2f, 0.2f, 0.45f); private readonly Color overcharmMaskColor = Color.white; private readonly Color overcharmBackdropColor = new Color(0.85f, 0.25f, 0.25f, 0.1344f); private readonly Color overcharmBackdropSpriteColor = new Color(1f, 1f, 1f, 0.392f); private readonly Color lifebloodMaskColor = new Color(0.4f, 0.75f, 1f, 1f); private readonly Color hivebloodMaskColor = new Color(1f, 0.72f, 0.18f, 1f); private readonly Color lifebloodMissingColor = new Color(0.28f, 0.46f, 0.66f, 0.45f); private Sprite soulOrbSprite; private RectTransform soulOrbRoot; private RectTransform soulRevealMask; private Image soulImage; private Image soulBgImage; private Sprite overcharmBackdropSprite; private Sprite frameSprite; private Sprite[] slashFrames; private int shadeMax; private int shadeHealth; private int shadeLifebloodMax; private int shadeLifeblood; private int previousShadeTotalHealth; private int prevHornetHealth; private int prevHornetMax; private bool hasExplicitShadeStats; private bool shadeOvercharmed; private bool shadeAssistModeActive; private bool suppressNextDamageSound; private bool pendingMaskRefresh; private Image hivebloodPreviewMask; private bool hivebloodEquipped; private ShadeCharmInventory subscribedCharmInventory; private bool charmInventoryDirty; private GameObject healthContainer; private Image overcharmBackdrop; private Canvas canvas; private CanvasScaler scaler; private CanvasGroup canvasGroup; private ShadeUnlockPopup unlockPopup; private Vector3 orbGameplayScale = Vector3.one; private Vector3 orbMenuScale = Vector3.one; private Vector3 healthGameplayScale = Vector3.one; private Vector3 healthMenuScale = Vector3.one; private const KeyCode DebugDamageKey = 0; private const KeyCode DebugHealKey = 0; private const KeyCode DebugSoulDecKey = 0; private const KeyCode DebugSoulIncKey = 0; private const KeyCode DebugSoulResetKey = 92; private bool debugUseCustomSilk; private float debugSilk; private bool shadeSoulOverride; private float shadeSoul; private float shadeSoulMax; private const float MaskScale = 0.88f; private const float OvercharmBackdropScale = 3.4f; private const float OvercharmBackdropRotation = 180f; private const float OvercharmBackdropHorizontalOffsetFraction = 3.2f; private const float OvercharmBackdropVerticalOffsetFraction = 1.4f; private const int OvercharmBackdropReferenceMaskCount = 3; private Vector2 overcharmMaskSize = Vector2.zero; private float overcharmMaskSpacing; private const float HivebloodPreviewFirstStageSeconds = 3.5f; private const float HivebloodPreviewSecondStageSeconds = 7f; private Sprite BuildMaskSprite() { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_004c: 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_0015: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(32, 32); for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { val.SetPixel(i, j, Color.white); } } val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f)); } private void LoadSprites() { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) try { string assetPath = ModPaths.GetAssetPath("select_game_HUD_0001_health.png"); string assetPath2 = ModPaths.GetAssetPath("select_game_HUD_0002_health_frame.png"); string assetPath3 = ModPaths.GetAssetPath("The Knight spells and items - atlas0 #00000309.png"); string assetPath4 = ModPaths.GetAssetPath("soul_orb_glow0000.png"); string assetPath5 = ModPaths.GetAssetPath("overcharm_backboard.png"); maskSprite = LoadSprite(assetPath); if ((Object)(object)maskSprite == (Object)null) { maskSprite = FindSpriteInGame("select_game_HUD_0001_health"); } hivebloodMaskSprite = CreateTintedSprite(maskSprite, hivebloodMaskColor); frameSprite = LoadSprite(assetPath2); if ((Object)(object)frameSprite == (Object)null) { frameSprite = FindSpriteInGame("select_game_HUD_0002_health_frame"); } slashFrames = LoadSpriteSheet(assetPath3, 8, 8); soulOrbSprite = LoadSprite(assetPath4); overcharmBackdropSprite = LoadSprite(assetPath5); if ((Object)(object)overcharmBackdropSprite == (Object)null) { overcharmBackdropSprite = ShadeCharmIconLoader.TryLoadIcon("overcharm_backboard", "overcharm_backboard.png"); } if (!((Object)(object)hivebloodMaskSprite == (Object)null)) { return; } Sprite val = BuildMaskSprite(); hivebloodMaskSprite = CreateTintedSprite(val, hivebloodMaskColor); if ((Object)(object)val != (Object)null) { Texture2D texture = val.texture; if ((Object)(object)texture != (Object)null) { Object.Destroy((Object)(object)texture); } Object.Destroy((Object)(object)val); } } catch { } } private Sprite CreateTintedSprite(Sprite source, Color tint) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } Texture2D val = null; try { Texture2D texture = source.texture; if ((Object)(object)texture == (Object)null) { return null; } Rect textureRect = source.textureRect; int num = Mathf.Max(1, Mathf.RoundToInt(((Rect)(ref textureRect)).width)); int num2 = Mathf.Max(1, Mathf.RoundToInt(((Rect)(ref textureRect)).height)); int num3 = Mathf.RoundToInt(((Rect)(ref textureRect)).x); int num4 = Mathf.RoundToInt(((Rect)(ref textureRect)).y); Color[] pixels = texture.GetPixels(num3, num4, num, num2); if (pixels == null || pixels.Length == 0) { return null; } Color[] array = (Color[])(object)new Color[pixels.Length]; for (int i = 0; i < pixels.Length; i++) { Color val2 = pixels[i]; array[i] = new Color(val2.r * tint.r, val2.g * tint.g, val2.b * tint.b, val2.a * tint.a); } val = new Texture2D(num, num2, (TextureFormat)5, false); val.SetPixels(array); val.Apply(); ((Texture)val).filterMode = (FilterMode)0; ((Texture)val).wrapMode = (TextureWrapMode)1; Sprite val3 = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num2), new Vector2(0.5f, 0.5f), source.pixelsPerUnit); if ((Object)(object)val3 != (Object)null) { return val3; } } catch { } if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } return null; } private Sprite LoadSprite(string path) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (!File.Exists(path)) { return null; } byte[] bytes = File.ReadAllBytes(path); Texture2D val = new Texture2D(2, 2, (TextureFormat)5, false); TryLoadImage(val, bytes); ((Texture)val).filterMode = (FilterMode)0; return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private Sprite[] LoadSpriteSheet(string path, int cols, int rows) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0072: 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) if (!File.Exists(path)) { return (Sprite[])(object)new Sprite[0]; } byte[] bytes = File.ReadAllBytes(path); Texture2D val = new Texture2D(2, 2, (TextureFormat)5, false); TryLoadImage(val, bytes); ((Texture)val).filterMode = (FilterMode)0; int num = ((Texture)val).width / cols; int num2 = ((Texture)val).height / rows; Sprite[] array = (Sprite[])(object)new Sprite[cols * rows]; int num3 = 0; for (int num4 = rows - 1; num4 >= 0; num4--) { for (int i = 0; i < cols; i++) { array[num3++] = Sprite.Create(val, new Rect((float)(i * num), (float)(num4 * num2), (float)num, (float)num2), new Vector2(0.5f, 0.5f)); } } return array; } private Sprite BuildCircleSprite() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0050: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) int num = 64; Texture2D val = new Texture2D(num, num); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor((float)num / 2f, (float)num / 2f); float num2 = (float)num / 2f; for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { Color val3 = ((Vector2.Distance(new Vector2((float)i, (float)j), val2) <= num2) ? Color.white : Color.clear); val.SetPixel(i, j, val3); } } val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f)); } private Sprite FindSpriteInGame(string namePart) { //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) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(namePart)) { return null; } string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(namePart); Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>(); Sprite result = null; int num = int.MinValue; Sprite[] array2 = array; foreach (Sprite val in array2) { if (!((Object)(object)val == (Object)null)) { string obj = ((Object)val).name ?? string.Empty; int num2 = 0; if (string.Equals(obj, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase)) { num2 += 1000; } if (obj.IndexOf(fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase) >= 0) { num2 += 100; } int num3 = num2; Rect rect = val.rect; float width = ((Rect)(ref rect)).width; rect = val.rect; num2 = num3 + (int)(width + ((Rect)(ref rect)).height); if (num2 > num) { num = num2; result = val; } } } return result; } private Sprite[] GetSlashFrames() { if (_slashFramesCache != null && _slashFramesCache.Length != 0) { return _slashFramesCache; } Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>(); List<Sprite> list = new List<Sprite>(); Sprite[] array2 = array; foreach (Sprite val in array2) { if (!((Object)(object)val == (Object)null)) { string text = ((Object)val).name ?? string.Empty; if (text.IndexOf("charge_slash", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("slash", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("hit", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("impact", StringComparison.OrdinalIgnoreCase) >= 0) { list.Add(val); } } } if (list.Count > 0) { _slashFramesCache = (from s in list orderby ((Object)s).name.IndexOf("charge_slash", StringComparison.OrdinalIgnoreCase) >= 0 descending, ((Object)s).name.IndexOf("_0002_", StringComparison.OrdinalIgnoreCase) >= 0 descending, ((Object)s).name select s).ToArray(); return _slashFramesCache; } if (slashFrames != null && slashFrames.Length != 0) { _slashFramesCache = slashFrames; return _slashFramesCache; } return Array.Empty<Sprite>(); } private static bool TryLoadImage(Texture2D tex, byte[] bytes) { try { Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule"); if (type != null) { MethodInfo method = type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3] { typeof(Texture2D), typeof(byte[]), typeof(bool) }, null); if (method != null) { method.Invoke(null, new object[3] { tex, bytes, false }); return true; } } } catch { } return false; } private void TryPlayPinnedHurtSfx(int lost) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown try { if ((Object)(object)sfxSource == (Object)null) { GameObject val = new GameObject("ShadeHUD_SFX"); val.transform.SetParent(((Component)this).transform, false); sfxSource = val.AddComponent<AudioSource>(); sfxSource.playOnAwake = false; sfxSource.spatialBlend = 0f; sfxSource.volume = Mathf.Clamp01(LegacyHelper.GetEffectiveSfxVolume()); } if ((Object)(object)pinnedHurtSingle == (Object)null || (Object)(object)pinnedHurtDouble == (Object)null) { AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>(); if (array != null) { AudioClip[] array2 = array; foreach (AudioClip val2 in array2) { if (!((Object)(object)val2 == (Object)null)) { string a = ((Object)val2).name ?? string.Empty; if ((Object)(object)pinnedHurtSingle == (Object)null && string.Equals(a, "hero_damage", StringComparison.OrdinalIgnoreCase)) { pinnedHurtSingle = val2; } if ((Object)(object)pinnedHurtDouble == (Object)null && string.Equals(a, "hero_double_damage", StringComparison.OrdinalIgnoreCase)) { pinnedHurtDouble = val2; } if ((Object)(object)pinnedHurtSingle != (Object)null && (Object)(object)pinnedHurtDouble != (Object)null) { break; } } } if ((Object)(object)pinnedHurtSingle == (Object)null) { array2 = array; foreach (AudioClip val3 in array2) { string text = (((Object)(object)val3 != (Object)null) ? ((Object)val3).name : null); if (!string.IsNullOrEmpty(text) && text.IndexOf("hero_damage", StringComparison.OrdinalIgnoreCase) >= 0) { pinnedHurtSingle = val3; break; } } } if ((Object)(object)pinnedHurtDouble == (Object)null) { array2 = array; foreach (AudioClip val4 in array2) { string text2 = (((Object)(object)val4 != (Object)null) ? ((Object)val4).name : null); if (!string.IsNullOrEmpty(text2) && text2.IndexOf("hero_double_damage", StringComparison.OrdinalIgnoreCase) >= 0) { pinnedHurtDouble = val4; break; } } } } } AudioClip val5 = ((lost >= 2 && (Object)(object)pinnedHurtDouble != (Object)null) ? pinnedHurtDouble : pinnedHurtSingle); if ((Object)(object)val5 != (Object)null) { float volume = Mathf.Clamp01(LegacyHelper.GetEffectiveSfxVolume()); sfxSource.volume = volume; sfxSource.PlayOneShot(val5); return; } } catch { } TryPlayDamageSfx(); } private void TryPlayDamageSfx() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown try { if ((Object)(object)sfxSource == (Object)null) { GameObject val = new GameObject("ShadeHUD_SFX"); val.transform.SetParent(((Component)this).transform, false); sfxSource = val.AddComponent<AudioSource>(); sfxSource.playOnAwake = false; sfxSource.spatialBlend = 0f; sfxSource.volume = Mathf.Clamp01(LegacyHelper.GetEffectiveSfxVolume()); } if (shadeHurtCandidates == null || shadeHurtCandidates.Count == 0) { shadeHurtCandidates = BuildShadeHurtCandidates(); shadeHurtIdx = 0; } if (shadeHurtCandidates != null && shadeHurtCandidates.Count > 0) { AudioClip val2 = shadeHurtCandidates[shadeHurtIdx % shadeHurtCandidates.Count]; shadeHurtIdx++; if ((Object)(object)val2 != (Object)null) { float volume = Mathf.Clamp01(LegacyHelper.GetEffectiveSfxVolume()); sfxSource.volume = volume; sfxSource.PlayOneShot(val2); } } } catch { } } private List<AudioClip> BuildShadeHurtCandidates() { List<AudioClip> list = new List<AudioClip>(); HashSet<AudioClip> hashSet = new HashSet<AudioClip>(); try { List<AudioClip> list2 = FindHurtClipsFromHornetFSM(); if (list2 != null) { foreach (AudioClip item in list2) { if ((Object)(object)item != (Object)null && hashSet.Add(item)) { list.Add(item); } } } } catch { } try { AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>(); if (array != null && array.Length != 0) { foreach (AudioClip item2 in from c in array where (Object)(object)c != (Object)null select new { clip = c, n = (((Object)c).name ?? string.Empty) } into x where x.n.IndexOf("hurt", StringComparison.OrdinalIgnoreCase) >= 0 || x.n.IndexOf("take_hit", StringComparison.OrdinalIgnoreCase) >= 0 || x.n.IndexOf("damage", StringComparison.OrdinalIgnoreCase) >= 0 || x.n.IndexOf("hit", StringComparison.OrdinalIgnoreCase) >= 0 || x.n.IndexOf("hornet", StringComparison.OrdinalIgnoreCase) >= 0 orderby x.n.IndexOf("take", StringComparison.OrdinalIgnoreCase) >= 0 && x.n.IndexOf("hit", StringComparison.OrdinalIgnoreCase) >= 0 descending, x.n.IndexOf("hornet", StringComparison.OrdinalIgnoreCase) >= 0 descending, x.n.IndexOf("hurt", StringComparison.OrdinalIgnoreCase) >= 0 descending, x.n.IndexOf("damage", StringComparison.OrdinalIgnoreCase) >= 0 descending select x.clip) { if ((Object)(object)item2 != (Object)null && hashSet.Add(item2)) { list.Add(item2); } } } } catch { } return list; } private List<AudioClip> FindHurtClipsFromHornetFSM() { List<AudioClip> list = new List<AudioClip>(); try { HeroController instance = HeroController.instance; if ((Object)(object)instance != (Object)null) { object obj = ((object)instance).GetType().GetField("HeroFSM", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(instance); if (obj != null) { PropertyInfo property = obj.GetType().GetProperty("States", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); IEnumerable enumerable = ((property != null) ? (property.GetValue(obj, null) as IEnumerable) : null); if (enumerable != null) { foreach (object item in enumerable) { PropertyInfo property2 = item.GetType().GetProperty("Actions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); IEnumerable enumerable2 = ((property2 != null) ? (property2.GetValue(item, null) as IEnumerable) : null); if (enumerable2 == null) { continue; } foreach (object item2 in enumerable2) { if (item2 == null) { continue; } try { PropertyInfo[] properties = item2.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.PropertyType == typeof(AudioClip)) { object? value = propertyInfo.GetValue(item2, null); AudioClip val = (AudioClip)((value is AudioClip) ? value : null); if ((Object)(object)val != (Object)null && !list.Contains(val)) { list.Add(val); } } Type propertyType = propertyInfo.PropertyType; if (propertyType != null && propertyType.FullName != null && propertyType.FullName.Contains("UnityEngine.AudioSource")) { object? value2 = propertyInfo.GetValue(item2, null); AudioSource val2 = (AudioSource)((value2 is AudioSource) ? value2 : null); if ((Object)(object)val2 != (Object)null && (Object)(object)val2.clip != (Object)null && !list.Contains(val2.clip)) { list.Add(val2.clip); } } if (!(propertyType != null) || propertyType.FullName == null || !propertyType.FullName.Contains("HutongGames.PlayMaker.FsmObject")) { continue; } object value3 = propertyInfo.GetValue(item2, null); if (value3 != null) { PropertyInfo property3 = value3.GetType().GetProperty("Value", BindingFlags.Instance | BindingFlags.Public); object? obj2 = ((property3 != null) ? property3.GetValue(value3, null) : null); AudioClip val3 = (AudioClip)((obj2 is AudioClip) ? obj2 : null); if ((Object)(object)val3 != (Object)null && !list.Contains(val3)) { list.Add(val3); } } } } catch { } } } } } } } catch { } return list; } public void Init(PlayerData pd) { playerData = pd; LoadSprites(); ComputeShadeFromPlayer(); CreateUI(); SubscribeToCharmInventory(); charmInventoryDirty = true; previousShadeTotalHealth = shadeHealth + shadeLifeblood; RefreshHealth(); } private float GetUIScale() { float num = Mathf.Max(0.1f, (float)Screen.height / 1080f); return 1f + (num - 1f) * 0.5f; } private void Update() { UpdatePauseFade(); SubscribeToCharmInventory(); if (charmInventoryDirty && playerData != null) { charmInventoryDirty = false; RefreshHealth(); } if (playerData == null) { return; } if (Input.GetKeyDown((KeyCode)0)) { shadeHealth = Mathf.Max(0, shadeHealth - 1); if (ModConfig.Instance.logHud) { try { Debug.Log((object)"[SimpleHUD] Debug: Shade HP -1"); } catch { } } } if (Input.GetKeyDown((KeyCode)0)) { shadeHealth = Mathf.Min(shadeMax, shadeHealth + 1); if (ModConfig.Instance.logHud) { try { Debug.Log((object)"[SimpleHUD] Debug: Shade HP +1"); } catch { } } } float num = (shadeSoulOverride ? Mathf.Max(1f, shadeSoulMax) : Mathf.Max(1f, (float)playerData.silkMax)); float num2 = Mathf.Max(1f, num * 0.1f); if (Input.GetKeyDown((KeyCode)0)) { if (shadeSoulOverride) { try { LegacyHelper.ShadeController shadeController = Object.FindFirstObjectByType<LegacyHelper.ShadeController>(); if ((Object)(object)shadeController != (Object)null) { shadeController.shadeSoul = Mathf.Min(shadeController.shadeSoul + 11, shadeController.shadeSoulMax); } } catch { } shadeSoul = Mathf.Min(shadeSoul + 11f, Mathf.Max(1f, shadeSoulMax)); if (ModConfig.Instance.logHud) { try { Debug.Log((object)"[SimpleHUD] Debug: Shade Soul +11"); } catch { } } } else { float num3 = (debugUseCustomSilk ? debugSilk : ((float)playerData.silk)); debugUseCustomSilk = true; debugSilk = Mathf.Min(num3 + num2, num); if (ModConfig.Instance.logHud) { try { Debug.Log((object)"[SimpleHUD] Debug: Hornet Silk +step"); } catch { } } } } if (Input.GetKeyDown((KeyCode)0)) { if (shadeSoulOverride) { try { LegacyHelper.ShadeController shadeController2 = Object.FindFirstObjectByType<LegacyHelper.ShadeController>(); if ((Object)(object)shadeController2 != (Object)null) { shadeController2.shadeSoul = Mathf.Max(shadeController2.shadeSoul - 11, 0); } } catch { } shadeSoul = Mathf.Max(shadeSoul - 11f, 0f); if (ModConfig.Instance.logHud) { try { Debug.Log((object)"[SimpleHUD] Debug: Shade Soul -11"); } catch { } } } else { float num4 = (debugUseCustomSilk ? debugSilk : ((float)playerData.silk)); debugUseCustomSilk = true; debugSilk = Mathf.Max(num4 - num2, 0f); if (ModConfig.Instance.logHud) { try { Debug.Log((object)"[SimpleHUD] Debug: Hornet Silk -step"); } catch { } } } } if (Input.GetKeyDown((KeyCode)92)) { if (shadeSoulOverride) { try { LegacyHelper.ShadeController shadeController3 = Object.FindFirstObjectByType<LegacyHelper.ShadeController>(); if ((Object)(object)shadeController3 != (Object)null) { shadeController3.shadeSoul = 0; } } catch { } shadeSoul = 0f; if (ModConfig.Instance.logHud) { try { Debug.Log((object)"[SimpleHUD] Debug: Shade Soul reset"); } catch { } } } else { debugUseCustomSilk = false; debugSilk = playerData.silk; if (ModConfig.Instance.logHud) { try { Debug.Log((object)"[SimpleHUD] Debug: Hornet Silk reset"); } catch { } } } } SyncShadeFromPlayer(); RefreshHealth(); RefreshSoul(); } private void UpdatePauseFade() { if (!((Object)(object)canvasGroup == (Object)null)) { bool flag = ShouldTreatAsMenu(); float num = (flag ? 0.35f : 1f); float alpha = canvasGroup.alpha; if (!Mathf.Approximately(alpha, num)) { float num2 = Mathf.Max(0.01f, Time.unscaledDeltaTime * 5f); canvasGroup.alpha = Mathf.MoveTowards(alpha, num, num2); } UpdateMenuOrientation(flag); } } private bool ShouldTreatAsMenu() { try { return MenuStateUtility.IsMenuActive(); } catch { return false; } } private void UpdateMenuOrientation(bool menuActive) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0004: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0075: 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_0083: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (menuActive ? orbMenuScale : orbGameplayScale); if ((Object)(object)soulOrbRoot != (Object)null && ((Transform)soulOrbRoot).localScale != val) { ((Transform)soulOrbRoot).localScale = val; } if (!((Object)(object)healthContainer != (Object)null)) { return; } RectTransform component = healthContainer.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { Vector3 val2 = (menuActive ? healthMenuScale : healthGameplayScale); if (((Transform)component).localScale != val2) { ((Transform)component).localScale = val2; } } } public void SetShadeSoul(int current, int max) { shadeSoulOverride = true; shadeSoul = Mathf.Max(0, current); shadeSoulMax = Mathf.Max(1, max); } public void SetShadeStats(int currentNormal, int maxNormal, int lifebloodCurrent, int lifebloodMax) { bool flag = !hasExplicitShadeStats; hasExplicitShadeStats = true; int num = Mathf.Max(0, maxNormal); int num2 = Mathf.Max(0, lifebloodMax); int num3 = Mathf.Clamp(currentNormal, 0, num); int num4 = Mathf.Clamp(lifebloodCurrent, 0, num2); bool num5 = num != shadeMax || num2 != shadeLifebloodMax; shadeMax = num; shadeLifebloodMax = num2; shadeHealth = num3; shadeLifeblood = num4; if (flag) { previousShadeTotalHealth = shadeHealth + shadeLifeblood; suppressNextDamageSound = false; } if (num5) { pendingMaskRefresh = true; } HandleAssistVisibilityChange(); RefreshHealth(); } public void SetShadeAssistMode(bool assistActive) { if (shadeAssistModeActive != assistActive) { shadeAssistModeActive = assistActive; pendingMaskRefresh |= !assistActive; previousShadeTotalHealth = shadeHealth + shadeLifeblood; HandleAssistVisibilityChange(); RefreshHealth(); } } public void SuppressNextShadeDamageSfx() { suppressNextDamageSound = true; } public void SetShadeOvercharmed(bool overcharmed) { if (shadeOvercharmed != overcharmed) { shadeOvercharmed = overcharmed; RefreshOvercharmBackdrop(); RefreshHealth(); } } public void ClearShadeSoulOverride() { shadeSoulOverride = false; } public void SetVisible(bool visible) { if ((Object)(object)canvas != (Object)null) { ((Behaviour)canvas).enabled = visible; } else { ((Component)this).gameObject.SetActive(visible); } } public void SetPlayerData(PlayerData pd) { if (pd != playerData) { playerData = pd; int num = shadeMax; SubscribeToCharmInventory(); charmInventoryDirty = true; ComputeShadeFromPlayer(); if (shadeMax != num) { RebuildMasks(); previousShadeTotalHealth = Mathf.Min(previousShadeTotalHealth, shadeMax + shadeLifebloodMax); } RefreshHealth(); RefreshSoul(); } } private void OnDestroy() { UnsubscribeFromCharmInventory(); } private void ComputeShadeFromPlayer() { if (playerData == null) { shadeMax = 0; shadeHealth = 0; shadeLifebloodMax = 0; shadeLifeblood = 0; prevHornetMax = 0; prevHornetHealth = 0; suppressNextDamageSound = false; return; } prevHornetMax = playerData.maxHealth; prevHornetHealth = playerData.health; if (!hasExplicitShadeStats) { shadeMax = (playerData.maxHealth + 1) / 2; shadeLifebloodMax = 0; shadeHealth = (playerData.health + 1) / 2; shadeLifeblood = 0; suppressNextDamageSound = true; } } private void SyncShadeFromPlayer() { if (playerData == null) { return; } int maxHealth = playerData.maxHealth; int health = playerData.health; if (!hasExplicitShadeStats) { int num = (maxHealth + 1) / 2; if (num != shadeMax) { shadeMax = num; RebuildMasks(); previousShadeTotalHealth = Mathf.Min(previousShadeTotalHealth, shadeMax + shadeLifebloodMax); shadeHealth = Mathf.Min(shadeHealth, shadeMax); } } prevHornetHealth = health; prevHornetMax = maxHealth; } private void SubscribeToCharmInventory() { ShadeCharmInventory charms = ShadeRuntime.Charms; if (charms == null) { UnsubscribeFromCharmInventory(); } else if (subscribedCharmInventory != charms) { UnsubscribeFromCharmInventory(); subscribedCharmInventory = charms; try { subscribedCharmInventory.StateChanged += HandleCharmInventoryChanged; charmInventoryDirty = true; } catch { subscribedCharmInventory = null; } } } private void UnsubscribeFromCharmInventory() { if (subscribedCharmInventory != null) { try { subscribedCharmInventory.StateChanged -= HandleCharmInventoryChanged; } catch { } subscribedCharmInventory = null; } } private void HandleCharmInventoryChanged() { charmInventoryDirty = true; } private void CreateUI() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0147: 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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: 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_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Expected O, but got Unknown //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Expected O, but got Unknown //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Expected O, but got Unknown //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_049d: Unknown result type (might be due to invalid IL or missing references) //IL_04a8: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Unknown result type (might be due to invalid IL or missing references) //IL_04d2: Expected O, but got Unknown //IL_0510: Unknown result type (might be due to invalid IL or missing references) //IL_0517: Unknown result type (might be due to invalid IL or missing references) //IL_052a: Unknown result type (might be due to invalid IL or missing references) //IL_0559: Unknown result type (might be due to invalid IL or missing references) //IL_055e: Unknown result type (might be due to invalid IL or missing references) //IL_056d: Unknown result type (might be due to invalid IL or missing references) //IL_0572: Unknown result type (might be due to invalid IL or missing references) //IL_057b: Unknown result type (might be due to invalid IL or missing references) //IL_054c: Unknown result type (might be due to invalid IL or missing references) //IL_0595: Unknown result type (might be due to invalid IL or missing references) //IL_05a5: Unknown result type (might be due to invalid IL or missing references) //IL_05c0: Unknown result type (might be due to invalid IL or missing references) //IL_05d5: Unknown result type (might be due to invalid IL or missing references) //IL_05e2: Unknown result type (might be due to invalid IL or missing references) //IL_05e7: Unknown result type (might be due to invalid IL or missing references) //IL_05ee: Unknown result type (might be due to invalid IL or missing references) //IL_05f3: Unknown result type (might be due to invalid IL or missing references) canvas = ((Component)this).gameObject.AddComponent<Canvas>(); canvas.renderMode = (RenderMode)0; canvas.overrideSorting = true; canvas.sortingOrder = -500; scaler = ((Component)this).gameObject.AddComponent<CanvasScaler>(); scaler.uiScaleMode = (ScaleMode)1; scaler.referenceResolution = new Vector2(1920f, 1080f); scaler.screenMatchMode = (ScreenMatchMode)0; scaler.matchWidthOrHeight = 1f; ((Component)this).gameObject.AddComponent<GraphicRaycaster>(); canvasGroup = ((Component)this).gameObject.GetComponent<CanvasGroup>(); if ((Object)(object)canvasGroup == (Object)null) { canvasGroup = ((Component)this).gameObject.AddComponent<CanvasGroup>(); } canvasGroup.interactable = false; canvasGroup.blocksRaycasts = false; soulOrbRoot = new GameObject("SoulOrb").AddComponent<RectTransform>(); ((Transform)soulOrbRoot).SetParent(((Component)canvas).transform, false); RectTransform obj = soulOrbRoot; RectTransform obj2 = soulOrbRoot; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(1f, 1f); obj2.anchorMax = val; obj.anchorMin = val; soulOrbRoot.pivot = new Vector2(1f, 1f); Vector2 val2; Rect rect; if (!((Object)(object)soulOrbSprite != (Object)null)) { val2 = new Vector2(96f, 96f); } else { rect = soulOrbSprite.rect; float width = ((Rect)(ref rect)).width; rect = soulOrbSprite.rect; val2 = new Vector2(width, ((Rect)(ref rect)).height); } Vector2 val3 = val2; float uIScale = GetUIScale(); soulOrbRoot.sizeDelta = val3 * uIScale * 0.85f; soulOrbRoot.anchoredPosition = new Vector2(-200f * uIScale, -20f * uIScale); ((Transform)soulOrbRoot).localScale = new Vector3(-1f, 1f, 1f); orbGameplayScale = ((Transform)soulOrbRoot).localScale; orbMenuScale = orbGameplayScale; GameObject val4 = new GameObject("SoulBackground"); val4.transform.SetParent((Transform)(object)soulOrbRoot, false); soulBgImage = val4.AddComponent<Image>(); soulBgImage.sprite = (((Object)(object)soulOrbSprite != (Object)null) ? soulOrbSprite : BuildCircleSprite()); soulBgImage.preserveAspect = true; RectTransform rectTransform = ((Graphic)soulBgImage).rectTransform; rectTransform.anchorMin = new Vector2(0f, 0f); rectTransform.anchorMax = new Vector2(1f, 1f); rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.anchoredPosition = Vector2.zero; rectTransform.sizeDelta = Vector2.zero; ((Graphic)soulBgImage).color = new Color(0.6f, 0.6f, 0.6f, 0.35f); GameObject val5 = new GameObject("SoulRevealMask"); val5.transform.SetParent((Transform)(object)soulOrbRoot, false); soulRevealMask = val5.AddComponent<RectTransform>(); soulRevealMask.anchorMin = new Vector2(0f, 0f); soulRevealMask.anchorMax = new Vector2(1f, 0f); soulRevealMask.pivot = new Vector2(0.5f, 0f); soulRevealMask.anchoredPosition = Vector2.zero; soulRevealMask.sizeDelta = new Vector2(0f, 0f); val5.AddComponent<RectMask2D>(); GameObject val6 = new GameObject("SoulImage"); val6.transform.SetParent((Transform)(object)soulOrbRoot, false); soulImage = val6.AddComponent<Image>(); soulImage.sprite = (((Object)(object)soulOrbSprite != (Object)null) ? soulOrbSprite : BuildCircleSprite()); soulImage.preserveAspect = true; ((MaskableGraphic)soulImage).maskable = true; ((Graphic)soulImage).raycastTarget = false; ((Graphic)soulImage).color = Color.white; soulImage.type = (Type)3; soulImage.fillMethod = (FillMethod)1; soulImage.fillOrigin = 0; soulImage.fillAmount = 0f; RectTransform rectTransform2 = ((Graphic)soulImage).rectTransform; rectTransform2.anchorMin = new Vector2(0.5f, 0f); rectTransform2.anchorMax = new Vector2(0.5f, 0f); rectTransform2.pivot = new Vector2(0.5f, 0f); rectTransform2.anchoredPosition = Vector2.zero; rectTransform2.sizeDelta = soulOrbRoot.sizeDelta; healthContainer = new GameObject("HealthContainer"); healthContainer.transform.SetParent(((Component)canvas).transform, false); RectTransform val7 = healthContainer.AddComponent<RectTransform>(); ((Vector2)(ref val))..ctor(1f, 1f); val7.anchorMax = val; val7.anchorMin = val; val7.pivot = new Vector2(1f, 1f); Vector2 val8; if (!((Object)(object)maskSprite != (Object)null)) { val8 = new Vector2(33f, 41f); } else { rect = maskSprite.rect; float width2 = ((Rect)(ref rect)).width; rect = maskSprite.rect; val8 = new Vector2(width2, ((Rect)(ref rect)).height); } float num = val8.y * uIScale * 0.88f; float num2 = soulOrbRoot.anchoredPosition.y - soulOrbRoot.sizeDelta.y * 0.5f; val7.anchoredPosition = new Vector2(soulOrbRoot.anchoredPosition.x, num2 + num * 0.5f); healthGameplayScale = ((Transform)val7).localScale; healthMenuScale = healthGameplayScale; BuildMasks(val7, uIScale); unlockPopup = ((Component)this).gameObject.GetComponent<ShadeUnlockPopup>(); if ((Object)(object)unlockPopup == (Object)null) { unlockPopup = ((Component)this).gameObject.AddComponent<ShadeUnlockPopup>(); } unlockPopup.Initialize(canvas, GetUIScale); UpdateMenuOrientation(ShouldTreatAsMenu()); } private void RefreshHealth() { //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) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) HandleAssistVisibilityChange(); hivebloodEquipped = ShadeRuntime.Charms?.IsEquipped(ShadeCharmId.Hiveblood) ?? false; if (shadeAssistModeActive) { int num = Mathf.Max(0, shadeMax) + Mathf.Max(0, shadeLifebloodMax); previousShadeTotalHealth = Mathf.Clamp(shadeHealth + shadeLifeblood, 0, num); HideHivebloodPreview(); return; } if (pendingMaskRefresh && (Object)(object)healthContainer != (Object)null) { RebuildMasks(); } if (maskImages == null) { pendingMaskRefresh = true; HideHivebloodPreview(); return; } int num2 = Mathf.Max(0, shadeMax); int num3 = Mathf.Max(0, shadeLifebloodMax); int num4 = num2 + num3; if (maskImages.Length != num4) { RebuildMasks(); if (maskImages == null) { return; } } int num5 = Mathf.Clamp(shadeHealth, 0, num2); int num6 = Mathf.Clamp(shadeLifeblood, 0, num3); int num7 = num5 + num6; if (num7 < previousShadeTotalHealth) { int num8 = previousShadeTotalHealth - num7; if (suppressNextDamageSound) { suppressNextDamageSound = false; } else if (num8 > 0) { TryPlayPinnedHurtSfx(num8); } int num9 = Mathf.Clamp(previousShadeTotalHealth, 0, maskImages.Length); int num10 = Mathf.Clamp(num7, 0, maskImages.Length); for (int num11 = num9 - 1; num11 >= num10; num11--) { if (num11 >= 0 && num11 < maskImages.Length) { bool wasLifeblood = num11 >= num2; ((MonoBehaviour)this).StartCoroutine(LoseHealth(maskImages[num11], shadeOvercharmed, wasLifeblood, hivebloodEquipped)); } } } else if (suppressNextDamageSound) { suppressNextDamageSound = false; } Sprite val = ((hivebloodEquipped && !shadeOvercharmed && (Object)(object)hivebloodMaskSprite != (Object)null && (Object)(object)hivebloodMaskSprite != (Object)null) ? hivebloodMaskSprite : maskSprite); Color normalMaskFilledColor = GetNormalMaskFilledColor(); for (int i = 0; i < num2 && i < maskImages.Length; i++) { Image val2 = maskImages[i]; if (!((Object)(object)val2 == (Object)null)) { if ((Object)(object)val != (Object)null) { val2.sprite = val; } ((Graphic)val2).color = ((i < num5) ? normalMaskFilledColor : missingMaskColor); } } for (int j = 0; j < num3; j++) { int num12 = num2 + j; if (num12 >= maskImages.Length) { break; } Image val3 = maskImages[num12]; if ((Object)(object)val3 == (Object)null) { continue; } if ((Object)(object)maskSprite != (Object)null) { val3.sprite = maskSprite; } if (j < num6) { if (!((Component)val3).gameObject.activeSelf) { ((Component)val3).gameObject.SetActive(true); } ((Graphic)val3).color = lifebloodMaskColor; } else if (!animatingMaskImages.Contains(val3) && ((Component)val3).gameObject.activeSelf) { ((Component)val3).gameObject.SetActive(false); } } RefreshHivebloodPreview(); previousShadeTotalHealth = num7; } private Color GetNormalMaskFilledColor() { //IL_0009: 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_0017: Unknown result type (might be due to invalid IL or missing references) if (shadeOvercharmed) { return overcharmMaskColor; } if (!hivebloodEquipped) { return Color.white; } return hivebloodMaskColor; } private void RefreshHivebloodPreview() { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017b: 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) if ((Object)(object)hivebloodPreviewMask == (Object)null && maskImages == null) { return; } if (shadeAssistModeActive) { HideHivebloodPreview(); return; } ShadeCharmInventory charms = ShadeRuntime.Charms; if (charms == null || !charms.HivebloodMaskRegenerating) { HideHivebloodPreview(); return; } float num = Mathf.Clamp(charms.HivebloodRegenTimer, 0f, charms.HivebloodRegenDuration); if (num < 3.5f) { HideHivebloodPreview(); return; } if (maskImages == null || maskImages.Length == 0) { HideHivebloodPreview(); return; } int num2 = Mathf.Max(0, shadeMax); if (num2 <= 0 || shadeHealth < 0 || shadeHealth >= num2) { HideHivebloodPreview(); return; } if (shadeHealth >= maskImages.Length) { HideHivebloodPreview(); return; } Image val = maskImages[shadeHealth]; if ((Object)(object)val == (Object)null) { HideHivebloodPreview(); return; } Image val2 = EnsureHivebloodPreviewMask(); RectTransform rectTransform = ((Graphic)val2).rectTransform; RectTransform rectTransform2 = ((Graphic)val).rectTransform; ((Transform)rectTransform).SetParent((Transform)(object)rectTransform2, false); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); rectTransform.anchorMax = val3; rectTransform.anchorMin = val3; rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.anchoredPosition = Vector2.zero; ((Transform)rectTransform).localScale = Vector3.one; ((Transform)rectTransform).localRotation = Quaternion.identity; ((Transform)rectTransform).SetAsLastSibling(); float num3 = ((num >= 7f) ? (2f / 3f) : (1f / 3f)); Vector2 sizeDelta = rectTransform2.sizeDelta; rectTransform.sizeDelta = sizeDelta * num3; Sprite val4 = hivebloodMaskSprite ?? maskSprite ?? val.sprite; if ((Object)(object)val4 != (Object)null) { val2.sprite = val4; } ((Graphic)val2).color = hivebloodMaskColor; ((Behaviour)val2).enabled = true; GameObject gameObject = ((Component)val2).gameObject; if (!gameObject.activeSelf) { gameObject.SetActive(true); } } private Image EnsureHivebloodPreviewMask() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hivebloodPreviewMask != (Object)null) { return hivebloodPreviewMask; } GameObject val = new GameObject("HivebloodRegenPreview"); RectTransform obj = val.AddComponent<RectTransform>(); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); obj.anchorMax = val2; obj.anchorMin = val2; obj.pivot = new Vector2(0.5f, 0.5f); ((Transform)obj).SetParent(((Component)this).transform, false); val.SetActive(false); hivebloodPreviewMask = val.AddComponent<Image>(); hivebloodPreviewMask.preserveAspect = true; ((Graphic)hivebloodPreviewMask).raycastTarget = false; return hivebloodPreviewMask; } private void HideHivebloodPreview() { if (!((Object)(object)hivebloodPreviewMask == (Object)null)) { RectTransform rectTransform = ((Graphic)hivebloodPreviewMask).rectTransform; if ((Object)(object)rectTransform != (Object)null && (Object)(object)((Transform)rectTransform).parent != (Object)(object)((Component)this).transform) { ((Transform)rectTransform).SetParent(((Component)this).transform, false); } GameObject gameObject = ((Component)hivebloodPreviewMask).gameObject; if (gameObject.activeSelf) { gameObject.SetActive(false); } } } private IEnumerator LoseHealth(Image img, bool wasOvercharmed, bool wasLifeblood, bool hivebloodActive) { if (!((Object)(object)img == (Object)null)) { animatingMaskImages.Add(img); Color filledColor; Color flickerColor; Color emptyColor; if (wasLifeblood) { filledColor = lifebloodMaskColor; flickerColor = new Color(lifebloodMaskColor.r, lifebloodMaskColor.g, lifebloodMaskColor.b, Mathf.Clamp01(lifebloodMaskColor.a * 0.6f)); emptyColor = lifebloodMissingColor; } else { filledColor = (wasOvercharmed ? overcharmMaskColor : (hivebloodActive ? hivebloodMaskColor : Color.white)); flickerColor = (wasOvercharmed ? filledColor : Color.red); emptyColor = missingMaskColor; } for (int i = 0; i < 2; i++) { ((Graphic)img).color = filledColor; yield return (object)new WaitForSeconds(0.05f); ((Graphic)img).color = flickerColor; yield return (object)new WaitForSeconds(0.05f); } ((Graphic)img).color = emptyColor; if (wasLifeblood) { HideLifebloodMaskIfDepleted(img); } animatingMaskImages.Remove(img); } } private void HideLifebloodMaskIfDepleted(Image img) { if ((Object)(object)img == (Object)null || maskImages == null) { return; } int num = Array.IndexOf(maskImages, img); if (num < 0) { return; } int num2 = Mathf.Max(0, shadeMax); int num3 = num - num2; if (num3 >= 0) { int num4 = Mathf.Clamp(shadeLifeblood, 0, Mathf.Max(0, shadeLifebloodMax)); if (num3 >= num4 && ((Component)img).gameObject.activeSelf) { ((Component)img).gameObject.SetActive(false); } } } private void RefreshSoul() { if (!((Object)(object)soulOrbRoot == (Object)null)) { float num = (shadeSoulOverride ? Mathf.Max(1f, shadeSoulMax) : Mathf.Max(1f, (float)playerData.silkMax)); float fillAmount = Mathf.Clamp01((shadeSoulOverride ? Mathf.Clamp(shadeSoul, 0f, num) : (debugUseCustomSilk ? debugSilk : ((float)playerData.silk))) / num); if ((Object)(object)soulImage != (Object)null) { soulImage.fillAmount = fillAmount; } } } private void HandleAssistVisibilityChange() { if ((Object)(object)healthContainer == (Object)null) { return; } bool flag = Mathf.Max(0, shadeMax) + Mathf.Max(0, shadeLifebloodMax) > 0; bool flag2 = !shadeAssistModeActive && flag; if (healthContainer.activeSelf != flag2) { healthContainer.SetActive(flag2); if (flag2) { pendingMaskRefresh = true; } } if ((Object)(object)overcharmBackdrop != (Object)null) { bool flag3 = flag2 && shadeOvercharmed; ((Behaviour)overcharmBackdrop).enabled = flag3; ((Component)overcharmBackdrop).gameObject.SetActive(flag3); } } private void RebuildMasks() { if (shadeAssistModeActive) { pendingMaskRefresh = true; return; } if ((Object)(object)healthContainer == (Object)null) { pendingMaskRefresh = true; return; } HideHivebloodPreview(); Image[] array = maskImages ?? Array.Empty<Image>(); foreach (Image val in array) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } animatingMaskImages.Clear(); BuildMasks(healthContainer.GetComponent<RectTransform>(), GetUIScale()); pendingMaskRefresh = false; } private void BuildMasks(RectTransform container, float uiScale) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(0, shadeMax) + Mathf.Max(0, shadeLifebloodMax); maskImages = (Image[])(object)new Image[num]; Vector2 val; if (!((Object)(object)maskSprite != (Object)null)) { val = new Vector2(33f, 41f); } else { Rect rect = maskSprite.rect; float width = ((Rect)(ref rect)).width; rect = maskSprite.rect; val = new Vector2(width, ((Rect)(ref rect)).height); } Vector2 val2 = val * uiScale * 0.88f; float num2 = 6f * uiScale; overcharmMaskSize = val2; overcharmMaskSpacing = num2; EnsureOvercharmBackdrop(container); float num3 = 0f; Vector2 val4 = default(Vector2); for (int i = 0; i < num; i++) { GameObject val3 = new GameObject($"Mask{i}"); val3.transform.SetParent((Transform)(object)container, false); RectTransform obj = val3.AddComponent<RectTransform>(); ((Vector2)(ref val4))..ctor(1f, 1f); obj.anchorMax = val4; obj.anchorMin = val4; obj.pivot = new Vector2(1f, 1f); obj.sizeDelta = val2; obj.anchoredPosition = new Vector2(0f - num3, 0f); num3 += val2.x + num2; Image val5 = val3.AddComponent<Image>(); val5.preserveAspect = true; val5.sprite = (((Object)(object)maskSprite != (Object)null) ? maskSprite : BuildMaskSprite()); ((Graphic)val5).color = Color.white; maskImages[i] = val5; } RefreshOvercharmBackdrop(); } private void EnsureOvercharmBackdrop(RectTransform container) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)container == (Object)null)) { if ((Object)(object)overcharmBackdrop == (Object)null) { GameObject val = new GameObject("OvercharmBackdrop"); val.transform.SetParent((Transform)(object)container, false); overcharmBackdrop = val.AddComponent<Image>(); ((Graphic)overcharmBackdrop).raycastTarget = false; overcharmBackdrop.preserveAspect = true; } if ((Object)(object)overcharmBackdropSprite != (Object)null) { overcharmBackdrop.sprite = overcharmBackdropSprite; ((Graphic)overcharmBackdrop).color = overcharmBackdropSpriteColor; } else if ((Object)(object)overcharmBackdrop.sprite == (Object)null) { overcharmBackdrop.sprite = BuildMaskSprite(); ((Graphic)overcharmBackdrop).color = overcharmBackdropColor; } else { ((Graphic)overcharmBackdrop).color = overcharmBackdropColor; } RectTransform rectTransform = ((Graphic)overcharmBackdrop).rectTransform; ((Transform)rectTransform).localScale = new Vector3(3.4f, 3.4f, 1f); ((Transform)rectTransform).localRotation = Quaternion.Euler(0f, 0f, 180f); ((Component)overcharmBackdrop).transform.SetAsFirstSibling(); } } private void RefreshOvercharmBackdrop() { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) if (shadeAssistModeActive) { if ((Object)(object)overcharmBackdrop != (Object)null) { ((Behaviour)overcharmBackdrop).enabled = false; ((Component)overcharmBackdrop).gameObject.SetActive(false); } } else { if ((Object)(object)healthContainer == (Object)null) { return; } EnsureOvercharmBackdrop(healthContainer.GetComponent<RectTransform>()); if ((Object)(object)overcharmBackdrop == (Object)null) { return; } if (Mathf.Max(0, shadeMax) + Mathf.Max(0, shadeLifebloodMax) <= 0 || maskImages == null || maskImages.Length == 0) { ((Behaviour)overcharmBackdrop).enabled = false; ((Component)overcharmBackdrop).gameObject.SetActive(false); return; } if (!TryCalculateMaskBounds(out var min, out var max)) { ((Behaviour)overcharmBackdrop).enabled = false; ((Component)overcharmBackdrop).gameObject.SetActive(false); return; } float num = Mathf.Max(0f, max.x - min.x); float num2 = Mathf.Max(0f, max.y - min.y); float num3 = num; float num4 = num2; if (overcharmMaskSize.x > 0f) { float num5 = overcharmMaskSize.x * 3f; if (overcharmMaskSpacing > 0f) { num5 += overcharmMaskSpacing * 2f; } num3 = num5; } if (overcharmMaskSize.y > 0f) { num4 = overcharmMaskSize.y; } if (num3 <= 0f || num4 <= 0f) { num3 = num; num4 = num2; } if (num3 <= 0f || num4 <= 0f) { ((Behaviour)overcharmBackdrop).enabled = false; ((Component)overcharmBackdrop).gameObject.SetActive(false); return; } RectTransform rectTransform = ((Graphic)overcharmBackdrop).rectTransform; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(1f, 1f); rectTransform.anchorMax = val; rectTransform.anchorMin = val; rectTransform.pivot = new Vector2(1f, 1f); rectTransform.sizeDelta = new Vector2(num3, num4); float num6 = 3.4f; ((Transform)rectTransform).localScale = new Vector3(num6, num6, 1f); ((Transform)rectTransform).localRotation = Quaternion.Euler(0f, 0f, 180f); float num7 = Mathf.Min(0f, max.x); float y = max.y; float num8 = num3 * 3.2f; if (num8 <= 0f && overcharmMaskSize.x > 0f) { num8 = overcharmMaskSize.x * 0.55f; } float num9 = num4 * 1.4f; if (num9 <= 0f && overcharmMaskSize.y > 0f) { num9 = overcharmMaskSize.y * 0.65f; } rectTransform.anchoredPosition = new Vector2(num7 - num8, y - num9); if ((Object)(object)overcharmBackdropSprite != (Object)null) { overcharmBackdrop.sprite = overcharmBackdropSprite; ((Graphic)overcharmBackdrop).color = overcharmBackdropSpriteColor; } else if ((Object)(object)overcharmBackdrop.sprite == (Object)null) { overcharmBackdrop.sprite = BuildMaskSprite(); ((Graphic)overcharmBackdrop).color = overcharmBackdropColor; } else { ((Graphic)overcharmBackdrop).color = overcharmBackdropColor; } ((Behaviour)overcharmBackdrop).enabled = shadeOvercharmed; ((Component)overcharmBackdrop).gameObject.SetActive(shadeOvercharmed); ((Component)overcharmBackdrop).transform.SetAsFirstSibling(); } } private bool TryCalculateMaskBounds(out Vector2 min, out Vector2 max) { //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_000c: 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_0060: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_0080: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0155: 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_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_0116: Unknown result type (might be due to invalid IL or missing references) min = Vector2.zero; max = Vector2.zero; if (maskImages == null || maskImages.Length == 0) { return false; } bool flag = false; Image[] array = maskImages; Vector2 val2 = default(Vector2); Vector2 val3 = default(Vector2); foreach (Image val in array) { if ((Object)(object)val == (Object)null) { continue; } RectTransform rectTransform = ((Graphic)val).rectTransform; if (!((Object)(object)rectTransform == (Object)null)) { Vector2 anchoredPosition = rectTransform.anchoredPosition; Rect rect = rectTransform.rect; Vector2 size = ((Rect)(ref rect)).size; Vector2 pivot = rectTransform.pivot; float num = anchoredPosition.x - size.x * pivot.x; float num2 = anchoredPosition.x + size.x * (1f - pivot.x); float num3 = anchoredPosition.y - size.y * pivot.y; float num4 = anchoredPosition.y + size.y * (1f - pivot.y); ((Vector2)(ref val2))..ctor(num, num3); ((Vector2)(ref val3))..ctor(num2, num4); if (!flag) { min = val2; max = val3; flag = true; } else { min = new Vector2(Mathf.Min(min.x, val2.x), Mathf.Min(min.y, val2.y)); max = new Vector2(Mathf.Max(max.x, val3.x), Mathf.Max(max.y, val3.y)); } } } if (!flag) { return false; } return true; } } [BepInPlugin("com.legacyoftheabyss.helper", "Legacy of the Abyss - Helper", "0.1.0")] public class LegacyHelper : BaseUnityPlugin { [HarmonyPatch(typeof(GameManager), "BeginScene")] private class GameManager_BeginScene_Patch { [CompilerGenerated] private static class <>O { public static EnterSceneEvent <0>__HandleFinishedEnteringScene; } private static void Postfix(GameManager __instance) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_007b: 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_0086: Expected O, but got Unknown if ((Object)(object)__instance != (Object)null) { ShadeRuntime.SyncActiveSlot(__instance); } DisableStartup(__instance); bool flag = __instance.IsGameplayScene(); if ((Object)(object)hud != (Object)null) { try { hud.SetVisible(flag && ModConfig.Instance.shadeEnabled); } catch { } } if (!flag) { DestroyShadeInstance(); return; } if (!ModConfig.Instance.shadeEnabled) { DestroyShadeInstance(); return; } if (!registeredEnterSceneHandler) { try { object obj2 = <>O.<0>__HandleFinishedEnteringScene; if (obj2 == null) { EnterSceneEvent val = HandleFinishedEnteringScene; <>O.<0>__HandleFinishedEnteringScene = val; obj2 = (object)val; } __instance.OnFinishedEnteringScene += (EnterSceneEvent)obj2; registeredEnterSceneHandler = true; } catch { } } if ((Object)(object)hud == (Object)null) { GameObject val2 = new GameObject("SimpleHUD"); Object.DontDestroyOnLoad((Object)val2); hud = val2.AddComponent<SimpleHUD>(); hud.Init(__instance.playerData); return; } try { hud.SetPlayerData(__instance.playerData); } catch { } } } [HarmonyPatch(typeof(TrackTriggerObjects), "OnTriggerEnter2D")] private static class TrackTriggerObjects_OnTriggerEnter2D_Patch { private static bool Prefix(TrackTriggerObjects __instance, Collider2D collision) { if (__instance is CameraLockArea && Object.op_Implicit((Object)(object)collision)) { try { if ((Object)(object)((Component)collision).GetComponent<ShadeController.AggroProxyTracker>() != (Object)null) { return false; } } catch { } } return true; } } [HarmonyPatch(typeof(Remasker), "OnTriggerEnter2D")] private static class Remasker_OnTriggerEnter2D_Patch { private static bool Prefix(Remasker __instance, Collider2D collision) { if ((Object)(object)collision == (Object)null) { return true; } ShadeController.AggroProxyTracker component = ((Component)collision).GetComponent<ShadeController.AggroProxyTracker>(); if ((Object)(object)component == (Object)null) { return true; } try { component.NotifyRemaskerIgnored(__instance); } catch { } return false; } } [HarmonyPatch(typeof(Remasker), "OnTriggerExit2D")] private static class Remasker_OnTriggerExit2D_Patch { private static bool Prefix(Remasker __instance, Collider2D collision) { if ((Object)(object)collision == (Object)null) { return true; } ShadeController.AggroProxyTracker component = ((Component)collision).GetComponent<ShadeController.AggroProxyTracker>(); if ((Object)(object)component == (Object)null) { return true; } try { component.NotifyRemaskerIgnored(__instance); } catch { } return false; } } [HarmonyPatch(typeof(AlertRange), "FixedUpdate")] internal static class AlertRange_FixedUpdate_Patch { private sealed class LogState { public bool Logged; } private static readonly FieldRef<AlertRange, bool> HaveLineOfSightRef = AccessTools.FieldRefAccess<AlertRange, bool>("haveLineOfSight"); private static readonly FieldRef<AlertRange, bool> IsHeroInRangeRef = AccessTools.FieldRefAccess<AlertRange, bool>("isHeroInRange"); private static readonly FieldRef<AlertRange, LineOfSightChecks> LineOfSightModeRef = AccessTools.FieldRefAccess<AlertRange, LineOfSightChecks>("lineOfSight"); private static readonly FieldRef<AlertRange, Transform> InitialParentRef = AccessTools.FieldRefAccess<AlertRange, Transform>("initialParent"); private static readonly List<ShadeAggroTracker.Target> TargetBuffer = new List<ShadeAggroTracker.Target>(); private static readonly ConditionalWeakTable<AlertRange, LogState> LoggedStates = new ConditionalWeakTable<AlertRange, LogState>(); private static void Postfix(AlertRange __instance) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Invalid comparison between Unknown and I4 //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Invalid comparison between Unknown and I4 //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)__instance == (Object)null || !ShadeAggroTracker.TryGetTargets(__instance, TargetBuffer) || TargetBuffer.Count == 0) { return; } bool flag = HaveLineOfSightRef.Invoke(__instance); bool flag2 = IsHeroInRangeRef.Invoke(__instance); bool flag3 = false; LineOfSightChecks val = LineOfSightModeRef.Invoke(__instance); if ((int)val <= 0) { flag3 = true; } else { Transform val2 = null; if ((int)val != 1) { if ((int)val == 2) { val2 = ((Component)__instance).transform.parent ?? InitialParentRef.Invoke(__instance); } } else { val2 = ((Component)__instance).transform; } Vector2 val3 = (Object.op_Implicit((Object)(object)val2) ? Vector2.op_Implicit(val2.position) : Vector2.op_Implicit(((Component)__instance).transform.position)); RaycastHit2D val4 = default(RaycastHit2D); foreach (ShadeAggroTracker.Target item in TargetBuffer) { if ((Object)(object)item.Shade == (Object)null || !item.Shade.IsAggroEligible || Helper.LineCast2DHit(val3, item.Position, 256, ref val4)) { continue; } flag3 = true; if (flag) { break; } LogState orCreateValue = LoggedStates.GetOrCreateValue(__instance); if (orCreateValue.Logged || !ModConfig.Instance.logShade) { break; } try { string text = (((Object)(object)item.Shade != (Object)null) ? ((Object)((Component)item.Shade).gameObject).name : "Shade"); object obj; if (!((Object)(object)((Component)__instance).transform != (Object)null)) { obj = ((Object)__instance).name; } else { Transform root = ((Component)__instance).transform.root; obj = ((root != null) ? ((Object)root).name : null) ?? ((Object)((Component)__instance).transform).name; } string text2 = (string)obj; LegacyHelper instance = Instance; if (instance != null) { ManualLogSource logger = ((BaseUnityPlugin)instance).Logger; if (logger != null) { logger.LogInfo((object)("Shade aggro granted line of sight for '" + ((Object)__instance).name + "' on '" + text2 + "' via shade '" + text + "'.")); } } } catch { } orCreateValue.Logged = true; break; } } if (!flag2) { IsHeroInRangeRef.Invoke(__instance) = true; } if (flag3) { HaveLineOfSightRef.Invoke(__instance) = true; } else { LoggedStates.GetOrCreateValue(__instance).Logged = false; } } catch (Exception arg) { try { LegacyHelper instance2 = Instance; if (instance2 != null) { ManualLogSource logger2 = ((BaseUnityPlugin)instance2).Logger; if (logger2 != null) { logger2.LogWarning((object)$"Shade aggro patch failed for '{((__instance != null) ? ((Object)__instance).name : null)}': {arg}"); } } } catch { } } finally { TargetBuffer.Clear(); } } internal static void ResetLog(AlertRange range) { if (!((Object)(object)range == (Object)null) && LoggedStates.TryGetValue(range, out var value)) { value.Logged = false; } } } [HarmonyPatch(typeof(GameManager), "PlayerDead")] private class GameManager_PlayerDead_Patch { private static void Postfix(GameManager __instance) { try { if (!ModConfig.Instance.shadeEnabled) { return; } if (ModConfig.Instance.shadeEnabled && (Object)(object)helper != (Object)null) { ShadeController component = helper.GetComponent<ShadeController>(); if ((Object)(object)component != (Object)null) { component.ReviveToAtLeast(1); SaveShadeState(component.GetCurrentNormalHP(), component.GetMaxNormalHP(), component.GetCurrentLifeblood(), component.GetMaxLifeblood(), component.GetShadeSoul(), component.GetCanTakeDamage(), component.GetBaseMaxHP()); return; } } if (ShadeRuntime.PersistentState.HasData) { ShadeRuntime.EnsureMinimumHealth(1); } } catch { } } } [HarmonyPatch(typeof(GameMap), "Update")] private class GameMap_Update_Patch { private static void Postfix(GameMap __instance) { ShadeCompassIconManager.Update(__instance); } } [HarmonyPatch(typeof(InventoryWideMap), "UpdatePositions")] private class InventoryWideMap_UpdatePositions_Patch { private static void Postfix(InventoryWideMap __instance) { ShadeCompassIconManager.UpdateWideMap(__instance); } } [HarmonyPatch(typeof(UIManager), "TogglePauseGame")] private class UIManager_TogglePauseGame_Patch { private static bool Prefix(UIManager __instance) { try { if (ShadeSettingsMenu.HandlePauseToggle(__instance)) { return false; } } catch { } return true; } } [HarmonyPatch(typeof(GameManager), "PauseGameToggle")] private class GameManager_PauseGameToggle_Patch { private static bool Prefix(GameManager __instance, ref IEnumerator __result) { try { UIManager val = UIManager.instance; if ((Object)(object)val == (Object)null && (Object)(object)__instance != (Object)null) { val = __instance.ui; } if ((Object)(object)val != (Object)null && ShadeSettingsMenu.HandlePauseToggle(val)) { __result = Skip(); return false; } } catch { } return true; } private static IEnumerator Skip() { yield break; } } [HarmonyPatch(typeof(GameManager), "PauseGameToggleByMenu")] private class GameManager_PauseGameToggleByMenu_Patch { private static bool Prefix(GameManager __instance, ref IEnumerator __result) { try { UIManager val = UIManager.instance; if ((Object)(object)val == (Object)null && (Object)(object)__instance != (Object)null) { val = __instance.ui; } if ((Object)(object)val != (Object)null && ShadeSettingsMenu.HandlePauseToggle(val)) { __result = Skip(); return false; } } catch { } return true; } private static IEnumerator Skip() { yield break; } } [HarmonyPatch(typeof(HealthManager), "SpawnCurrency")] private class HealthManager_SpawnCurrency_Patch { private static void Prefix(ref int smallGeoCount, ref int mediumGeoCount, ref int largeGeoCount, ref int largeSmoothGeoCount) { if (FragileGreedActive) { smallGeoCount = ApplyMultiplier(smallGeoCount); mediumGeoCount = ApplyMultiplier(mediumGeoCount); largeGeoCount = ApplyMultiplier(largeGeoCount); largeSmoothGeoCount = ApplyMultiplier(largeSmoothGeoCount); } } private static int ApplyMultiplier(int value) { if (value <= 0) { return value; } int num = Mathf.CeilToInt((float)value * 1.5f); return Mathf.Max(1, num); } } [HarmonyPatch(typeof(UIManager), "ShowMenu")] private class UIManager_ShowMenu_Patch { private static bool Prefix(UIManager __instance, MenuScreen menu, ref IEnumerator __result) { try { if (!ShadeSettingsMenu.IsShowing || (Object)(object)menu == (Object)null || (Object)(object)__instance == (Object)null) { return true; } if ((Object)(object)menu == (Object)(object)__instance.pauseMenuScreen || (Object)(object)menu == (Object)(object)__instance.optionsMenuScreen || (Object)(object)menu == (Object)(object)__instance.gameOptionsMenuScreen) { __result = EmptyEnumerator(); return false; } } catch { } return true; } private static IEnumerator EmptyEnumerator() { yield break; } } [HarmonyPatch(typeof(GameManager), "Awake")] private class GameManager_Awake_Patch { private static void Postfix(GameManager __instance) { registeredEnterSceneHandler = false; DisableStartup(__instance); } } [HarmonyPatch(typeof(GameManager), "Start")] private class GameManager_Start_Patch { private static void Postfix(GameManager __instance) { DisableStartup(__instance); } } [HarmonyPatch] private class InventoryPaneList_EnsureShadePane_Patch { private static IEnumerable<MethodBase> TargetMethods() { Type type = typeof(InventoryPaneList); if (type == null) { yield break; } string[] array = new string[3] { "Awake", "Start", "OnEnable" }; string[] array2 = array; foreach (string text in array2) { MethodInfo methodInfo = AccessTools.Method(type, text, (Type[])null, (Type[])null); if (methodInfo != null) { yield return methodInfo; } } } private static void Postfix(InventoryPaneList __instance) { if ((Object)(object)__instance == (Object)null) { return; } try { ShadeInventoryPaneIntegration.EnsurePane(__instance); } catch (Exception arg) { if (ModConfig.Instance.logMenu) { try { Debug.LogWarning((object)$"[ShadeInventory] Failed to ensure shade pane: {arg}"); return; } catch { return; } } } } } [HarmonyPatch(typeof(InventoryPaneInput), "PressSubmit")] private class InventoryPaneInput_PressSubmit_Shade { private static bool Prefix(InventoryPaneInput __instance) { try { ShadeInventoryPane shadeInventoryPane = ShadeInventoryPaneIntegration.TryGetShadePane(__instance) ?? ShadeInventoryPane.ActivePane; if ((Object)(object)shadeInventoryPane != (Object)null) { shadeInventoryPane.HandleSubmit(); return false; } } catch { } return true; } } [HarmonyPatch(typeof(InventoryPaneInput), "PressDirection")] private class InventoryPaneInput_PressDirection_Shade { private static void Postfix(InventoryPaneInput __instance, InputEventType direction) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) try { (ShadeInventoryPaneIntegration.TryGetShadePane(__instance) ?? ShadeInventoryPane.ActivePane)?.HandleDirectionalInput(direction); } catch { } } } [HarmonyPatch(typeof(InventoryPaneList), "BeginPane")] private class InventoryPaneList_BeginPane_BindShadeInput { private static void Postfix(InventoryPaneList __instance, InventoryPane pane) { try { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)pane == (Object)null)) { ShadeInventoryPane shadeInventoryPane = pane as ShadeInventoryPane; if ((Object)(object)shadeInventoryPane == (Object)null) { shadeInventoryPane = pane.RootPane as ShadeInventoryPane; } if ((Object)(object)shadeInventoryPane != (Object)null) { ShadeInventoryPaneIntegration.BindInput(shadeInventoryPane, __instance, captureFocus: true); } } } catch { } } } [HarmonyPatch(typeof(StartManager), "Start")] private class StartManager_Start_Enumerator_Patch { private static void Prefix(StartManager __instance) { if ((Object)(object)__instance.startManagerAnimator != (Object)null) { __instance.startManagerAnimator.SetBool("WillShowQuote", false); } } private static void Postfix(StartManager __instance, ref IEnumerator __result) { if (__result == null) { return; } FieldInfo[] fields = __result.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType == typeof(bool) && fieldInfo.Name.Contains("showIntroSequence")) { fieldInfo.SetValue(__result, false); if ((Object)(object)__instance.startManagerAnimator != (Object)null) { __instance.startManagerAnimator.Play("LoadingIcon", 0, 1f); } break; } } } } [HarmonyPatch(typeof(RestBenchHelper), "SetOnBench")] private class RestBenchHelper_SetOnBench_Patch { private static void Postfix(bool onBench) { if (!onBench) { return; } try { if (ModConfig.Instance.shadeEnabled && ModConfig.Instance.shadeEnabled && (Object)(object)helper != (Object)null) { ShadeController component = helper.GetComponent<ShadeController>(); if ((Object)(object)component != (Object)null) { component.FullHealFromBench(); SaveShadeState(component.GetCurrentNormalHP(), component.GetMaxNormalHP(), component.GetCurrentLifeblood(), component.GetMaxLifeblood(), component.GetShadeSoul(), component.GetCanTakeDamage(), component.GetBaseMaxHP()); } } } catch { } } } [HarmonyPatch(typeof(DamageEnemies), "Start")] private class DamageEnemies_Start_Mod { private static void Postfix(DamageEnemies __instance) { try { Type typeFromHandle = typeof(DamageEnemies); bool flag = false; bool flag2 = false; try { flag = (bool)(typeFromHandle.GetField("sourceIsHero", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance) ?? ((object)false)); } catch { } try { flag2 = (bool)(typeFromHandle.GetField("isHeroDamage", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance) ?? ((object)false)); } catch { } if (flag || flag2) { __instance.damageDealt = Mathf.Max(1, Mathf.RoundToInt((float)__instance.damageDealt * ModConfig.Instance.hornetDamageMultiplier)); } } catch { } } } [HarmonyPatch(typeof(HeroController), "BindCompleted")] private class HeroController_BindCompleted_Patch { private static void Prefix(HeroController __instance, out int __state) { __state = 0; try { if ((Object)(object)__instance != (Object)null && __instance.playerData != null) { __state = __instance.playerData.health; } } catch { } } private static void Postfix(HeroController __instance, int __state) { try { PlayerData val = __instance?.playerData; if (val != null) { int num = val.health - __state; int bindHornetHeal = ModConfig.Instance.bindHornetHeal; if (num != bindHornetHeal) { val.health = Mathf.Clamp(__state + bindHornetHeal, 0, val.maxHealth); } } if (ModConfig.Instance.shadeEnabled && (Object)(object)helper != (Object)null) { ShadeController component = helper.GetComponent<ShadeController>(); if ((Object)(object)component != (Object)null) { component.ApplyBindHealFromHornet(((Object)(object)__instance != (Object)null) ? __instance.transform : null); } } } catch { } } } [HarmonyPatch(typeof(InputHandler), "MapKeyboardLayoutFromGameSettings")] private class BlockKeyboardRebinding { private static bool Prefix() { try { return ModConfig.Instance?.hornetKeyboardEnabled ?? false; } catch { return false; } } } [HarmonyPatch(typeof(InputHandler), "MapDefaultKeyboardLayout")] private class BlockDefaultKeyboardMap { private static bool Prefix() { try { return ModConfig.Instance?.hornetKeyboardEnabled ?? false; } catch { return false; } } } [HarmonyPatch(typeof(InputHandler), "MapControllerButtons")] private class ControlControllerMapping { private static bool Prefix() { try { ModConfig instance = ModConfig.Instance; if (instance == null) { return true; } if (instance.hornetControllerEnabled) { return true; } ShadeInputConfig shadeInput = instance.shadeInput; if (shadeInput != null && shadeInput.UsesControllerBindings()) { return true; } return false; } catch { return true; } } } internal static class InputDeviceBlocker { [StructLayout(LayoutKind.Sequential, Size = 1)] internal readonly struct MenuTransferSaveScope : IDisposable { public void Dispose() { } } private static readonly HashSet<InputDevice> restrictedShadeDevices = new HashSet<InputDevice>(); private static readonly List<InputDevice> cleanupList = new List<InputDevice>(); private static readonly HashSet<string> AllowedHeroActions = new HashSet<string>(StringComparer.Ordinal) { "Pause", "openInventory", "openInventoryMap", "openInventoryJournal", "openInventoryTools", "openInventoryQuests", "QuickMap" }; private static readonly Dictionary<InputDevice, bool> IgnoreDeviceCache = new Dictionary<InputDevice, bool>(); private static int ignoreDeviceCacheFrame = -1; private static int blockShadeCacheFrame = -1; private static bool blockShadeCacheValue; private static void SetDeviceRestricted(InputDevice device, bool restrict) { if (device != null && device != InputDevice.Null) { if (restrict) { restrictedShadeDevices.Add(device); } else { restrictedShadeDevices.Remove(device); } } } private static void ReleaseTrackedDevices(InputHandler handler) { if (restrictedShadeDevices.Count == 0) { return; } cleanupList.Clear(); cleanupList.AddRange(restrictedShadeDevices); foreach (InputDevice cleanup in cleanupList) { SetDeviceRestricted(cleanup, restrict: false); } cleanupList.Clear(); } private static void CleanupDetachedDevices(InputHandler handler, IList<InputDevice> devices) { if (restrictedShadeDevices.Count == 0) { return; } cleanupList.Clear(); cleanupList.AddRange(restrictedShadeDevices); foreach (InputDevice cleanup in cleanupList) { if (cleanup == null || cleanup == InputDevice.Null) { SetDeviceRestricted(cleanup, restrict: false); } else if (devices == null || !ContainsDevice(devices, cleanup)) { SetDeviceRestricted(cleanup, restrict: false); } } cleanupList.Clear(); } private static bool ContainsDevice(IList<InputDevice> list, InputDevice device) { if (list == null || device == null || device == InputDevice.Nul