Decompiled source of Blind Deaf and Mute Challenge v1.1.0
tony4twentys-Blind Deaf and Mute Challenge.dll
Decompiled 17 hours 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.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using PEAKLib.Core; using Photon.Pun; using Photon.Realtime; using PhotonCustomPropsUtils; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; using Zorro.Core; using Zorro.Settings; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Blind Deaf and Mute Challenge")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Blind Deaf and Mute Challenge")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("c2254fa2-c18c-428a-b0c2-1c7b26f94967")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } } namespace BlindDeafMuteChallenge { internal static class BdmAbilityHud { private sealed class AbilityWidget { internal GameObject Root; internal Image OuterFill; internal Image OuterEmpty; internal Image InnerFill; internal Image InnerEmpty; internal GameObject InnerRoot; internal Image Icon; internal TextMeshProUGUI Label; internal CanvasGroup Group; } private const int SortOrder = 6000; private const float Gap = 100f; private const float IconSize = 32f; private const float InnerScale = 0.72f; private static readonly Color DefaultCooldownColor = new Color(1f, 0.82f, 0.15f, 1f); private static readonly Color DefaultUseColor = new Color(0.72f, 0.35f, 0.95f, 1f); private static GameObject _root; private static Canvas _canvas; private static RectTransform _row; private static AbilityWidget _sonar; private static AbilityWidget _hook; private static AbilityWidget _detection; private static Sprite _sonarSprite; private static Sprite _hookSprite; private static Sprite _detectionSprite; private static int _hookIconItemId = int.MinValue; private static bool _detectionIconTried; private static bool _loggedMissingTemplate; private static bool _loggedCloned; internal static void EnsureCreated() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0078: 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) //IL_008e: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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) if (!((Object)(object)_root != (Object)null)) { _root = new GameObject("BDM_AbilityHud"); Object.DontDestroyOnLoad((Object)(object)_root); _canvas = _root.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 6000; CanvasScaler val = _root.AddComponent<CanvasScaler>(); val.uiScaleMode = (ScaleMode)1; val.referenceResolution = new Vector2(1920f, 1080f); GameObject val2 = new GameObject("Row"); val2.transform.SetParent(_root.transform, false); _row = val2.AddComponent<RectTransform>(); _row.anchorMin = new Vector2(0.5f, 0f); _row.anchorMax = new Vector2(0.5f, 0f); _row.pivot = new Vector2(0.5f, 0f); _row.anchoredPosition = new Vector2(0f, 0f); _row.sizeDelta = new Vector2(280f, 140f); _root.SetActive(false); } } internal static void Shutdown() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); _root = null; } _canvas = null; _row = null; _sonar = null; _hook = null; _detection = null; _sonarSprite = null; _hookSprite = null; _detectionSprite = null; _hookIconItemId = int.MinValue; _detectionIconTried = false; _loggedMissingTemplate = false; _loggedCloned = false; } internal static void Tick() { EnsureCreated(); BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null || !BdmModAuthorizationService.CanUseSyncedChallenge()) { if ((Object)(object)_root != (Object)null && _root.activeSelf) { _root.SetActive(false); } return; } BdmSyncedSettings effectiveSettings = instance.GetEffectiveSettings(); bool flag = instance.IsBlindEffectWanted() && effectiveSettings.EnableSonar; bool flag2 = instance.IsLocalMuteActive && effectiveSettings.EnableRescueHook; bool flag3 = instance.IsLocalDeafActive && effectiveSettings.EnableDetection; if (!flag && !flag2 && !flag3) { if (_root.activeSelf) { _root.SetActive(false); } return; } if (!EnsureWidgetsFromVanillaTemplate()) { if (_root.activeSelf) { _root.SetActive(false); } return; } if (!_root.activeSelf) { _root.SetActive(true); } EnsureIcons(); ApplyLiveLayout(); if (_sonar != null) { _sonar.Root.SetActive(flag); if (flag) { UpdateWidget(_sonar, BdmBlindSonar.HudCooldownFill, BdmBlindSonar.HudUseFill, BdmBlindSonar.IsReady, BdmBlindSonar.IsActive, "Sonar"); } } if (_detection != null) { _detection.Root.SetActive(flag3); if (flag3) { UpdateWidget(_detection, BdmDeafDetection.HudCooldownFill, BdmDeafDetection.HudUseFill, BdmDeafDetection.IsReady, BdmDeafDetection.IsActive, "Detection"); } } if (_hook != null) { _hook.Root.SetActive(flag2); if (flag2) { UpdateWidget(_hook, BdmMuteRescueHook.HudCooldownFill, BdmMuteRescueHook.HudUseFill, BdmMuteRescueHook.IsReady, BdmMuteRescueHook.IsActive, "Lifeline"); } } LayoutWidgets(flag, flag3, flag2); } private static void ApplyLiveLayout() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; float num = (((Object)(object)instance != (Object)null) ? instance.AbilityHudPosX : 0f); float num2 = (((Object)(object)instance != (Object)null) ? instance.AbilityHudPosY : 0f); float labelY = (((Object)(object)instance != (Object)null) ? instance.AbilityHudLabelOffsetY : 54f); float fontSize = (((Object)(object)instance != (Object)null) ? instance.AbilityHudLabelFontSize : 30f); if ((Object)(object)_row != (Object)null) { _row.anchoredPosition = new Vector2(num, num2); } ApplyLabelStyle(_sonar, labelY, fontSize); ApplyLabelStyle(_detection, labelY, fontSize); ApplyLabelStyle(_hook, labelY, fontSize); } private static void ApplyLabelStyle(AbilityWidget widget, float labelY, float fontSize) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)widget?.Label == (Object)null)) { RectTransform rectTransform = ((TMP_Text)widget.Label).rectTransform; rectTransform.anchoredPosition = new Vector2(0f, labelY); rectTransform.sizeDelta = new Vector2(Mathf.Max(160f, fontSize * 7.5f), Mathf.Max(22f, fontSize + 6f)); ((TMP_Text)widget.Label).fontSize = fontSize; BdmGameUiFont.Apply(widget.Label); } } private static Color GetCooldownColor() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; return ((Object)(object)instance != (Object)null) ? instance.AbilityHudCooldownColor : DefaultCooldownColor; } private static Color GetUseColor() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; return ((Object)(object)instance != (Object)null) ? instance.AbilityHudUseColor : DefaultUseColor; } private static bool EnsureWidgetsFromVanillaTemplate() { if (_sonar != null && _hook != null && _detection != null) { return true; } UI_UseItemProgress val = FindVanillaProgress(); if ((Object)(object)val == (Object)null || (Object)(object)val.fill == (Object)null || (Object)(object)val.empty == (Object)null) { if (!_loggedMissingTemplate) { _loggedMissingTemplate = true; BlindDeafMuteChallengePlugin.Instance?.LogDebug("[BlindDeafMute] Ability HUD waiting for vanilla UI_UseItemProgress..."); } return false; } if (_sonar == null) { _sonar = CloneDualRingWidget(val, "Sonar"); } if (_detection == null) { _detection = CloneDualRingWidget(val, "Detection"); } if (_hook == null) { _hook = CloneDualRingWidget(val, "RescueHook"); } if (_sonar == null || _hook == null || _detection == null) { return false; } if (!_loggedCloned) { _loggedCloned = true; BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Ability HUD: dual concentric UI_UseItemProgress rings ready."); } return true; } private static UI_UseItemProgress FindVanillaProgress() { try { if ((Object)(object)GUIManager.instance != (Object)null && (Object)(object)GUIManager.instance.hudCanvas != (Object)null) { UI_UseItemProgress componentInChildren = ((Component)GUIManager.instance.hudCanvas).GetComponentInChildren<UI_UseItemProgress>(true); if ((Object)(object)componentInChildren != (Object)null) { return componentInChildren; } } } catch { } return Object.FindFirstObjectByType<UI_UseItemProgress>((FindObjectsInactive)1); } private static AbilityWidget CloneDualRingWidget(UI_UseItemProgress template, string name) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Expected O, but got Unknown //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)template == (Object)null || (Object)(object)_row == (Object)null) { return null; } GameObject val = new GameObject("BDM_" + name); val.transform.SetParent((Transform)(object)_row, false); RectTransform val2 = val.AddComponent<RectTransform>(); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = Vector2.zero; val2.sizeDelta = new Vector2(120f, 140f); CanvasGroup val4 = val.AddComponent<CanvasGroup>(); val4.blocksRaycasts = false; val4.interactable = false; if (!TryCloneRingPair(template, val.transform, "Outer", 1f, GetCooldownColor(), out var fill, out var empty, out var _)) { Object.Destroy((Object)(object)val); return null; } if (!TryCloneRingPair(template, val.transform, "Inner", 0.72f, GetUseColor(), out var fill2, out var empty2, out var cloneRoot2)) { Object.Destroy((Object)(object)val); return null; } GameObject val5 = new GameObject("BDM_Icon"); val5.transform.SetParent(val.transform, false); RectTransform val6 = val5.AddComponent<RectTransform>(); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); val6.anchorMax = val3; val6.anchorMin = val3; val6.pivot = new Vector2(0.5f, 0.5f); val6.sizeDelta = new Vector2(32f, 32f); val6.anchoredPosition = Vector2.zero; Image val7 = val5.AddComponent<Image>(); val7.preserveAspect = true; ((Graphic)val7).raycastTarget = false; ((Graphic)val7).color = Color.white; GameObject val8 = new GameObject("BDM_Label"); val8.transform.SetParent(val.transform, false); RectTransform val9 = val8.AddComponent<RectTransform>(); val9.anchorMin = new Vector2(0.5f, 0f); val9.anchorMax = new Vector2(0.5f, 0f); val9.pivot = new Vector2(0.5f, 1f); val9.anchoredPosition = new Vector2(0f, 54f); val9.sizeDelta = new Vector2(220f, 36f); TextMeshProUGUI val10 = val8.AddComponent<TextMeshProUGUI>(); ((Graphic)val10).raycastTarget = false; ((TMP_Text)val10).enableWordWrapping = false; ((TMP_Text)val10).overflowMode = (TextOverflowModes)0; ((TMP_Text)val10).alignment = (TextAlignmentOptions)258; ((TMP_Text)val10).fontSize = 30f; ((TMP_Text)val10).fontStyle = (FontStyles)0; ((Graphic)val10).color = new Color(1f, 1f, 1f, 0.92f); ((TMP_Text)val10).text = ((name == "RescueHook") ? "Lifeline" : name); BdmGameUiFont.Apply(val10); return new AbilityWidget { Root = val, OuterFill = fill, OuterEmpty = empty, InnerFill = fill2, InnerEmpty = empty2, InnerRoot = cloneRoot2, Icon = val7, Label = val10, Group = val4 }; } private static bool TryCloneRingPair(UI_UseItemProgress template, Transform parent, string name, float scale, Color fillColor, out Image fill, out Image empty, out GameObject cloneRoot) { //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Invalid comparison between Unknown and I4 fill = null; empty = null; cloneRoot = null; GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, parent, false); ((Object)val).name = name; val.SetActive(true); cloneRoot = val; UI_UseItemProgress component = val.GetComponent<UI_UseItemProgress>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } fill = (((Object)(object)component != (Object)null) ? component.fill : null); empty = (((Object)(object)component != (Object)null) ? component.empty : null); if ((Object)(object)fill == (Object)null || (Object)(object)empty == (Object)null) { Image[] componentsInChildren = val.GetComponentsInChildren<Image>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (!((Object)(object)componentsInChildren[i] == (Object)null)) { if ((Object)(object)fill == (Object)null && (int)componentsInChildren[i].type == 3) { fill = componentsInChildren[i]; } else if ((Object)(object)empty == (Object)null && (Object)(object)componentsInChildren[i] != (Object)(object)fill) { empty = componentsInChildren[i]; } } } } if ((Object)(object)fill == (Object)null) { Object.Destroy((Object)(object)val); cloneRoot = null; return false; } RectTransform component2 = val.GetComponent<RectTransform>(); if ((Object)(object)component2 != (Object)null) { Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); component2.anchorMax = val2; component2.anchorMin = val2; component2.pivot = new Vector2(0.5f, 0.5f); component2.anchoredPosition = Vector2.zero; ((Transform)component2).localScale = Vector3.one * scale; } ConfigureRadial(fill, fillColor); if ((Object)(object)empty != (Object)null) { ((Behaviour)empty).enabled = true; ((Graphic)empty).raycastTarget = false; } return true; } private static void ConfigureRadial(Image fill, Color color) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)fill == (Object)null)) { if ((int)fill.type != 3) { fill.type = (Type)3; fill.fillMethod = (FillMethod)4; fill.fillOrigin = 2; fill.fillClockwise = true; } ((Graphic)fill).color = color; ((Behaviour)fill).enabled = true; ((Graphic)fill).raycastTarget = false; } } private static void LayoutWidgets(bool showSonar, bool showDetection, bool showHook) { List<AbilityWidget> list = new List<AbilityWidget>(3); if (showSonar && _sonar != null) { list.Add(_sonar); } if (showDetection && _detection != null) { list.Add(_detection); } if (showHook && _hook != null) { list.Add(_hook); } if (list.Count != 0) { if (list.Count == 1) { SetWidgetX(list[0], 0f); } else if (list.Count == 2) { float num = 50f; SetWidgetX(list[0], 0f - num); SetWidgetX(list[1], num); } else { SetWidgetX(list[0], -100f); SetWidgetX(list[1], 0f); SetWidgetX(list[2], 100f); } } } private static void SetWidgetX(AbilityWidget widget, float x) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) RectTransform component = widget.Root.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { component.anchoredPosition = new Vector2(x, 24f); } } private static void UpdateWidget(AbilityWidget widget, float cooldownFill, float useFill, bool ready, bool active, string labelText) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_0074: 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_0171: 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_0186: Unknown result type (might be due to invalid IL or missing references) cooldownFill = Mathf.Clamp01(cooldownFill); useFill = Mathf.Clamp01(useFill); if ((Object)(object)widget.Root != (Object)null) { Vector3 localScale = widget.Root.transform.localScale; if (((Vector3)(ref localScale)).sqrMagnitude < 0.01f) { widget.Root.transform.localScale = Vector3.one; } } if ((Object)(object)widget.OuterFill != (Object)null) { ConfigureRadial(widget.OuterFill, GetCooldownColor()); widget.OuterFill.fillAmount = cooldownFill; } if ((Object)(object)widget.OuterEmpty != (Object)null) { ((Behaviour)widget.OuterEmpty).enabled = true; } bool flag = active || useFill > 0.001f; if ((Object)(object)widget.InnerRoot != (Object)null) { widget.InnerRoot.SetActive(flag); } if (flag && (Object)(object)widget.InnerFill != (Object)null) { ConfigureRadial(widget.InnerFill, GetUseColor()); widget.InnerFill.fillAmount = useFill; } if ((Object)(object)widget.InnerEmpty != (Object)null) { ((Behaviour)widget.InnerEmpty).enabled = flag; } float a = (ready ? 1f : (active ? 0.95f : Mathf.Lerp(0.35f, 0.9f, cooldownFill))); if ((Object)(object)widget.Icon != (Object)null) { Color color = ((Graphic)widget.Icon).color; color.a = a; ((Graphic)widget.Icon).color = color; } if ((Object)(object)widget.Group != (Object)null) { widget.Group.alpha = (ready ? 1f : 0.95f); } if ((Object)(object)widget.Label != (Object)null) { if (((TMP_Text)widget.Label).text != labelText) { ((TMP_Text)widget.Label).text = labelText; } BdmGameUiFont.Apply(widget.Label); } } private static void EnsureIcons() { //IL_008a: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) if (_sonar != null && (Object)(object)_sonar.Icon != (Object)null && (Object)(object)_sonarSprite == (Object)null) { Texture2D val = TryEmojiTex("1f987") ?? TryEmojiTex("1f3a7") ?? TryEmojiTex("1f50a") ?? TryEmojiTex("1f4e3"); if ((Object)(object)val != (Object)null) { _sonarSprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); _sonar.Icon.sprite = _sonarSprite; } } if (_detection != null && (Object)(object)_detection.Icon != (Object)null && !_detectionIconTried) { _detectionIconTried = true; Texture2D val2 = TryEmojiTex("1f9f3") ?? TryEmojiTex("1f4bc") ?? TryEmojiTex("1f6aa") ?? TryEmojiTex("1f4e6"); if ((Object)(object)val2 != (Object)null) { _detectionSprite = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f), 100f); _detection.Icon.sprite = _detectionSprite; } } if (_hook != null && (Object)(object)_hook.Icon != (Object)null) { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; int num = (((Object)(object)instance != (Object)null) ? instance.GetEffectiveSettings().RescueHookItemId : 167); if (num != _hookIconItemId) { TryAssignHookIcon(num); } } } private static void TryAssignHookIcon(int itemId) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) try { Item val = default(Item); if (!ItemDatabase.TryGetItem((ushort)Mathf.Clamp(itemId, 1, 65535), ref val) || (Object)(object)val == (Object)null || val.UIData == null) { return; } Texture2D icon = val.UIData.GetIcon(); if (!((Object)(object)icon == (Object)null)) { if ((Object)(object)_hookSprite != (Object)null) { Object.Destroy((Object)(object)_hookSprite); _hookSprite = null; } _hookSprite = Sprite.Create(icon, new Rect(0f, 0f, (float)((Texture)icon).width, (float)((Texture)icon).height), new Vector2(0.5f, 0.5f), 100f); if ((Object)(object)_hook?.Icon != (Object)null) { _hook.Icon.sprite = _hookSprite; } _hookIconItemId = itemId; } } catch { } } private static Texture2D TryEmojiTex(string codeKey) { BdmEmojiCatalog.Entry entry = BdmEmojiCatalog.FindByCodeKey(codeKey); return (entry != null) ? BdmEmojiCatalog.GetTexture(entry) : null; } } internal static class BdmAssignmentSyncService { public const int SchemaVersion = 1; public const char PairSeparator = ';'; public const char KeyValueSeparator = '='; internal static bool HasRemoteAssignments { get; private set; } internal static Dictionary<int, BlindDeafMuteChallengePlugin.AfflictionType> RemoteAssignments { get; private set; } = new Dictionary<int, BlindDeafMuteChallengePlugin.AfflictionType>(); internal static void ClearRemoteAssignments() { HasRemoteAssignments = false; RemoteAssignments = new Dictionary<int, BlindDeafMuteChallengePlugin.AfflictionType>(); } internal static void ApplyRemoteSnapshot(string payload) { if (!PhotonNetwork.IsMasterClient && !string.IsNullOrEmpty(payload)) { if (!TryDeserialize(payload, out var map)) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Failed to parse host assignment snapshot."); return; } HasRemoteAssignments = true; RemoteAssignments = map; BlindDeafMuteChallengePlugin.Instance?.LogAlways($"[BlindDeafMute] Applied host assignment snapshot ({map.Count} players)."); BlindDeafMuteChallengePlugin.Instance?.ApplyRemoteAssignments(map); } } internal static string Serialize(IReadOnlyDictionary<int, BlindDeafMuteChallengePlugin.AfflictionType> assignments) { StringBuilder stringBuilder = new StringBuilder(128); Append(stringBuilder, "v", 1.ToString(CultureInfo.InvariantCulture)); if (assignments != null) { foreach (KeyValuePair<int, BlindDeafMuteChallengePlugin.AfflictionType> assignment in assignments) { Append(stringBuilder, assignment.Key.ToString(CultureInfo.InvariantCulture), ((int)assignment.Value).ToString(CultureInfo.InvariantCulture)); } } return stringBuilder.ToString(); } internal static bool TryDeserialize(string payload, out Dictionary<int, BlindDeafMuteChallengePlugin.AfflictionType> map) { map = new Dictionary<int, BlindDeafMuteChallengePlugin.AfflictionType>(); if (string.IsNullOrEmpty(payload)) { return false; } if (payload.IndexOf('=') < 0 && payload.IndexOf(':') >= 0) { return TryDeserializeLegacy(payload, out map); } int result = 0; bool flag = false; string[] array = payload.Split(new char[1] { ';' }); foreach (string text in array) { if (string.IsNullOrEmpty(text)) { continue; } int num = text.IndexOf('='); if (num > 0) { string text2 = text.Substring(0, num); string s = text.Substring(num + 1); int result2; int result3; if (text2 == "v") { flag = int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out result); } else if (int.TryParse(text2, NumberStyles.Integer, CultureInfo.InvariantCulture, out result2) && int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out result3) && Enum.IsDefined(typeof(BlindDeafMuteChallengePlugin.AfflictionType), result3)) { map[result2] = (BlindDeafMuteChallengePlugin.AfflictionType)result3; } } } return flag && result == 1; } private static bool TryDeserializeLegacy(string payload, out Dictionary<int, BlindDeafMuteChallengePlugin.AfflictionType> map) { map = new Dictionary<int, BlindDeafMuteChallengePlugin.AfflictionType>(); string[] array = payload.Split(new char[1] { '|' }); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }); if (array2.Length == 2 && int.TryParse(array2[0], out var result)) { BlindDeafMuteChallengePlugin.AfflictionType result3; if (int.TryParse(array2[1], out var result2) && Enum.IsDefined(typeof(BlindDeafMuteChallengePlugin.AfflictionType), result2)) { result3 = (BlindDeafMuteChallengePlugin.AfflictionType)result2; } else if (!Enum.TryParse<BlindDeafMuteChallengePlugin.AfflictionType>(array2[1], ignoreCase: true, out result3)) { continue; } map[result] = result3; } } return map.Count > 0; } private static void Append(StringBuilder builder, string key, string value) { if (builder.Length > 0) { builder.Append(';'); } builder.Append(key); builder.Append('='); builder.Append(value ?? string.Empty); } } internal static class BdmGameUiFont { private static TMP_FontAsset _cached; private static int _cachedSceneHandle = -1; internal static TMP_FontAsset Get() { //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_0009: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); int num = SceneHandle.op_Implicit(((Scene)(ref activeScene)).handle); if ((Object)(object)_cached != (Object)null && _cachedSceneHandle == num) { return _cached; } _cached = FindGameFont(); _cachedSceneHandle = num; return _cached; } internal static void Apply(TextMeshProUGUI text) { if (!((Object)(object)text == (Object)null)) { TMP_FontAsset val = Get(); if ((Object)(object)val != (Object)null) { ((TMP_Text)text).font = val; } ((TMP_Text)text).fontStyle = (FontStyles)0; } } private static TMP_FontAsset FindGameFont() { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) try { GUIManager instance = GUIManager.instance; if ((Object)(object)instance != (Object)null) { TextMeshProUGUI componentInChildren = ((Component)instance).GetComponentInChildren<TextMeshProUGUI>(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)((TMP_Text)componentInChildren).font != (Object)null) { return ((TMP_Text)componentInChildren).font; } } } catch { } try { TextMeshProUGUI val = Object.FindFirstObjectByType<TextMeshProUGUI>((FindObjectsInactive)1); if ((Object)(object)val != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)null) { return ((TMP_Text)val).font; } } catch { } try { TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>(); foreach (TextMeshProUGUI val2 in array) { if ((Object)(object)val2 == (Object)null || (Object)(object)((TMP_Text)val2).font == (Object)null) { continue; } Scene scene = ((Component)val2).gameObject.scene; if (((Scene)(ref scene)).IsValid()) { scene = ((Component)val2).gameObject.scene; if (((Scene)(ref scene)).isLoaded) { return ((TMP_Text)val2).font; } } } } catch { } return null; } } internal static class BdmBlindMobility { [HarmonyPatch(typeof(CharacterMovement), "GetMovementForce")] private static class GetMovementForce_Patch { private static void Postfix(CharacterMovement __instance, ref float __result) { if (!((Object)(object)__instance == (Object)null) && WantBlindMobility(__instance.character)) { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; float num = (((Object)(object)instance != (Object)null) ? Mathf.Clamp(instance.GetEffectiveSettings().BlindRunSpeedMultiplier, 1f, 3f) : 1.5f); __result *= num; } } } private static Character _climbAppliedTo; private static float _savedClimbMod = 1f; private static float _savedRopeMod = 1f; private static float _savedVineMod = 1f; private static bool _haveClimbSaved; internal static void Tick() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; Character localCharacter = Character.localCharacter; if (!((Object)(object)instance != (Object)null) || !instance.IsBlindEffectWanted() || !BdmModAuthorizationService.CanUseSyncedChallenge() || !instance.GetEffectiveSettings().EnableBlindMobility || !((Object)(object)localCharacter != (Object)null) || localCharacter.refs == null) { RestoreClimb(); } else { ApplyClimb(localCharacter, instance.GetEffectiveSettings()); } } internal static void Shutdown() { RestoreClimb(); } private static bool WantBlindMobility(Character character) { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)character == (Object)null) { return false; } if ((Object)(object)character != (Object)(object)Character.localCharacter) { return false; } if (!instance.IsBlindEffectWanted() || !BdmModAuthorizationService.CanUseSyncedChallenge()) { return false; } return instance.GetEffectiveSettings().EnableBlindMobility; } private static void ApplyClimb(Character local, BdmSyncedSettings s) { if ((Object)(object)_climbAppliedTo != (Object)(object)local || !_haveClimbSaved) { RestoreClimb(); _savedClimbMod = (((Object)(object)local.refs.climbing != (Object)null) ? local.refs.climbing.climbSpeedMod : 1f); _savedRopeMod = (((Object)(object)local.refs.ropeHandling != (Object)null) ? local.refs.ropeHandling.climbSpeedMod : 1f); _savedVineMod = (((Object)(object)local.refs.vineClimbing != (Object)null) ? local.refs.vineClimbing.climbSpeedMod : 1f); _haveClimbSaved = true; _climbAppliedTo = local; } float num = Mathf.Clamp(s.BlindClimbSpeedMultiplier, 1f, 3f); if ((Object)(object)local.refs.climbing != (Object)null) { local.refs.climbing.climbSpeedMod = _savedClimbMod * num; } if ((Object)(object)local.refs.ropeHandling != (Object)null) { local.refs.ropeHandling.climbSpeedMod = _savedRopeMod * num; } if ((Object)(object)local.refs.vineClimbing != (Object)null) { local.refs.vineClimbing.climbSpeedMod = _savedVineMod * num; } } private static void RestoreClimb() { if (!_haveClimbSaved || (Object)(object)_climbAppliedTo == (Object)null) { _haveClimbSaved = false; _climbAppliedTo = null; return; } try { if ((Object)(object)_climbAppliedTo.refs?.climbing != (Object)null) { _climbAppliedTo.refs.climbing.climbSpeedMod = _savedClimbMod; } if ((Object)(object)_climbAppliedTo.refs?.ropeHandling != (Object)null) { _climbAppliedTo.refs.ropeHandling.climbSpeedMod = _savedRopeMod; } if ((Object)(object)_climbAppliedTo.refs?.vineClimbing != (Object)null) { _climbAppliedTo.refs.vineClimbing.climbSpeedMod = _savedVineMod; } } catch { } _haveClimbSaved = false; _climbAppliedTo = null; } } internal static class BdmBlindSonar { private static Coroutine _routine; private static float _cooldownStartedAt = -1f; private static float _useStartedAt = -1f; private static float _useDurationSeconds = 1f; private static bool _controllingBlackout; internal static bool IsActive => _routine != null; internal static bool IsControllingBlackout => _controllingBlackout; internal static bool IsOnCooldown => CooldownRemainingSeconds > 0f; internal static float CooldownRemainingSeconds { get { if (_cooldownStartedAt < 0f) { return 0f; } float liveCooldownSeconds = GetLiveCooldownSeconds(); return Mathf.Max(0f, _cooldownStartedAt + liveCooldownSeconds - Time.unscaledTime); } } internal static bool IsReady => !IsActive && !IsOnCooldown; internal static float CooldownDurationSeconds => GetLiveCooldownSeconds(); internal static float ActiveRemainingSeconds => (!IsActive) ? 0f : Mathf.Max(0f, _useStartedAt + _useDurationSeconds - Time.unscaledTime); internal static float HudCooldownFill { get { if (!IsOnCooldown && !IsActive) { return 1f; } float cooldownDurationSeconds = CooldownDurationSeconds; if (cooldownDurationSeconds <= 0.01f || _cooldownStartedAt < 0f) { return 1f; } return Mathf.Clamp01(1f - CooldownRemainingSeconds / cooldownDurationSeconds); } } internal static float HudUseFill { get { if (!IsActive || _useDurationSeconds <= 0.01f) { return 0f; } return Mathf.Clamp01(ActiveRemainingSeconds / _useDurationSeconds); } } internal static void TryActivate() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null) { return; } if (!instance.IsBlindEffectWanted() || !BdmModAuthorizationService.CanUseSyncedChallenge()) { instance.LogAlways("[BlindDeafMute] Sonar is for Blind players only."); return; } BdmSyncedSettings effectiveSettings = instance.GetEffectiveSettings(); if (!effectiveSettings.EnableSonar) { instance.LogAlways("[BlindDeafMute] Sonar power is disabled by host."); return; } if (IsActive) { instance.LogAlways("[BlindDeafMute] Sonar already active."); return; } if (IsOnCooldown) { instance.LogAlways($"[BlindDeafMute] Sonar on cooldown ({CooldownRemainingSeconds:0}s left)."); return; } BdmSyncedSettings bdmSyncedSettings = effectiveSettings; int num = Mathf.Clamp(bdmSyncedSettings.SonarPingCount, 1, 10); float num2 = Mathf.Max(0.1f, bdmSyncedSettings.SonarVisionSeconds); float num3 = Mathf.Max(0f, bdmSyncedSettings.SonarFadeInSeconds); float num4 = Mathf.Max(0.1f, bdmSyncedSettings.SonarFadeOutSeconds); float num5 = Mathf.Max(0f, bdmSyncedSettings.SonarPingDelay); float num6 = Mathf.Max(1f, bdmSyncedSettings.SonarCooldownSeconds); _useDurationSeconds = Mathf.Max(0.5f, (float)num * (num3 + num2 + num4 + num5)); _useStartedAt = Time.unscaledTime; _cooldownStartedAt = Time.unscaledTime; _routine = ((MonoBehaviour)instance).StartCoroutine(RunSonar(num, num2, num3, num4, num5)); instance.LogAlways($"[BlindDeafMute] Sonar activated — {num} ping(s), ~{_useDurationSeconds:0.#}s use, cooldown {num6:0}s."); } internal static void Cancel() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if (_routine != null && (Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StopCoroutine(_routine); _routine = null; } _controllingBlackout = false; StopCurseFx(); instance?.RestoreBlackoutAfterSonar(); } private static float GetLiveCooldownSeconds() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null) { return 300f; } return Mathf.Max(1f, instance.GetEffectiveSettings().SonarCooldownSeconds); } private static IEnumerator RunSonar(int pings, float visionSeconds, float fadeInSeconds, float fadeOutSeconds, float pingDelaySeconds) { BlindDeafMuteChallengePlugin plugin = BlindDeafMuteChallengePlugin.Instance; _controllingBlackout = true; plugin?.EnsureBlackoutForSonar(); StartCurseFx(); for (int i = 0; i < pings; i++) { if ((Object)(object)plugin == (Object)null) { break; } if (!plugin.IsBlindEffectWanted()) { break; } yield return FadeBlackout(1f, 0f, fadeInSeconds); yield return (object)new WaitForSecondsRealtime(visionSeconds); yield return FadeBlackout(0f, 1f, fadeOutSeconds); if (pingDelaySeconds > 0f) { yield return (object)new WaitForSecondsRealtime(pingDelaySeconds); } } StopCurseFx(); _controllingBlackout = false; _routine = null; plugin?.RestoreBlackoutAfterSonar(); plugin?.LogAlways("[BlindDeafMute] Sonar finished."); } private static IEnumerator FadeBlackout(float from, float to, float duration) { BlindDeafMuteChallengePlugin plugin = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)plugin == (Object)null) { yield break; } if (duration <= 0.001f) { plugin.SetBlackoutAlpha(to); yield break; } float start = Time.unscaledTime; while (true) { float t = Mathf.Clamp01((Time.unscaledTime - start) / duration); plugin.SetBlackoutAlpha(Mathf.Lerp(from, to, t)); if (t >= 1f) { break; } yield return null; } plugin.SetBlackoutAlpha(to); } private static void StartCurseFx() { try { ScreenVFX val = (((Object)(object)GUIManager.instance != (Object)null) ? GUIManager.instance.curseSVFX : null); if ((Object)(object)val == (Object)null || (Object)(object)val.renderer == (Object)null) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Sonar: curseSVFX not found."); return; } ((Component)val).gameObject.SetActive(true); float num = 1f; if ((Object)(object)GUIManager.instance != (Object)null && GUIManager.instance.photosensitivity) { num *= 0.5f; } val.renderer.material.SetFloat(ScreenVFX.INTENSITY, num); } catch (Exception ex) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Sonar curse FX start failed: " + ex.Message); } } private static void StopCurseFx() { try { ScreenVFX val = (((Object)(object)GUIManager.instance != (Object)null) ? GUIManager.instance.curseSVFX : null); if (!((Object)(object)val == (Object)null)) { val.EndFX(); } } catch (Exception ex) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Sonar EndFX failed: " + ex.Message); } } } internal static class BdmDeafBonusLoot { private const string MagicConfetti = "BDM_DEAF_CONFETTI_V1"; private const float SpawnDelaySeconds = 0.15f; private const int MaxRerollsPerItem = 24; private static bool _hookedEvents; private static bool _hookedPhoton; private static ParticleSystem _confettiTemplate; private static GameObject _confettiTemplateRoot; private static SFX_PlayOneShot _successTemplate; internal static void Initialize() { if (!_hookedEvents) { GlobalEvents.OnLuggageOpened = (Action<Luggage, Character>)Delegate.Combine(GlobalEvents.OnLuggageOpened, new Action<Luggage, Character>(OnLuggageOpened)); _hookedEvents = true; BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Deaf bonus-loot hook ready."); } } internal static void Shutdown() { if (_hookedEvents) { GlobalEvents.OnLuggageOpened = (Action<Luggage, Character>)Delegate.Remove(GlobalEvents.OnLuggageOpened, new Action<Luggage, Character>(OnLuggageOpened)); _hookedEvents = false; } if (_hookedPhoton && PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived -= OnPhotonEvent; _hookedPhoton = false; } if ((Object)(object)_confettiTemplateRoot != (Object)null) { Object.Destroy((Object)(object)_confettiTemplateRoot); _confettiTemplateRoot = null; } _confettiTemplate = null; _successTemplate = null; } internal static void TryWarmConfettiCache() { CacheConfettiTemplate(forceLog: false); } internal static void EnsurePhotonHooked() { if (!_hookedPhoton && PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived += OnPhotonEvent; _hookedPhoton = true; } } private static void OnLuggageOpened(Luggage luggage, Character interactor) { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)luggage == (Object)null || (Object)(object)interactor == (Object)null || !BdmModAuthorizationService.CanUseSyncedChallenge() || !instance.GetEffectiveSettings().EnableDeafBonusLoot || !PhotonNetwork.IsMasterClient || luggage is RespawnChest) { return; } int actorNumber = BlindDeafMuteChallengePlugin.GetActorNumber(interactor); if (instance.GetAssignedRole(actorNumber) != BlindDeafMuteChallengePlugin.AfflictionType.Deaf) { return; } BdmSyncedSettings effectiveSettings = instance.GetEffectiveSettings(); float num = NormalizeBonusLootChance(effectiveSettings.DeafBonusLootChance); if (!(num <= 0f) && !(Random.value > num)) { int count = Mathf.Clamp(effectiveSettings.DeafBonusLootCount, 1, 8); ushort[] array = ParseItemIds(effectiveSettings.DeafBonusLootItemIds); if (array.Length == 0) { instance.LogAlways("[BlindDeafMute] Deaf bonus loot skipped — empty/invalid ItemID list."); } else { ((MonoBehaviour)instance).StartCoroutine(SpawnBonusRoutine(luggage, array, count)); } } } private static IEnumerator SpawnBonusRoutine(Luggage luggage, ushort[] pool, int count) { yield return (object)new WaitForSeconds(0.15f); if ((Object)(object)luggage == (Object)null || !PhotonNetwork.IsMasterClient) { yield break; } BlindDeafMuteChallengePlugin plugin = BlindDeafMuteChallengePlugin.Instance; Vector3 basePos = luggage.Center(); Quaternion baseRot = ((Component)luggage).transform.rotation; int spawned = 0; for (int i = 0; i < count; i++) { if (!TryPickValidPrefab(pool, out var prefab, out var pickedId)) { plugin?.LogAlways("[BlindDeafMute] Deaf bonus loot: no valid ItemID left in host list."); break; } Vector3 pos = basePos + baseRot * new Vector3(Random.Range(-0.15f, 0.15f), 0.1f + 0.05f * (float)i, Random.Range(-0.15f, 0.15f)); GameObject go; try { go = PhotonNetwork.InstantiateItemRoom(((Object)((Component)prefab).gameObject).name, pos, baseRot); } catch (Exception ex) { plugin?.LogAlways($"[BlindDeafMute] Deaf bonus spawn failed id={pickedId}: {ex.Message}"); continue; } if ((Object)(object)go == (Object)null) { continue; } Item item = go.GetComponent<Item>(); if (!((Object)(object)item == (Object)null)) { try { ((Spawner)luggage).OffsetSpawn(item); ((Spawner)luggage).InitializePhysics(item); } catch (Exception ex2) { Exception ex3 = ex2; plugin?.LogDebug("[BlindDeafMute] Deaf bonus Offset/Physics: " + ex3.Message); } spawned++; plugin?.LogAlways($"[BlindDeafMute] Deaf bonus loot spawned id={pickedId} ({((Object)((Component)prefab).gameObject).name})."); prefab = null; } } if (spawned > 0) { Vector3 fxPos = luggage.Center() + Vector3.up * 0.4f; plugin?.LogAlways($"[BlindDeafMute] Deaf bonus confetti: requesting FX at {fxPos} (spawned={spawned})."); PlayConfettiAt(fxPos); BroadcastConfetti(fxPos); } } private static bool TryPickValidPrefab(ushort[] pool, out Item prefab, out ushort pickedId) { prefab = null; pickedId = 0; if (pool == null || pool.Length == 0) { return false; } int num = Mathf.Min(24, Mathf.Max(8, pool.Length * 3)); Item val = default(Item); for (int i = 0; i < num; i++) { ushort num2 = pool[Random.Range(0, pool.Length)]; if (ItemDatabase.TryGetItem(num2, ref val) && !((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null)) { prefab = val; pickedId = num2; return true; } } return false; } internal static float NormalizeBonusLootChance(float raw) { if (float.IsNaN(raw) || float.IsInfinity(raw)) { return 0f; } if (raw > 1f) { raw *= 0.01f; } if (raw < 0f) { return 0f; } if (raw > 1f) { return 1f; } return raw; } internal static ushort[] ParseItemIds(string raw) { if (string.IsNullOrWhiteSpace(raw)) { return Array.Empty<ushort>(); } string[] array = raw.Split(new char[4] { ',', ';', ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); List<ushort> list = new List<ushort>(array.Length); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0 && ushort.TryParse(text, out var result)) { list.Add(result); } } return list.ToArray(); } internal static string SanitizeItemIdsForSync(string raw) { ushort[] array = ParseItemIds(raw); if (array.Length == 0) { return string.Empty; } return string.Join(",", Array.ConvertAll(array, (ushort id) => id.ToString())); } private static void BroadcastConfetti(Vector3 pos) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_005b: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) EnsurePhotonHooked(); if (PhotonNetwork.InRoom) { object[] array = new object[4] { "BDM_DEAF_CONFETTI_V1", pos.x, pos.y, pos.z }; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; PhotonNetwork.RaiseEvent(BdmEmojiNet.EventCode, (object)array, val, SendOptions.SendReliable); } } private static void OnPhotonEvent(EventData photonEvent) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (photonEvent == null || photonEvent.Code != BdmEmojiNet.EventCode || !(photonEvent.CustomData is object[] array) || array.Length < 4 || !(array[0] is string a) || !string.Equals(a, "BDM_DEAF_CONFETTI_V1", StringComparison.Ordinal)) { return; } try { float num = Convert.ToSingle(array[1]); float num2 = Convert.ToSingle(array[2]); float num3 = Convert.ToSingle(array[3]); PlayConfettiAt(new Vector3(num, num2, num3)); } catch { } } internal static void PlayConfettiAt(Vector3 worldPos) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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) BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; CacheConfettiTemplate(forceLog: true); bool flag = (Object)(object)_confettiTemplate != (Object)null && (Object)(object)_confettiTemplateRoot != (Object)null; instance?.LogDebug($"[BlindDeafMute] Confetti PlayConfettiAt pos={worldPos} " + string.Format("templateOk={0} root={1} ", flag, ((Object)(object)_confettiTemplateRoot != (Object)null) ? ((Object)_confettiTemplateRoot).name : "null") + "ps=" + (((Object)(object)_confettiTemplate != (Object)null) ? ((Object)_confettiTemplate).name : "null")); if (!flag) { instance?.LogAlways("[BlindDeafMute] Deaf bonus confetti SKIPPED — no cached ParticleSystem. Visit Airport (or any scene with a BasketballHoop) once so it can be cached, then try again."); } else if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(PlayConfettiRoutine(worldPos)); } else { PlayConfettiImmediate(worldPos); } } private static IEnumerator PlayConfettiRoutine(Vector3 worldPos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) BlindDeafMuteChallengePlugin plugin = BlindDeafMuteChallengePlugin.Instance; GameObject clone; try { bool templateWasActive = _confettiTemplateRoot.activeSelf; _confettiTemplateRoot.SetActive(false); clone = Object.Instantiate<GameObject>(_confettiTemplateRoot); _confettiTemplateRoot.SetActive(templateWasActive); ((Object)clone).name = "BDM_DeafBonusConfetti"; clone.transform.SetParent((Transform)null, true); clone.transform.position = worldPos; clone.transform.rotation = Quaternion.identity; clone.transform.localScale = Vector3.one; clone.SetActive(false); plugin?.LogDebug($"[BlindDeafMute] Confetti clone created id={((Object)clone).GetInstanceID()} " + $"active={clone.activeSelf} pos={clone.transform.position} " + $"psCount={clone.GetComponentsInChildren<ParticleSystem>(true).Length}"); } catch (Exception ex) { Exception ex2 = ex; plugin?.LogAlways("[BlindDeafMute] Deaf bonus confetti clone failed: " + ex2.Message); yield break; } yield return null; try { if ((Object)(object)clone == (Object)null) { plugin?.LogAlways("[BlindDeafMute] Confetti clone was destroyed before play."); yield break; } clone.SetActive(true); ParticleSystem[] systems = clone.GetComponentsInChildren<ParticleSystem>(true); plugin?.LogDebug($"[BlindDeafMute] Confetti activated clone at {clone.transform.position}, systems={systems.Length}"); for (int i = 0; i < systems.Length; i++) { ParticleSystem ps = systems[i]; MainModule main = ps.main; plugin?.LogDebug($"[BlindDeafMute] Confetti PS[{i}] name={((Object)((Component)ps).gameObject).name} " + $"playOnAwake={((MainModule)(ref main)).playOnAwake} isPlaying={ps.isPlaying} " + $"renderer={(Object)(object)((Component)ps).GetComponent<ParticleSystemRenderer>() != (Object)null}"); ps.Clear(true); ps.Play(true); plugin?.LogDebug($"[BlindDeafMute] Confetti PS[{i}] after Play isPlaying={ps.isPlaying}"); main = default(MainModule); } if ((Object)(object)_successTemplate != (Object)null) { _successTemplate.Play(); plugin?.LogDebug("[BlindDeafMute] Confetti success SFX Play() called."); } else { plugin?.LogDebug("[BlindDeafMute] Confetti success SFX template is null."); } plugin?.LogAlways($"[BlindDeafMute] Deaf bonus confetti PLAYED at {worldPos} (systems={systems.Length})."); } catch (Exception ex) { Exception ex3 = ex; plugin?.LogAlways("[BlindDeafMute] Deaf bonus confetti play failed: " + ex3.Message); } if ((Object)(object)clone != (Object)null) { Object.Destroy((Object)(object)clone, 6f); } } private static void PlayConfettiImmediate(Vector3 worldPos) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) try { bool activeSelf = _confettiTemplateRoot.activeSelf; _confettiTemplateRoot.SetActive(false); GameObject val = Object.Instantiate<GameObject>(_confettiTemplateRoot, worldPos, Quaternion.identity); _confettiTemplateRoot.SetActive(activeSelf); val.SetActive(true); ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].Clear(true); componentsInChildren[i].Play(true); } Object.Destroy((Object)(object)val, 6f); if ((Object)(object)_successTemplate != (Object)null) { _successTemplate.Play(); } } catch (Exception ex) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Deaf bonus confetti failed: " + ex.Message); } } private static void CacheConfettiTemplate(bool forceLog) { if ((Object)(object)_confettiTemplate != (Object)null && (Object)(object)_confettiTemplateRoot != (Object)null) { if (forceLog) { BlindDeafMuteChallengePlugin.Instance?.LogDebug("[BlindDeafMute] Confetti cache HIT root=" + ((Object)_confettiTemplateRoot).name); } return; } _confettiTemplate = null; _confettiTemplateRoot = null; BasketballHoop[] array = Object.FindObjectsByType<BasketballHoop>((FindObjectsInactive)1, (FindObjectsSortMode)0); int num = ((array != null) ? array.Length : 0); BlindDeafMuteChallengePlugin.Instance?.LogDebug($"[BlindDeafMute] Confetti cache MISS — scanning BasketballHoop count={num}"); if (array == null || array.Length == 0) { if (forceLog) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Confetti: 0 BasketballHoop in this scene — cannot cache yet."); } return; } for (int i = 0; i < array.Length; i++) { BasketballHoop val = array[i]; if ((Object)(object)val == (Object)null) { continue; } ParticleSystem val2 = val.confetti; string text = "hoop.confetti field"; if ((Object)(object)val2 == (Object)null) { Transform val3 = FindChildNamed(((Component)val).transform, "Confetti"); if ((Object)(object)val3 != (Object)null) { val2 = ((Component)val3).GetComponent<ParticleSystem>() ?? ((Component)val3).GetComponentInChildren<ParticleSystem>(true); text = "child '" + ((Object)val3).name + "'"; } } if ((Object)(object)val2 == (Object)null) { val2 = ((Component)val).GetComponentInChildren<ParticleSystem>(true); text = "GetComponentInChildren<ParticleSystem>"; } BlindDeafMuteChallengePlugin.Instance?.LogDebug($"[BlindDeafMute] Confetti hoop[{i}]='{((Object)val).name}' source={text} " + "ps=" + (((Object)(object)val2 != (Object)null) ? ((Object)((Component)val2).gameObject).name : "null") + " " + $"fieldNull={(Object)(object)val.confetti == (Object)null}"); if (!((Object)(object)val2 == (Object)null)) { try { bool activeSelf = ((Component)val2).gameObject.activeSelf; ((Component)val2).gameObject.SetActive(false); GameObject val4 = Object.Instantiate<GameObject>(((Component)val2).gameObject); ((Component)val2).gameObject.SetActive(activeSelf); ((Object)val4).name = "BDM_ConfettiTemplate"; val4.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val4); _confettiTemplateRoot = val4; _confettiTemplate = val4.GetComponent<ParticleSystem>() ?? val4.GetComponentInChildren<ParticleSystem>(true); _successTemplate = val.success; BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Confetti template CACHED from '" + ((Object)val).name + "' via " + text + " → persistPs=" + (((Object)(object)_confettiTemplate != (Object)null) ? ((Object)_confettiTemplate).name : "null") + "."); return; } catch (Exception ex) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Confetti template cache failed: " + ex.Message); } } } if (forceLog) { BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Confetti: found BasketballHoop(s) but no ParticleSystem to cache."); } } private static Transform FindChildNamed(Transform root, string name) { if ((Object)(object)root == (Object)null) { return null; } if (string.Equals(((Object)root).name, name, StringComparison.OrdinalIgnoreCase)) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindChildNamed(root.GetChild(i), name); if ((Object)(object)val != (Object)null) { return val; } } return null; } } internal static class BdmDeafDetection { private struct OutlineEdge { public LineRenderer Line; public Vector3 Anchor; } private const float WidthReferenceDistance = 8f; private const float WidthScaleMin = 0.45f; private const float WidthScaleMax = 18f; private static Coroutine _routine; private static float _cooldownStartedAt = -1f; private static float _useStartedAt = -1f; private static float _useDurationSeconds = 1f; private static GameObject _outlineRoot; private static Material _lineMaterial; private static readonly List<OutlineEdge> _edges = new List<OutlineEdge>(256); internal static bool IsActive => _routine != null; internal static bool IsOnCooldown => CooldownRemainingSeconds > 0f; internal static float CooldownRemainingSeconds { get { if (_cooldownStartedAt < 0f) { return 0f; } float liveCooldownSeconds = GetLiveCooldownSeconds(); return Mathf.Max(0f, _cooldownStartedAt + liveCooldownSeconds - Time.unscaledTime); } } internal static bool IsReady => !IsActive && !IsOnCooldown; internal static float CooldownDurationSeconds => GetLiveCooldownSeconds(); internal static float ActiveRemainingSeconds => (!IsActive) ? 0f : Mathf.Max(0f, _useStartedAt + _useDurationSeconds - Time.unscaledTime); internal static float HudCooldownFill { get { if (!IsOnCooldown && !IsActive) { return 1f; } float cooldownDurationSeconds = CooldownDurationSeconds; if (cooldownDurationSeconds <= 0.01f || _cooldownStartedAt < 0f) { return 1f; } return Mathf.Clamp01(1f - CooldownRemainingSeconds / cooldownDurationSeconds); } } internal static float HudUseFill { get { if (!IsActive || _useDurationSeconds <= 0.01f) { return 0f; } return Mathf.Clamp01(ActiveRemainingSeconds / _useDurationSeconds); } } internal static void TryActivate() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null) { return; } if (!instance.IsLocalDeafActive) { instance.LogAlways("[BlindDeafMute] Detection is for Deaf players only."); return; } BdmSyncedSettings effectiveSettings = instance.GetEffectiveSettings(); if (!effectiveSettings.EnableDetection) { instance.LogAlways("[BlindDeafMute] Detection power is disabled by host."); return; } if (IsActive) { instance.LogAlways("[BlindDeafMute] Detection already active."); return; } if (IsOnCooldown) { instance.LogAlways($"[BlindDeafMute] Detection on cooldown ({CooldownRemainingSeconds:0}s left)."); return; } float num = Mathf.Clamp(effectiveSettings.DetectionDurationSeconds, 0.5f, 120f); float num2 = Mathf.Clamp(effectiveSettings.DetectionCooldownSeconds, 1f, 3600f); _useDurationSeconds = num; _useStartedAt = Time.unscaledTime; _cooldownStartedAt = Time.unscaledTime; _routine = ((MonoBehaviour)instance).StartCoroutine(RunDetection(num)); instance.LogAlways($"[BlindDeafMute] Detection activated — {num:0.#}s use, cooldown {num2:0}s."); } internal static void Cancel() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if (_routine != null && (Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StopCoroutine(_routine); _routine = null; } ClearLineRenderers(); } internal static void Shutdown() { Cancel(); _cooldownStartedAt = -1f; if ((Object)(object)_outlineRoot != (Object)null) { Object.Destroy((Object)(object)_outlineRoot); _outlineRoot = null; } if ((Object)(object)_lineMaterial != (Object)null) { Object.Destroy((Object)(object)_lineMaterial); _lineMaterial = null; } } private static float GetLiveCooldownSeconds() { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance == (Object)null) { return 120f; } return Mathf.Clamp(instance.GetEffectiveSettings().DetectionCooldownSeconds, 1f, 3600f); } private static IEnumerator RunDetection(float duration) { BuildOutlines(); float end = Time.unscaledTime + duration; while (Time.unscaledTime < end) { if (Time.frameCount % 30 == 0) { BuildOutlines(); } else { UpdateOutlineWidths(); } yield return null; } ClearLineRenderers(); _routine = null; BlindDeafMuteChallengePlugin.Instance?.LogAlways("[BlindDeafMute] Detection finished."); } private static void BuildOutlines() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_00c8: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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) EnsureRoot(); ClearLineRenderers(); Color color = (Color)(((Object)(object)BlindDeafMuteChallengePlugin.Instance != (Object)null) ? BlindDeafMuteChallengePlugin.Instance.DetectionOutlineColor : new Color(1f, 0f, 0.988f, 1f)); Camera camera = GetCamera(); Vector3 val = (((Object)(object)camera != (Object)null) ? ((Component)camera).transform.position : Vector3.zero); try { if (Luggage.ALL_LUGGAGE == null) { return; } for (int i = 0; i < Luggage.ALL_LUGGAGE.Count; i++) { Luggage val2 = Luggage.ALL_LUGGAGE[i]; if (!((Object)(object)val2 == (Object)null) && ((Component)val2).gameObject.activeInHierarchy && !(val2 is RespawnChest)) { Bounds luggageBounds = GetLuggageBounds(val2); float num = (((Object)(object)camera != (Object)null) ? Vector3.Distance(val, ((Bounds)(ref luggageBounds)).center) : 8f); float num2 = Mathf.Clamp((num - 12f) * 0.025f, 0f, 4f); ((Bounds)(ref luggageBounds)).Expand(0.15f + num2); AddBoxOutline(luggageBounds, color, ((Bounds)(ref luggageBounds)).center); } } } catch { } UpdateOutlineWidths(); } private static Bounds GetLuggageBounds(Luggage luggage) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_00f6: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00c0: 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_00ca: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) Renderer[] meshRenderers = luggage.meshRenderers; bool flag = false; Bounds result = default(Bounds); ((Bounds)(ref result))..ctor(((Component)luggage).transform.position, Vector3.one * 0.8f); if (meshRenderers != null) { foreach (Renderer obj in meshRenderers) { MeshRenderer val = (MeshRenderer)(object)((obj is MeshRenderer) ? obj : null); if (!((Object)(object)val == (Object)null) && ((Renderer)val).enabled) { if (!flag) { result = ((Renderer)val).bounds; flag = true; } else { ((Bounds)(ref result)).Encapsulate(((Renderer)val).bounds); } } } } if (!flag) { try { Vector3 val2 = luggage.Center(); result = new Bounds(val2, Vector3.one * 1.2f); } catch { ((Bounds)(ref result))..ctor(((Component)luggage).transform.position, Vector3.one * 1.2f); } } return result; } private static void AddBoxOutline(Bounds bounds, Color color, Vector3 anchor) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0074: 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_0085: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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_00f0: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: 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_017f: Expected O, but got Unknown //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_0217: 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_0252: 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) Vector3 center = ((Bounds)(ref bounds)).center; Vector3 extents = ((Bounds)(ref bounds)).extents; Vector3[] array = (Vector3[])(object)new Vector3[8] { center + new Vector3(0f - extents.x, 0f - extents.y, 0f - extents.z), center + new Vector3(0f - extents.x, 0f - extents.y, extents.z), center + new Vector3(0f - extents.x, extents.y, 0f - extents.z), center + new Vector3(0f - extents.x, extents.y, extents.z), center + new Vector3(extents.x, 0f - extents.y, 0f - extents.z), center + new Vector3(extents.x, 0f - extents.y, extents.z), center + new Vector3(extents.x, extents.y, 0f - extents.z), center + new Vector3(extents.x, extents.y, extents.z) }; int[,] array2 = new int[12, 2] { { 0, 1 }, { 0, 2 }, { 0, 4 }, { 7, 3 }, { 7, 5 }, { 7, 6 }, { 1, 3 }, { 1, 5 }, { 2, 3 }, { 2, 6 }, { 4, 5 }, { 4, 6 } }; float num = ComputeWidth(Vector3.Distance(GetCameraPos(), anchor)); for (int i = 0; i < array2.GetLength(0); i++) { GameObject val = new GameObject("Edge"); val.transform.SetParent(_outlineRoot.transform, false); LineRenderer val2 = val.AddComponent<LineRenderer>(); ((Renderer)val2).sharedMaterial = GetLineMaterial(); val2.positionCount = 2; val2.useWorldSpace = true; val2.widthMultiplier = num; val2.startWidth = num; val2.endWidth = num; val2.startColor = color; val2.endColor = color; ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; ((Renderer)val2).allowOcclusionWhenDynamic = false; val2.SetPosition(0, array[array2[i, 0]]); val2.SetPosition(1, array[array2[i, 1]]); _edges.Add(new OutlineEdge { Line = val2, Anchor = anchor }); } } private static void UpdateOutlineWidths() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_0044: Unknown result type (might be due to invalid IL or missing references) if (_edges.Count == 0) { return; } Vector3 cameraPos = GetCameraPos(); for (int i = 0; i < _edges.Count; i++) { OutlineEdge outlineEdge = _edges[i]; if (!((Object)(object)outlineEdge.Line == (Object)null)) { float distance = Vector3.Distance(cameraPos, outlineEdge.Anchor); float num = ComputeWidth(distance); outlineEdge.Line.widthMultiplier = num; outlineEdge.Line.startWidth = num; outlineEdge.Line.endWidth = num; } } } private static float ComputeWidth(float distance) { BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; float num = (((Object)(object)instance != (Object)null) ? instance.DetectionOutlineThickness : 0.06f); float num2 = Mathf.Clamp(Mathf.Max(distance, 0.5f) / 8f, 0.45f, 18f); return Mathf.Max(0.002f, num * num2); } private static Camera GetCamera() { try { if ((Object)(object)MainCamera.instance != (Object)null && (Object)(object)MainCamera.instance.cam != (Object)null) { return MainCamera.instance.cam; } } catch { } return Camera.main; } private static Vector3 GetCameraPos() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) Camera camera = GetCamera(); if ((Object)(object)camera != (Object)null) { return ((Component)camera).transform.position; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null) { try { return localCharacter.Head; } catch { return ((Component)localCharacter).transform.position; } } return Vector3.zero; } private static void EnsureRoot() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (!((Object)(object)_outlineRoot != (Object)null)) { _outlineRoot = new GameObject("BDM_DetectionOutlines"); Object.DontDestroyOnLoad((Object)(object)_outlineRoot); } } private static void ClearLineRenderers() { _edges.Clear(); if (!((Object)(object)_outlineRoot == (Object)null)) { for (int num = _outlineRoot.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)_outlineRoot.transform.GetChild(num)).gameObject); } } } private static Material GetLineMaterial() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_lineMaterial != (Object)null) { return _lineMaterial; } Shader val = Shader.Find("Hidden/Internal-Colored"); if ((Object)(object)val == (Object)null) { val = Shader.Find("Sprites/Default"); } if ((Object)(object)val == (Object)null) { val = Shader.Find("Unlit/Color"); } _lineMaterial = new Material(val); ((Object)_lineMaterial).hideFlags = (HideFlags)61; _lineMaterial.SetInt("_ZTest", 8); _lineMaterial.SetInt("_ZWrite", 0); if (_lineMaterial.HasProperty("_Color")) { _lineMaterial.SetColor("_Color", Color.white); } return _lineMaterial; } } internal static class BdmEmojiBubbles { private sealed class Bubble { internal GameObject Go; internal RectTransform Rect; internal RawImage Image; internal Character Follow; internal int CharacterId; internal float BornAt; internal float DieAt; internal float Size; internal Coroutine Routine; } private sealed class ReactingCue { internal GameObject Go; internal RectTransform Rect; internal Character Follow; internal int CharacterId; internal Coroutine Routine; } private const float HeadWorldOffsetY = 0.35f; private const float ScreenYBoost = 36f; private const float StringGap = 4f; private const float PopInSeconds = 0.12f; private const float FadeOutSeconds = 0.22f; private static readonly Dictionary<int, List<Bubble>> _byCharacter = new Dictionary<int, List<Bubble>>(8); private static readonly Dictionary<int, ReactingCue> _reacting = new Dictionary<int, ReactingCue>(4); private static readonly HashSet<int> _reactingWanted = new HashSet<int>(); private static readonly Dictionary<int, Character> _reactingFollow = new Dictionary<int, Character>(4); private static readonly Dictionary<int, string> _reactingSenderCue = new Dictionary<int, string>(4); internal static bool Show(Character character, string codeKey, float durationSeconds) { //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Expected O, but got Unknown //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null || string.IsNullOrEmpty(codeKey)) { return false; } BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; if ((Object)(object)instance != (Object)null && instance.IsBlindEffectWanted()) { instance.LogDebug("[BlindDeafMute] Emoji bubble skipped — local player is Blind."); return false; } if ((Object)(object)instance != (Object)null && instance.BlockAlphabetEmojis && BdmEmojiCatalog.IsAlphabetCodeKey(codeKey)) { instance.LogDebug("[BlindDeafMute] Alphabet emoji blocked: " + codeKey); return false; } if ((Object)(object)instance != (Object)null && !instance.ShowSkinToneVariants && BdmEmojiCatalog.IsSkinToneVariant(codeKey)) { instance.LogDebug("[BlindDeafMute] Skin-tone emoji blocked: " + codeKey); return false; } GUIManager instance2 = GUIManager.instance; if ((Object)(object)instance2 == (Object)null || (Object)(object)instance2.hudCanvas == (Object)null) { instance?.LogAlways("[BlindDeafMute] Emoji bubble skipped — no HUD canvas."); return false; } BdmEmojiCatalog.EnsureLoaded(); BdmEmojiCatalog.Entry entry = BdmEmojiCatalog.FindByCodeKey(codeKey); Texture2D texture = BdmEmojiCatalog.GetTexture(entry); if ((Object)(object)texture == (Object)null) { instance?.LogAlways("[BlindDeafMute] Emoji bubble missing texture for '" + codeKey + "' (is emojis/ installed?)."); return false; } int instanceID = ((Object)character).GetInstanceID(); float localBubbleSize = GetLocalBubbleSize(instance); float num = Mathf.Max(0.5f, durationSeconds); bool flag = (Object)(object)instance == (Object)null || instance.AllowEmojiString; int num2 = (((Object)(object)instance != (Object)null) ? Mathf.Clamp(instance.MaxEmojiStringLength, 1, 16) : 6); if (!_byCharacter.TryGetValue(instanceID, out var value)) { value = new List<Bubble>(num2); _byCharacter[instanceID] = value; } if (!flag) { ClearGroup(value, restoreReacting: false); } else { while (value.Count >= num2) { DestroyBubble(value[0], value); } } GameObject val = new GameObject("BDM_EmojiBubble", new Type[1] { typeof(RectTransform) }); RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent(((Component)instance2.hudCanvas).transform, false); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.zero; component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(localBubbleSize * 0.7f, localBubbleSize * 0.7f); RawImage val2 = val.AddComponent<RawImage>(); val2.texture = (Texture)(object)texture; ((Graphic)val2).raycastTarget = false; ((Graphic)val2).color = new Color(1f, 1f, 1f, 0f); val.transform.SetAsLastSibling(); float unscaledTime = Time.unscaledTime; Bubble bubble = new Bubble { Go = val, Rect = component, Image = val2, Follow = character, CharacterId = instanceID, BornAt = unscaledTime, DieAt = unscaledTime + num, Size = localBubbleSize }; value.Add(bubble); HideReactingCue(instanceID); for (int i = 0; i < value.Count; i++) { value[i].DieAt = bubble.DieAt; } PositionGroup(value, flag); MonoBehaviour val3 = (MonoBehaviour)(object)instance; if ((Object)(object)val3 != (Object)null) { bubble.Routine = val3.StartCoroutine(RunBubble(bubble)); } else { Object.Destroy((Object)(object)val, num); } instance?.LogDebug("[BlindDeafMute] Emoji bubble shown '" + codeKey + "' on " + character.characterName + "."); return true; } internal static void ClearForCharacter(Character character) { if (!((Object)(object)character == (Object)null)) { int instanceID = ((Object)character).GetInstanceID(); if (!_byCharacter.TryGetValue(instanceID, out var value)) { TryRestoreReacting(instanceID); return; } ClearGroup(value, restoreReacting: true); _byCharacter.Remove(instanceID); } } internal static void SetReacting(Character character, bool reacting, string senderCueKey = null) { if ((Object)(object)character == (Object)null) { return; } BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; int instanceID = ((Object)character).GetInstanceID(); if ((Object)(object)instance != (Object)null && (instance.IsBlindEffectWanted() || !instance.ShowReactingCue)) { ClearReactingWanted(instanceID); HideReactingCue(instanceID); return; } if (!reacting) { ClearReactingWanted(instanceID); HideReactingCue(instanceID); return; } string text = BlindDeafMuteChallengePlugin.NormalizeIncomingCueAsset((!string.IsNullOrEmpty(senderCueKey)) ? senderCueKey : (((Object)(object)instance != (Object)null) ? instance.IncomingEmojiCueKey : "1f4ac")); _reactingWanted.Add(instanceID); _reactingFollow[instanceID] = character; _reactingSenderCue[instanceID] = text; if (HasActiveBubbles(instanceID)) { HideReactingCue(instanceID); } else { ShowReactingCue(character, text); } } private static void ClearReactingWanted(int characterId) { _reactingWanted.Remove(characterId); _reactingFollow.Remove(characterId); _reactingSenderCue.Remove(characterId); } private static bool HasActiveBubbles(int characterId) { List<Bubble> value; return _byCharacter.TryGetValue(characterId, out value) && value.Count > 0; } private static void ShowReactingCue(Character character, string senderCueKey) { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00fa: 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_011e: 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_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_019c: 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) //IL_01a8: 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_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0217: 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) if ((Object)(object)character == (Object)null) { return; } int instanceID = ((Object)character).GetInstanceID(); if (_reacting.ContainsKey(instanceID)) { return; } BlindDeafMuteChallengePlugin instance = BlindDeafMuteChallengePlugin.Instance; GUIManager instance2 = GUIManager.instance; if (!((Object)(object)instance2 == (Object)null) && !((Object)(object)instance2.hudCanvas == (Object)null)) { BdmEmojiCatalog.EnsureLoaded(); string text = (((Object)(object)instance != (Object)null) ? instance.ResolveIncomingCueDisplayKey(senderCueKey) : BlindDeafMuteChallengePlugin.NormalizeIncomingCueAsset(senderCueKey)); Texture2D texture = BdmEmojiCatalog.GetTexture(BdmEmojiCatalog.FindByCodeKey(text)); if ((Object)(object)texture == (Object)null && text != "1f4ac") { texture = BdmEmojiCatalog.GetTexture(BdmEmojiCatalog.FindByCodeKey("1f4ac")); } GameObject val = new GameObject("BDM_EmojiReacting", new Type[1] { typeof(RectTransform) }); RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent(((Component)instance2.hudCanvas).transform, false); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.zero; component.pivot = new Vector2(0.5f, 0.5f); float num = GetLocalBubbleSize(instance) * 0.5f; component.sizeDelta = new Vector2(num, num); RawImage val2 = val.AddComponent<RawImage>(); ((Graphic)val2).raycastTarget = false; if ((Object)(object)texture != (Object)null) { val2.texture = (Texture)(object)texture; ((Graphic)val2).color = Color.white; } else { Texture2D val3 = new Texture2D(2, 2, (TextureFormat)4, false); val3.SetPixels((Color[])(object)new Color[4] { Color.white, Color.white, Color.white, Color.white }); val3.Apply(false, true); val2.texture = (Texture)(object)val3; ((Graphic)val2).color = new Color(0.95f, 0.95f, 0.95f, 0.9f); component.sizeDelta = new Vector2(num * 1.2f, num * 0.7f); } ReactingCue reactingCue = new ReactingCue { Go = val, Rect = component, Follow = character, CharacterId = instanceID }; _reacting[instanceID] = reactingCue; if ((Object)(object)instance != (Object)null) { reactingCue.Routine = ((MonoBehaviour)instance).StartCoroutine(RunReacting(reactingCue)); } } } private static void HideReactingCue(int characterId) { if (_reacting.TryGetValue(characterId, out var value)) { _reacting.Remove(characterId); if (value.Routine != null && (Object)(object)BlindDeafMuteChallengePlugin.Instance != (Object)null) { ((MonoBehaviour)BlindDeafMuteChallengePlugin.Instance).StopCoroutine(value.Routine); } if ((Object)(object)value.Go != (Object)null) { Object.Destroy((Object)(object)value.Go); } } } private static void TryRestoreReacting(int characterId) { if (_reactingWanted.Contains(characterId) && !HasActiveBubbles(characterId) && _reactingFollow.TryGetValue(characterId, out var value) && !((Object)(object)value == (Object)null)) { string value2; string senderCueKey = (_reactingSenderCue.TryGetValue(characterId, out value2) ? value2 : "1f4ac"); ShowReactingCue(value, senderCueKey); } } private static float GetLocalBubbleSize(BlindDeafMuteChallengePlugin plugin) { float num = (((Object)(object)plugin != (Object)null) ? Mathf.Clamp(plugin.EmojiBubbleSize, 24f, 256f) : 72f); return num * BdmEmojiCatalog.UiScale; } private static IEnumerator RunBubble(Bubble bubble) { while ((Object)(object)bubble.Go != (Object)null && Time.unscaledTime < bubble.DieAt) { float now = Time.unscaledTime; float age = now - bubble.BornAt; float left = bubble.DieAt - now; float popT = Mathf.Clamp01(age / 0.12f); float scale = Mathf.Lerp(0.7f, 1f, popT); float alpha = popT; if (left < 0.22f) { alpha *= Mathf.Clamp01(left / 0.22f); } if ((Object)(object)bubble.Rect != (Object)null) { bubble.Rect.sizeDelta = new Vector2(bubble.Size * scale, bubble.Size * scale); } if ((Object)(object)bubble.Image != (Object)null) { Color c = ((Graphic)bubble.Image).color; c.a = alpha; ((Graphic)bubble.Image).color = c; } if (_byCharacter.TryGetValue(bubble.CharacterId, out var group)) { PositionGroup(stringMode: (Object)(object)BlindDeafMuteChallengePlugin.Instance == (Object)null || BlindDeafMuteChallengePlugin.Instance.AllowEmojiString, group: group); } yield return null; group = null; } if (_byCharacter.TryGetValue(bubble.CharacterId, out var g)) { int characterId = bubble.CharacterId; DestroyBubble(bubble, g); if (g.Count == 0) { _byCharacter.Remove(characterId); TryRestoreReacting(characterId); } else { PositionGroup(stringMode: (Object)(object)BlindDeafMuteChallengePlugin.Instance == (Object)null || BlindDeafMuteChallengePlugin.Instance.AllowEmojiString, group: g); } } else if ((Object)(object)bubble.Go != (Object)null) { Object.Destroy((Object)(object)bubble.Go); TryRestoreReacting(bubble.CharacterId); } } private static IEnumerator RunReacting(ReactingCue cue) { while ((Object)(object)cue.Go != (Object)null) { PositionReacting(cue); yield return null; } } private static void ClearGroup(List<Bubble> group, bool restoreReacting) { int num = ((group != null && group.Count > 0) ? group[0].CharacterId : 0); for (int num2 = group.Count - 1; num2 >= 0; num2--) { DestroyBubble(group[num2], group); } if (restoreReacting && num != 0) { TryRestoreReacting(num); } } private static void DestroyBubble(Bubble bubble, List<Bubble> group) { if (bubble != null) { if (bubble.Routine != null && (Object)(object)BlindDeafMuteChallengePlugin.Instance != (Object)null) { ((MonoBehaviour)BlindDeafMuteChallengePlugin.Instance).StopCoroutine(bubble.Routine); bubble.Routine = null; } if ((Object)(object)bubble.Go != (Object)null) { Object.Destroy((Object)(object)bubble.Go); } group.Remove(bubble); } } private static bool TryGetHeadScreen(Character follow, out Vector3 screen) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00c0: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) screen = default(Vector3); if ((Object)(object)follow == (Object)null) { return false; } if (!IsWithinViewDistance(follow)) { return false; } Camera val = null; try { if ((Object)(object)MainCamera.instance != (Object)null && (Object)(object)MainCamera.instance.cam != (Object)null) { val = MainCamera.instance.cam; } } catch { } if ((Object)(object)val == (Object)null) { val = Camera.main; } if ((Object)(object)val == (Object)null) { return false; } Vector3 val2; try { val2 = follow.Head; } catch { val2 = ((Component)follow).transform.position; } val2.y += 0.35f; screen = val.WorldToScreenPoint(val2); if (screen.z < 0.1f) { return false; } screen.y += 36f; return true; } private static bool IsWithinViewDistance(Character follow) { //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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_012d: 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_003a: 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_