using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ScrapVisbility")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ScrapVisbility")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("8a6853bd-bdc9-4741-95c7-5aa2c8c6a6f9")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace DoorLockpickPlus; [BepInPlugin("YourFurnace.DoorLockpickPlus", "DoorLockpickPlus", "1.3.8")] public class DoorLockpickPlus : BaseUnityPlugin { private const string modGUID = "YourFurnace.DoorLockpickPlus"; private const string modName = "DoorLockpickPlus"; private const string modVersion = "1.3.8"; private readonly Harmony harmony = new Harmony("YourFurnace.DoorLockpickPlus"); internal static DoorLockpickPlus Instance; internal static ManualLogSource Log; internal static ConfigEntry EnableNormalDoorLockpicking; internal static ConfigEntry EnableBigDoorHacking; internal static ConfigEntry EnableBigDoorInPersonClose; internal static ConfigEntry DebugRollLogging; internal static ConfigEntry EnableLockpickSounds; internal static ConfigEntry NormalDoorPickTime; internal static ConfigEntry NormalDoorSuccessChance; internal static ConfigEntry BigDoorHackTime; internal static ConfigEntry BigDoorSuccessChance; internal static ConfigEntry BigDoorCloseTime; internal static ConfigEntry RetryCooldown; internal static ConfigEntry FailFlashTime; internal static ConfigEntry LockpickSoundVolume; internal static ConfigEntry NormalDoorTriggerWidth; internal static ConfigEntry NormalDoorTriggerHeight; internal static ConfigEntry NormalDoorTriggerDepth; internal static ConfigEntry DoorTintStrength; internal static ConfigEntry DoorOverlayAlpha; internal static ConfigEntry DoorEmissionStrength; internal static ConfigEntry DoorLightStrength; internal static ConfigEntry NormalDoorVisualMultiplier; internal static ConfigEntry BigDoorVisualMultiplier; private float nextScanTime = 0f; private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; EnableNormalDoorLockpicking = ((BaseUnityPlugin)this).Config.Bind("General", "Enable normal door lockpicking", true, "Adds a normal Lethal Company E hold prompt to locked normal doors."); EnableBigDoorHacking = ((BaseUnityPlugin)this).Config.Bind("General", "Enable big door prying", true, "Adds a normal Lethal Company E hold prompt to closed terminal controlled big doors."); EnableBigDoorInPersonClose = ((BaseUnityPlugin)this).Config.Bind("General", "Enable big door in-person close", true, "Adds a normal Lethal Company E hold prompt to close open terminal controlled big doors."); EnableLockpickSounds = ((BaseUnityPlugin)this).Config.Bind("Audio", "Enable lockpick sounds", true, "Plays the base game lockpicking sound while holding E on a locked normal door."); LockpickSoundVolume = ((BaseUnityPlugin)this).Config.Bind("Audio", "Lockpick sound volume", 0.75f, "Volume for lockpick, success, and fail sounds."); NormalDoorPickTime = ((BaseUnityPlugin)this).Config.Bind("Normal Doors", "Normal door pick time", 10f, "Seconds required to lockpick a normal locked door."); NormalDoorSuccessChance = ((BaseUnityPlugin)this).Config.Bind("Normal Doors", "Normal door success chance", 0.5f, "Chance to unlock a normal locked door. 0.50 means 50%."); BigDoorHackTime = ((BaseUnityPlugin)this).Config.Bind("Big Doors", "Big door pry time", 25f, "Seconds required to pry open a terminal controlled big door."); BigDoorSuccessChance = ((BaseUnityPlugin)this).Config.Bind("Big Doors", "Big door pry success chance", 0.33f, "Chance to pry open a terminal controlled big door. 0.33 means 33%."); BigDoorCloseTime = ((BaseUnityPlugin)this).Config.Bind("Big Doors", "Big door close time", 2f, "Seconds required to close an open terminal controlled big door in person. This is always successful."); RetryCooldown = ((BaseUnityPlugin)this).Config.Bind("Safety", "Retry cooldown", 2f, "Cooldown after a lockpick or pry attempt finishes. Helps prevent retry race conditions."); FailFlashTime = ((BaseUnityPlugin)this).Config.Bind("Visuals", "Fail flash time", 1.5f, "How long a failed door flashes red."); DebugRollLogging = ((BaseUnityPlugin)this).Config.Bind("Debug", "Debug roll logging", true, "Logs lockpick and pry rolls to the BepInEx console. Leave this on while playtesting."); NormalDoorTriggerWidth = ((BaseUnityPlugin)this).Config.Bind("Trigger Sizes", "Normal door trigger width", 2.25f, "Minimum width of the invisible lockpick interaction trigger on normal doors."); NormalDoorTriggerHeight = ((BaseUnityPlugin)this).Config.Bind("Trigger Sizes", "Normal door trigger height", 3.5f, "Minimum height of the invisible lockpick interaction trigger on normal doors."); NormalDoorTriggerDepth = ((BaseUnityPlugin)this).Config.Bind("Trigger Sizes", "Normal door trigger depth", 2.25f, "Minimum depth of the invisible lockpick interaction trigger on normal doors."); DoorTintStrength = ((BaseUnityPlugin)this).Config.Bind("Door Visuals", "Door tint strength", 0.55f, "How much the real door mesh is tinted while lockpicking or failing. This belongs to DoorLockpickPlus only."); DoorOverlayAlpha = ((BaseUnityPlugin)this).Config.Bind("Door Visuals", "Door overlay alpha", 0.18f, "Transparent overlay strength for the door mesh. Lower this if the highlight is too solid."); DoorEmissionStrength = ((BaseUnityPlugin)this).Config.Bind("Door Visuals", "Door emission strength", 1.15f, "Emission pushed into the door material while highlighted."); DoorLightStrength = ((BaseUnityPlugin)this).Config.Bind("Door Visuals", "Door light strength", 0.55f, "Point light strength while highlighted."); NormalDoorVisualMultiplier = ((BaseUnityPlugin)this).Config.Bind("Door Visuals", "Normal door visual multiplier", 1.35f, "Extra brightness multiplier for normal doors. Raise this if normal doors are too faint."); BigDoorVisualMultiplier = ((BaseUnityPlugin)this).Config.Bind("Door Visuals", "Big door visual multiplier", 0.35f, "Brightness multiplier for big doors. Lower this if big doors are too bright."); harmony.PatchAll(); Log.LogInfo((object)"DoorLockpickPlus 1.3.8 loaded. Scene-safe big door commands and fixed door highlights enabled."); } private void OnDestroy() { harmony.UnpatchSelf(); } private void Update() { if (!(Time.time < nextScanTime)) { nextScanTime = Time.time + 1f; AttachToNormalDoors(); AttachToBigDoors(); } } private void AttachToNormalDoors() { if (EnableNormalDoorLockpicking == null || !EnableNormalDoorLockpicking.Value) { return; } DoorLock[] array = Object.FindObjectsOfType(); DoorLock[] array2 = array; foreach (DoorLock val in array2) { if (!((Object)(object)val == (Object)null) && (Object)(object)((Component)val).GetComponent() == (Object)null) { NormalDoorLockpickTarget normalDoorLockpickTarget = ((Component)val).gameObject.AddComponent(); normalDoorLockpickTarget.Init(val); } } } private void AttachToBigDoors() { if ((EnableBigDoorHacking == null || !EnableBigDoorHacking.Value) && (EnableBigDoorInPersonClose == null || !EnableBigDoorInPersonClose.Value)) { return; } TerminalAccessibleObject[] array = Object.FindObjectsOfType(); TerminalAccessibleObject[] array2 = array; foreach (TerminalAccessibleObject val in array2) { if (!((Object)(object)val == (Object)null) && BigDoorUtil.IsProbablyBigDoor(val) && (Object)(object)((Component)val).GetComponent() == (Object)null) { BigDoorLockpickTarget bigDoorLockpickTarget = ((Component)val).gameObject.AddComponent(); bigDoorLockpickTarget.Init(val); } } } internal static void ShowTip(string header, string body, bool warning) { try { HUDManager val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null) { return; } MethodInfo methodInfo = AccessTools.Method(typeof(HUDManager), "DisplayTip", new Type[5] { typeof(string), typeof(string), typeof(bool), typeof(bool), typeof(string) }, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(val, new object[5] { header, body, warning, false, "DoorLockpickPlus" }); return; } MethodInfo methodInfo2 = AccessTools.Method(typeof(HUDManager), "DisplayTip", (Type[])null, (Type[])null); if (methodInfo2 == null) { return; } ParameterInfo[] parameters = methodInfo2.GetParameters(); object[] array = new object[parameters.Length]; int num = 0; for (int i = 0; i < parameters.Length; i++) { Type parameterType = parameters[i].ParameterType; if (parameterType == typeof(string)) { switch (num) { case 0: array[i] = header; break; case 1: array[i] = body; break; default: array[i] = "DoorLockpickPlus"; break; } num++; } else if (parameterType == typeof(bool)) { array[i] = warning; } else { array[i] = null; } } methodInfo2.Invoke(val, array); } catch { } } internal static Color YellowHighlight() { //IL_0015: 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_001d: Unknown result type (might be due to invalid IL or missing references) return new Color(1f, 0.78f, 0.08f, 1f); } internal static Color RedHighlight() { //IL_0015: 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_001d: Unknown result type (might be due to invalid IL or missing references) return new Color(1f, 0.12f, 0.08f, 1f); } } internal class NormalDoorLockpickTarget : MonoBehaviour { [CompilerGenerated] private sealed class d__21 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public NormalDoorLockpickTarget <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__21(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; <>4__this.MaintainDoorUnlockedState(); break; } if (<>4__this.unlockedByThisMod && (Object)(object)<>4__this.door != (Object)null) { <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private DoorLock door; private DoorVisualHighlighter highlighter; private DoorAudioController audioController; private readonly List vanillaTriggers = new List(); private readonly Dictionary vanillaSnapshots = new Dictionary(); private GameObject customTriggerObject; private InteractTrigger customTrigger; private float cooldownUntil = 0f; private float redFlashUntil = 0f; private bool resolvingAttempt = false; private bool unlockedByThisMod = false; private bool unlockGuardStarted = false; private bool unlockMethodsCalled = false; private bool wasHoldingLockpick = false; public void Init(DoorLock targetDoor) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) door = targetDoor; Bounds doorFocusBounds = GetDoorFocusBounds(); highlighter = ((Component)this).gameObject.AddComponent(); highlighter.Init(((Component)this).gameObject, doorFocusBounds, bigDoor: false); audioController = ((Component)this).gameObject.AddComponent(); audioController.Init(door); CacheVanillaTriggers(); CreateCustomTrigger(); } private Bounds GetDoorFocusBounds() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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) Bounds bounds = default(Bounds); ((Bounds)(ref bounds))..ctor(((Component)this).transform.position, Vector3.one * 2f); bool hasBounds = false; if ((Object)(object)door != (Object)null && (Object)(object)door.doorTrigger != (Object)null) { BoundsUtil.EncapsulateTransformBounds(((Component)door.doorTrigger).transform, ref bounds, ref hasBounds); } if ((Object)(object)door != (Object)null && (Object)(object)door.doorTriggerB != (Object)null) { BoundsUtil.EncapsulateTransformBounds(((Component)door.doorTriggerB).transform, ref bounds, ref hasBounds); } if (!hasBounds) { bounds = BoundsUtil.GetBounds(((Component)this).gameObject); return bounds; } return bounds; } private void CacheVanillaTriggers() { TryAddVanillaTrigger(door.doorTrigger); TryAddVanillaTrigger(door.doorTriggerB); InteractTrigger[] componentsInChildren = ((Component)door).GetComponentsInChildren(true); InteractTrigger[] array = componentsInChildren; foreach (InteractTrigger trigger in array) { TryAddVanillaTrigger(trigger); } } private void TryAddVanillaTrigger(InteractTrigger trigger) { if (!((Object)(object)trigger == (Object)null) && !vanillaTriggers.Contains(trigger)) { vanillaTriggers.Add(trigger); vanillaSnapshots[trigger] = new TriggerSnapshot(trigger); } } private void CreateCustomTrigger() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) Bounds doorFocusBounds = GetDoorFocusBounds(); customTriggerObject = new GameObject("DoorLockpickPlus_NormalDoor_InteractTrigger"); customTriggerObject.transform.position = ((Bounds)(ref doorFocusBounds)).center; customTriggerObject.transform.rotation = Quaternion.identity; BoxCollider val = customTriggerObject.AddComponent(); ((Collider)val).isTrigger = true; val.size = new Vector3(Mathf.Max(DoorLockpickPlus.NormalDoorTriggerWidth.Value, ((Bounds)(ref doorFocusBounds)).size.x + 1f), Mathf.Max(DoorLockpickPlus.NormalDoorTriggerHeight.Value, ((Bounds)(ref doorFocusBounds)).size.y + 0.8f), Mathf.Max(DoorLockpickPlus.NormalDoorTriggerDepth.Value, ((Bounds)(ref doorFocusBounds)).size.z + 1f)); InteractTriggerUtil.MakeGameObjectARealInteractTrigger(customTriggerObject); customTrigger = customTriggerObject.AddComponent(); InteractTriggerUtil.ConfigureBaseTrigger(customTrigger); InteractTriggerUtil.CopyIconFromTriggers(customTrigger, vanillaTriggers); InteractTriggerUtil.AddInteractListener(customTrigger, OnDoorInteract); customTriggerObject.SetActive(false); } private void Update() { //IL_0106: 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) if ((Object)(object)door == (Object)null) { ClearAll(); return; } if (unlockedByThisMod) { StopLockpickLoopIfNeeded(); MaintainDoorUnlockedState(); ConfigureUnlockedVanillaTriggers(); SetCustomTriggerActive(active: false); highlighter.Clear(); return; } if (!IsLocked()) { StopLockpickLoopIfNeeded(); ConfigureUnlockedVanillaTriggers(); SetCustomTriggerActive(active: false); highlighter.Clear(); return; } DisableVanillaTriggersWhileLocked(); UpdateCustomTriggerPosition(); bool flag = Time.time < cooldownUntil; bool flag2 = (Object)(object)customTrigger != (Object)null && customTrigger.isBeingHeldByPlayer; ConfigureCustomTrigger(flag); UpdateLockpickLoop(flag2 && !flag && !resolvingAttempt); if (Time.time < redFlashUntil) { highlighter.Apply(DoorLockpickPlus.RedHighlight(), 1f, enableLight: true, DoorLockpickPlus.NormalDoorVisualMultiplier.Value); } else if (flag2 || resolvingAttempt) { highlighter.Apply(DoorLockpickPlus.YellowHighlight(), 1f, enableLight: true, DoorLockpickPlus.NormalDoorVisualMultiplier.Value); } else { highlighter.Clear(); } } private void LateUpdate() { if (unlockedByThisMod) { MaintainDoorUnlockedState(); } } [IteratorStateMachine(typeof(d__21))] private IEnumerator EndOfFrameUnlockGuard() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__21(0) { <>4__this = this }; } private void UpdateLockpickLoop(bool shouldPlay) { if (DoorLockpickPlus.EnableLockpickSounds == null || !DoorLockpickPlus.EnableLockpickSounds.Value) { StopLockpickLoopIfNeeded(); } else if (shouldPlay) { if (!wasHoldingLockpick) { wasHoldingLockpick = true; if ((Object)(object)audioController != (Object)null) { audioController.StartLockpickLoop(); } } } else { StopLockpickLoopIfNeeded(); } } private void StopLockpickLoopIfNeeded() { if (wasHoldingLockpick) { wasHoldingLockpick = false; if ((Object)(object)audioController != (Object)null) { audioController.StopLockpickLoop(); } } } private void UpdateCustomTriggerPosition() { //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_002b: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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) if (!((Object)(object)customTriggerObject == (Object)null)) { Bounds doorFocusBounds = GetDoorFocusBounds(); customTriggerObject.transform.position = ((Bounds)(ref doorFocusBounds)).center; customTriggerObject.transform.rotation = Quaternion.identity; BoxCollider component = customTriggerObject.GetComponent(); if ((Object)(object)component != (Object)null) { component.size = new Vector3(Mathf.Max(DoorLockpickPlus.NormalDoorTriggerWidth.Value, ((Bounds)(ref doorFocusBounds)).size.x + 1f), Mathf.Max(DoorLockpickPlus.NormalDoorTriggerHeight.Value, ((Bounds)(ref doorFocusBounds)).size.y + 0.8f), Mathf.Max(DoorLockpickPlus.NormalDoorTriggerDepth.Value, ((Bounds)(ref doorFocusBounds)).size.z + 1f)); } InteractTriggerUtil.MakeGameObjectARealInteractTrigger(customTriggerObject); } } private void ConfigureCustomTrigger(bool inCooldown) { if (!((Object)(object)customTrigger == (Object)null)) { InteractTriggerUtil.ConfigureBaseTrigger(customTrigger); customTrigger.interactable = !inCooldown && !resolvingAttempt; customTrigger.timeToHold = Mathf.Max(0.1f, DoorLockpickPlus.NormalDoorPickTime.Value); customTrigger.hoverTip = (inCooldown ? "Lockpick cooling down..." : "Pick lock"); customTrigger.holdTip = "Lockpicking..."; SetCustomTriggerActive(active: true); } } private void SetCustomTriggerActive(bool active) { if ((Object)(object)customTriggerObject != (Object)null && customTriggerObject.activeSelf != active) { customTriggerObject.SetActive(active); } } private void DisableVanillaTriggersWhileLocked() { foreach (InteractTrigger vanillaTrigger in vanillaTriggers) { if (!((Object)(object)vanillaTrigger == (Object)null)) { vanillaTrigger.interactable = false; vanillaTrigger.hoverTip = "Locked"; vanillaTrigger.holdTip = "Locked"; } } } private void RestoreVanillaTriggers() { foreach (KeyValuePair vanillaSnapshot in vanillaSnapshots) { if ((Object)(object)vanillaSnapshot.Key != (Object)null) { vanillaSnapshot.Value.Restore(vanillaSnapshot.Key); } } } private void OnDoorInteract(PlayerControllerB player) { if ((Object)(object)door == (Object)null || (Object)(object)player == (Object)null) { return; } StopLockpickLoopIfNeeded(); if (!IsLocked()) { return; } if (resolvingAttempt || Time.time < cooldownUntil) { DoorLockpickPlus.ShowTip("Lockpick", "Wait a moment before trying again.", warning: true); return; } resolvingAttempt = true; float num = Mathf.Clamp01(DoorLockpickPlus.NormalDoorSuccessChance.Value); float num2 = Random.Range(0f, 1f); bool flag = num2 <= num; if (DoorLockpickPlus.DebugRollLogging != null && DoorLockpickPlus.DebugRollLogging.Value && DoorLockpickPlus.Log != null) { DoorLockpickPlus.Log.LogInfo((object)("Normal door lockpick roll: " + num2.ToString("0.000") + " / chance " + num.ToString("0.000") + " / success " + flag)); } if (flag) { unlockedByThisMod = true; unlockMethodsCalled = false; CallKeyStyleUnlockOnce(); MaintainDoorUnlockedState(); ConfigureUnlockedVanillaTriggers(); SetCustomTriggerActive(active: false); if ((Object)(object)audioController != (Object)null) { audioController.PlayUnlockSoundOnce(); } if (!unlockGuardStarted) { unlockGuardStarted = true; ((MonoBehaviour)this).StartCoroutine(EndOfFrameUnlockGuard()); } DoorLockpickPlus.ShowTip("Lockpick Success", "The door unlocked.", warning: false); cooldownUntil = Time.time + 0.5f; } else { if ((Object)(object)audioController != (Object)null) { audioController.PlayFailSoundOnce(); } DoorLockpickPlus.ShowTip("Lockpick Failed", "The lock held. Try again.", warning: true); redFlashUntil = Time.time + Mathf.Max(0.1f, DoorLockpickPlus.FailFlashTime.Value); cooldownUntil = Time.time + Mathf.Max(0.1f, DoorLockpickPlus.RetryCooldown.Value); } resolvingAttempt = false; } private bool IsLocked() { if ((Object)(object)door == (Object)null) { return false; } return door.isLocked; } private void CallKeyStyleUnlockOnce() { if (!((Object)(object)door == (Object)null) && !unlockMethodsCalled) { unlockMethodsCalled = true; CallUnlockMethodsOnDoor(door); if ((Object)(object)door.twinDoor != (Object)null) { CallUnlockMethodsOnDoor(door.twinDoor); } } } private void CallUnlockMethodsOnDoor(DoorLock targetDoor) { if (!((Object)(object)targetDoor == (Object)null) && !ReflectionUtil.CallNoArgExact(targetDoor, "UnlockDoorSyncWithServer")) { ReflectionUtil.CallNoArgExact(targetDoor, "UnlockDoor"); ReflectionUtil.CallNoArgExact(targetDoor, "UnlockDoorServerRpc"); } } private void MaintainDoorUnlockedState() { MaintainDoorUnlockedStateFor(door); if ((Object)(object)door != (Object)null && (Object)(object)door.twinDoor != (Object)null) { MaintainDoorUnlockedStateFor(door.twinDoor); } } private void MaintainDoorUnlockedStateFor(DoorLock targetDoor) { if (!((Object)(object)targetDoor == (Object)null)) { targetDoor.isLocked = false; targetDoor.isPickingLock = false; targetDoor.lockPickTimeLeft = 0f; targetDoor.canBeLocked = false; if ((Object)(object)targetDoor.doorTrigger != (Object)null) { targetDoor.doorTrigger.interactable = true; targetDoor.doorTrigger.timeToHoldSpeedMultiplier = 1f; targetDoor.doorTrigger.timeToHold = targetDoor.defaultTimeToHold; } if ((Object)(object)targetDoor.doorTriggerB != (Object)null) { targetDoor.doorTriggerB.interactable = true; targetDoor.doorTriggerB.timeToHoldSpeedMultiplier = 1f; targetDoor.doorTriggerB.timeToHold = targetDoor.defaultTimeToHold; } } } private void ConfigureUnlockedVanillaTriggers() { ConfigureUnlockedVanillaTriggersFor(door); if ((Object)(object)door != (Object)null && (Object)(object)door.twinDoor != (Object)null) { ConfigureUnlockedVanillaTriggersFor(door.twinDoor); } } private void ConfigureUnlockedVanillaTriggersFor(DoorLock targetDoor) { if (!((Object)(object)targetDoor == (Object)null)) { if ((Object)(object)targetDoor.doorTrigger != (Object)null) { targetDoor.doorTrigger.interactable = true; targetDoor.doorTrigger.oneHandedItemAllowed = true; targetDoor.doorTrigger.twoHandedItemAllowed = true; targetDoor.doorTrigger.timeToHoldSpeedMultiplier = 1f; targetDoor.doorTrigger.timeToHold = targetDoor.defaultTimeToHold; } if ((Object)(object)targetDoor.doorTriggerB != (Object)null) { targetDoor.doorTriggerB.interactable = true; targetDoor.doorTriggerB.oneHandedItemAllowed = true; targetDoor.doorTriggerB.twoHandedItemAllowed = true; targetDoor.doorTriggerB.timeToHoldSpeedMultiplier = 1f; targetDoor.doorTriggerB.timeToHold = targetDoor.defaultTimeToHold; } } } private void ClearAll() { StopLockpickLoopIfNeeded(); RestoreVanillaTriggers(); if ((Object)(object)customTriggerObject != (Object)null) { Object.Destroy((Object)(object)customTriggerObject); customTriggerObject = null; } if ((Object)(object)highlighter != (Object)null) { highlighter.Clear(); } } private void OnDestroy() { ClearAll(); } } internal class BigDoorLockpickTarget : MonoBehaviour { [CompilerGenerated] private sealed class d__20 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public bool targetOpen; public BigDoorLockpickTarget <>4__this; private bool 5__1; private bool 5__2; private bool 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Expected O, but got Unknown //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Expected O, but got Unknown //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if ((Object)(object)<>4__this.bigDoor == (Object)null) { <>4__this.resolvingAttempt = false; return false; } 5__1 = BigDoorUtil.IsOpen(<>4__this.bigDoor); if (5__1 == targetOpen) { if (targetOpen) { DoorLockpickPlus.ShowTip("Big Door", "The big door is already open.", warning: false); } else { DoorLockpickPlus.ShowTip("Big Door", "The big door is already closed.", warning: false); } <>4__this.cooldownUntil = Time.time + 0.5f; <>4__this.resolvingAttempt = false; return false; } if (DoorLockpickPlus.DebugRollLogging != null && DoorLockpickPlus.DebugRollLogging.Value && DoorLockpickPlus.Log != null) { DoorLockpickPlus.Log.LogInfo((object)("Big door command start. targetOpen=" + targetOpen + " beforeOpen=" + 5__1 + " code=" + BigDoorUtil.GetObjectCode(<>4__this.bigDoor))); } BigDoorUtil.ClearCooldown(<>4__this.bigDoor); BigDoorUtil.SendTerminalCommand(<>4__this.bigDoor); <>2__current = (object)new WaitForSeconds(0.35f); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)<>4__this.bigDoor == (Object)null) { <>4__this.resolvingAttempt = false; return false; } 5__2 = BigDoorUtil.IsOpen(<>4__this.bigDoor); if (5__2 != targetOpen) { BigDoorUtil.ClearCooldown(<>4__this.bigDoor); BigDoorUtil.ForceSetOpen(<>4__this.bigDoor, targetOpen); <>2__current = (object)new WaitForSeconds(0.2f); <>1__state = 2; return true; } goto IL_023f; case 2: <>1__state = -1; goto IL_023f; case 3: { <>1__state = -1; break; } IL_023f: if ((Object)(object)<>4__this.bigDoor != (Object)null && BigDoorUtil.IsOpen(<>4__this.bigDoor) != targetOpen) { BigDoorUtil.ForceSetOpen(<>4__this.bigDoor, targetOpen); <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 3; return true; } break; } 5__3 = (Object)(object)<>4__this.bigDoor != (Object)null && BigDoorUtil.IsOpen(<>4__this.bigDoor); if (DoorLockpickPlus.DebugRollLogging != null && DoorLockpickPlus.DebugRollLogging.Value && DoorLockpickPlus.Log != null) { DoorLockpickPlus.Log.LogInfo((object)("Big door command end. targetOpen=" + targetOpen + " actualOpen=" + 5__3)); } if (5__3 == targetOpen) { if (targetOpen) { DoorLockpickPlus.ShowTip("Pry Success", "The big door opened.", warning: false); } else { DoorLockpickPlus.ShowTip("Big Door Closed", "The big door closed.", warning: false); } } else { DoorLockpickPlus.ShowTip("Door Command Failed", "The command ran but the door did not reach the expected state.", warning: true); } <>4__this.cooldownUntil = Time.time + 0.5f; <>4__this.resolvingAttempt = false; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private TerminalAccessibleObject bigDoor; private DoorVisualHighlighter highlighter; private readonly List triggers = new List(); private readonly List triggerObjects = new List(); private float cooldownUntil = 0f; private float redFlashUntil = 0f; private bool resolvingAttempt = false; private float nextTriggerRefreshTime = 0f; private int lastBoundsSignature = 0; public void Init(TerminalAccessibleObject targetDoor) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) bigDoor = targetDoor; Bounds bounds = BoundsUtil.GetBounds(((Component)this).gameObject); highlighter = ((Component)this).gameObject.AddComponent(); highlighter.Init(((Component)this).gameObject, bounds, bigDoor: true); RebuildSurfaceTriggers(); } private void Update() { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bigDoor == (Object)null || (Object)(object)((Component)bigDoor).gameObject == (Object)null) { Clear(); return; } if (!((Component)bigDoor).gameObject.activeInHierarchy) { Clear(); return; } if (Time.time >= nextTriggerRefreshTime) { nextTriggerRefreshTime = Time.time + 0.75f; RebuildSurfaceTriggersIfNeeded(); } bool isOpen = BigDoorUtil.IsOpen(bigDoor); bool inCooldown = Time.time < cooldownUntil; bool flag = AnyTriggerHeld(); UpdateTriggerTransforms(); ConfigureTriggers(isOpen, inCooldown); if (Time.time < redFlashUntil) { highlighter.Apply(DoorLockpickPlus.RedHighlight(), 1f, enableLight: true, DoorLockpickPlus.BigDoorVisualMultiplier.Value); } else if (flag || resolvingAttempt) { highlighter.Apply(DoorLockpickPlus.YellowHighlight(), 1f, enableLight: true, DoorLockpickPlus.BigDoorVisualMultiplier.Value); } else { highlighter.Clear(); } } private bool AnyTriggerHeld() { for (int i = 0; i < triggers.Count; i++) { if ((Object)(object)triggers[i] != (Object)null && triggers[i].isBeingHeldByPlayer) { return true; } } return false; } private void RebuildSurfaceTriggersIfNeeded() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) List individualVisualBounds = BoundsUtil.GetIndividualVisualBounds(((Component)this).gameObject, bigDoor: true); if (individualVisualBounds.Count == 0) { individualVisualBounds.Add(BoundsUtil.GetBounds(((Component)this).gameObject)); } int num = Mathf.Clamp(individualVisualBounds.Count, 1, 8); int boundsSignature = GetBoundsSignature(individualVisualBounds, num); if (num != triggerObjects.Count || boundsSignature != lastBoundsSignature) { RebuildSurfaceTriggers(); } } private int GetBoundsSignature(List boundsList, int count) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) int num = 17; num = num * 31 + count; for (int i = 0; i < count && i < boundsList.Count; i++) { Bounds val = boundsList[i]; num = num * 31 + Mathf.RoundToInt(((Bounds)(ref val)).center.x * 10f); num = num * 31 + Mathf.RoundToInt(((Bounds)(ref val)).center.y * 10f); num = num * 31 + Mathf.RoundToInt(((Bounds)(ref val)).center.z * 10f); num = num * 31 + Mathf.RoundToInt(((Bounds)(ref val)).size.x * 10f); num = num * 31 + Mathf.RoundToInt(((Bounds)(ref val)).size.y * 10f); num = num * 31 + Mathf.RoundToInt(((Bounds)(ref val)).size.z * 10f); } return num; } private void RebuildSurfaceTriggers() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) DestroyTriggers(); if (!((Object)(object)bigDoor == (Object)null) && !((Object)(object)((Component)bigDoor).gameObject == (Object)null)) { List individualVisualBounds = BoundsUtil.GetIndividualVisualBounds(((Component)this).gameObject, bigDoor: true); if (individualVisualBounds.Count == 0) { individualVisualBounds.Add(BoundsUtil.GetBounds(((Component)this).gameObject)); } int num = Mathf.Clamp(individualVisualBounds.Count, 1, 8); lastBoundsSignature = GetBoundsSignature(individualVisualBounds, num); for (int i = 0; i < num; i++) { CreateSurfaceTrigger(i, individualVisualBounds[i]); } UpdateTriggerTransforms(); } } private void CreateSurfaceTrigger(int index, Bounds bounds) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DoorLockpickPlus_BigDoor_SurfaceTrigger_" + index); if ((Object)(object)bigDoor != (Object)null) { val.transform.SetParent(((Component)bigDoor).transform, true); } BoxCollider val2 = val.AddComponent(); ((Collider)val2).isTrigger = true; ConfigureSurfaceBox(val2, bounds); InteractTriggerUtil.MakeGameObjectARealInteractTrigger(val); InteractTrigger val3 = val.AddComponent(); InteractTriggerUtil.ConfigureBaseTrigger(val3); InteractTriggerUtil.CopyIconFromScene(val3); InteractTriggerUtil.AddInteractListener(val3, OnBigDoorInteract); triggerObjects.Add(val); triggers.Add(val3); } private void UpdateTriggerTransforms() { //IL_004f: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bigDoor == (Object)null || (Object)(object)((Component)bigDoor).gameObject == (Object)null) { return; } List individualVisualBounds = BoundsUtil.GetIndividualVisualBounds(((Component)this).gameObject, bigDoor: true); if (individualVisualBounds.Count == 0) { individualVisualBounds.Add(BoundsUtil.GetBounds(((Component)this).gameObject)); } int num = Mathf.Min(triggerObjects.Count, individualVisualBounds.Count); for (int i = 0; i < num; i++) { GameObject val = triggerObjects[i]; if (!((Object)(object)val == (Object)null)) { if ((Object)(object)val.transform.parent != (Object)(object)((Component)bigDoor).transform) { val.transform.SetParent(((Component)bigDoor).transform, true); } Transform transform = val.transform; Bounds val2 = individualVisualBounds[i]; transform.position = ((Bounds)(ref val2)).center; val.transform.rotation = Quaternion.identity; BoxCollider component = val.GetComponent(); if ((Object)(object)component != (Object)null) { ConfigureSurfaceBox(component, individualVisualBounds[i]); } InteractTriggerUtil.MakeGameObjectARealInteractTrigger(val); } } } private void ConfigureSurfaceBox(BoxCollider box, Bounds bounds) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)box == (Object)null)) { Vector3 size = ((Bounds)(ref bounds)).size; size.x = Mathf.Max(0.6f, size.x); size.y = Mathf.Max(1.2f, size.y); size.z = Mathf.Max(0.45f, size.z); box.center = Vector3.zero; box.size = size; } } private void ConfigureTriggers(bool isOpen, bool inCooldown) { bool flag = false; float timeToHold = 1f; string hoverTip = ""; string holdTip = ""; if (isOpen && DoorLockpickPlus.EnableBigDoorInPersonClose.Value) { flag = true; timeToHold = Mathf.Max(0.1f, DoorLockpickPlus.BigDoorCloseTime.Value); hoverTip = (inCooldown ? "Door controls cooling down..." : "Close big door"); holdTip = "Closing door..."; } else if (!isOpen && DoorLockpickPlus.EnableBigDoorHacking.Value) { flag = true; timeToHold = Mathf.Max(0.1f, DoorLockpickPlus.BigDoorHackTime.Value); hoverTip = (inCooldown ? "Pry attempt cooling down..." : "Pry open big door"); holdTip = "Attempting to pry open..."; } for (int i = 0; i < triggers.Count; i++) { InteractTrigger val = triggers[i]; if (!((Object)(object)val == (Object)null)) { InteractTriggerUtil.ConfigureBaseTrigger(val); val.interactable = flag && !inCooldown && !resolvingAttempt; val.timeToHold = timeToHold; val.hoverTip = hoverTip; val.holdTip = holdTip; } } } private void OnBigDoorInteract(PlayerControllerB player) { if ((Object)(object)bigDoor == (Object)null || (Object)(object)player == (Object)null) { resolvingAttempt = false; return; } if (resolvingAttempt || Time.time < cooldownUntil) { DoorLockpickPlus.ShowTip("Door Controls", "Wait a moment before trying again.", warning: true); return; } resolvingAttempt = true; bool flag = BigDoorUtil.IsOpen(bigDoor); if (DoorLockpickPlus.DebugRollLogging != null && DoorLockpickPlus.DebugRollLogging.Value && DoorLockpickPlus.Log != null) { DoorLockpickPlus.Log.LogInfo((object)("Big door interact on " + ((Object)bigDoor).name + " / current open " + flag)); } if (flag) { ((MonoBehaviour)this).StartCoroutine(ExecuteBigDoorCommand(targetOpen: false)); return; } float num = Mathf.Clamp01(DoorLockpickPlus.BigDoorSuccessChance.Value); float num2 = Random.Range(0f, 1f); bool flag2 = num2 <= num; if (DoorLockpickPlus.DebugRollLogging != null && DoorLockpickPlus.DebugRollLogging.Value && DoorLockpickPlus.Log != null) { DoorLockpickPlus.Log.LogInfo((object)("Big door pry roll: " + num2.ToString("0.000") + " / chance " + num.ToString("0.000") + " / success " + flag2)); } if (flag2) { ((MonoBehaviour)this).StartCoroutine(ExecuteBigDoorCommand(targetOpen: true)); return; } DoorLockpickPlus.ShowTip("Pry Failed", "You failed to pry it open. Try again.", warning: true); redFlashUntil = Time.time + Mathf.Max(0.1f, DoorLockpickPlus.FailFlashTime.Value); cooldownUntil = Time.time + Mathf.Max(0.1f, DoorLockpickPlus.RetryCooldown.Value); resolvingAttempt = false; } [IteratorStateMachine(typeof(d__20))] private IEnumerator ExecuteBigDoorCommand(bool targetOpen) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__20(0) { <>4__this = this, targetOpen = targetOpen }; } private void DestroyTriggers() { for (int i = 0; i < triggerObjects.Count; i++) { if ((Object)(object)triggerObjects[i] != (Object)null) { Object.Destroy((Object)(object)triggerObjects[i]); } } triggerObjects.Clear(); triggers.Clear(); } private void Clear() { resolvingAttempt = false; if ((Object)(object)highlighter != (Object)null) { highlighter.Clear(); } DestroyTriggers(); } private void OnDisable() { resolvingAttempt = false; DestroyTriggers(); } private void OnDestroy() { Clear(); } } internal class DoorAudioController : MonoBehaviour { private DoorLock door; private AudioSource source; private AudioClip pickingClip; private AudioClip unlockClip; private AudioClip failClip; public void Init(DoorLock targetDoor) { door = targetDoor; source = ((Component)this).gameObject.GetComponent(); if ((Object)(object)source == (Object)null) { source = ((Component)this).gameObject.AddComponent(); } source.playOnAwake = false; source.loop = false; source.spatialBlend = 1f; source.rolloffMode = (AudioRolloffMode)1; source.minDistance = 1f; source.maxDistance = 18f; source.dopplerLevel = 0f; source.spatialize = false; pickingClip = AudioUtil.GetAudioClip(door, new string[3] { "pickingLockSFX", "pickLockSFX", "lockpickSFX" }); unlockClip = AudioUtil.GetAudioClip(door, new string[3] { "unlockSFX", "unlockDoorSFX", "doorUnlockSFX" }); failClip = AudioUtil.GetAudioClip(door, new string[3] { "doorLockSFX", "lockedDoorSFX", "lockSFX" }); } public void StartLockpickLoop() { if (!((Object)(object)source == (Object)null) && !((Object)(object)pickingClip == (Object)null)) { float volume = ((DoorLockpickPlus.LockpickSoundVolume != null) ? Mathf.Clamp01(DoorLockpickPlus.LockpickSoundVolume.Value) : 0.75f); if (source.isPlaying && (Object)(object)source.clip == (Object)(object)pickingClip && source.loop) { source.volume = volume; return; } source.Stop(); source.clip = pickingClip; source.loop = true; source.volume = volume; source.Play(); } } public void StopLockpickLoop() { if (!((Object)(object)source == (Object)null) && (Object)(object)source.clip == (Object)(object)pickingClip && source.loop) { source.Stop(); source.loop = false; source.clip = null; } } public void PlayUnlockSoundOnce() { StopLockpickLoop(); PlayOneShotClean(unlockClip); } public void PlayFailSoundOnce() { StopLockpickLoop(); PlayOneShotClean(failClip); } private void PlayOneShotClean(AudioClip clip) { if (!((Object)(object)source == (Object)null) && !((Object)(object)clip == (Object)null)) { float num = ((DoorLockpickPlus.LockpickSoundVolume != null) ? Mathf.Clamp01(DoorLockpickPlus.LockpickSoundVolume.Value) : 0.75f); source.loop = false; source.clip = null; source.Stop(); source.PlayOneShot(clip, num); } } private void OnDestroy() { if ((Object)(object)source != (Object)null) { source.Stop(); } } } internal class DoorVisualHighlighter : MonoBehaviour { private readonly List renderers = new List(); private readonly Dictionary blocks = new Dictionary(); private readonly List overlayObjects = new List(); private readonly List overlayMaterials = new List(); private GameObject lightObject; private Light lightSource; private bool isBigDoor; public void Init(GameObject root, Bounds focusBounds, bool bigDoor) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) isBigDoor = bigDoor; CacheRenderers(root, focusBounds, bigDoor); CreateOverlayMeshes(); CreateLight(); if (DoorLockpickPlus.Log != null) { string text = (((Object)(object)root != (Object)null) ? ((Object)root).name : "null"); DoorLockpickPlus.Log.LogInfo((object)("DoorLockpickPlus visual renderers for " + text + ": " + renderers.Count)); } } private void CacheRenderers(GameObject root, Bounds focusBounds, bool bigDoor) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_0124: Expected O, but got Unknown renderers.Clear(); blocks.Clear(); if ((Object)(object)root == (Object)null) { return; } List list = new List(); CollectRendererCandidates(root.transform, focusBounds, bigDoor, list); if (!bigDoor && list.Count == 0 && (Object)(object)root.transform.parent != (Object)null) { CollectRendererCandidates(root.transform.parent, focusBounds, bigDoor, list); } if (!bigDoor && list.Count == 0 && (Object)(object)root.transform.parent != (Object)null && (Object)(object)root.transform.parent.parent != (Object)null) { CollectRendererCandidates(root.transform.parent.parent, focusBounds, bigDoor, list); } for (int i = 0; i < list.Count; i++) { Renderer val = list[i]; if (!((Object)(object)val == (Object)null) && !renderers.Contains(val)) { renderers.Add(val); blocks[val] = new MaterialPropertyBlock(); } } } private void CollectRendererCandidates(Transform root, Bounds focusBounds, bool bigDoor, List output) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_0091: 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) if ((Object)(object)root == (Object)null || output == null) { return; } Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); Bounds val = focusBounds; ((Bounds)(ref val)).Expand(bigDoor ? 4f : 5f); Renderer[] array = componentsInChildren; foreach (Renderer val2 in array) { if (!RendererUtil.IsVisibleDoorRenderer(val2, bigDoor)) { continue; } if (!bigDoor && !((Bounds)(ref val)).Intersects(val2.bounds)) { Bounds bounds = val2.bounds; float num = Vector3.Distance(((Bounds)(ref bounds)).center, ((Bounds)(ref focusBounds)).center); if (num > 5.5f) { continue; } } if (!output.Contains(val2)) { output.Add(val2); } } } private void CreateOverlayMeshes() { foreach (Renderer renderer in renderers) { if ((Object)(object)renderer == (Object)null) { continue; } MeshFilter component = ((Component)renderer).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) { CreateMeshOverlay(renderer, component.sharedMesh); continue; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMesh != (Object)null) { CreateSkinnedMeshOverlay(val); } } } private void CreateMeshOverlay(Renderer originalRenderer, Mesh mesh) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0025: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DoorLockpickPlus_OverlayMesh"); val.transform.SetParent(((Component)originalRenderer).transform, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one * 1.006f; val.layer = ((Component)originalRenderer).gameObject.layer; MeshFilter val2 = val.AddComponent(); val2.sharedMesh = mesh; MeshRenderer val3 = val.AddComponent(); Material item = (((Renderer)val3).sharedMaterial = CreateOverlayMaterial(Color.clear)); ((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val3).receiveShadows = false; ((Renderer)val3).enabled = false; overlayObjects.Add(val); overlayMaterials.Add(item); } private void CreateSkinnedMeshOverlay(SkinnedMeshRenderer originalRenderer) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0025: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DoorLockpickPlus_OverlaySkinnedMesh"); val.transform.SetParent(((Component)originalRenderer).transform, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one * 1.006f; val.layer = ((Component)originalRenderer).gameObject.layer; SkinnedMeshRenderer val2 = val.AddComponent(); val2.sharedMesh = originalRenderer.sharedMesh; val2.bones = originalRenderer.bones; val2.rootBone = originalRenderer.rootBone; Material item = (((Renderer)val2).sharedMaterial = CreateOverlayMaterial(Color.clear)); ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; ((Renderer)val2).enabled = false; overlayObjects.Add(val); overlayMaterials.Add(item); } private Material CreateOverlayMaterial(Color color) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) Shader val = Shader.Find("Sprites/Default"); if ((Object)(object)val == (Object)null) { val = Shader.Find("Particles/Standard Unlit"); } if ((Object)(object)val == (Object)null) { val = Shader.Find("Unlit/Color"); } if ((Object)(object)val == (Object)null) { val = Shader.Find("Standard"); } Material val2 = new Material(val); ((Object)val2).name = "DoorLockpickPlus_OverlayMaterial"; val2.renderQueue = 3100; if (val2.HasProperty("_SrcBlend")) { val2.SetInt("_SrcBlend", 5); } if (val2.HasProperty("_DstBlend")) { val2.SetInt("_DstBlend", 10); } if (val2.HasProperty("_ZWrite")) { val2.SetInt("_ZWrite", 0); } if (val2.HasProperty("_Cull")) { val2.SetInt("_Cull", 0); } SetMaterialColor(val2, color, 1f); return val2; } private void CreateLight() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) lightObject = new GameObject("DoorLockpickPlus_HighlightLight"); lightObject.transform.SetParent(((Component)this).transform, false); lightObject.transform.localPosition = Vector3.zero; lightSource = lightObject.AddComponent(); lightSource.type = (LightType)2; lightSource.range = 4f; lightSource.intensity = 0f; lightSource.shadows = (LightShadows)0; lightSource.renderMode = (LightRenderMode)1; ((Behaviour)lightSource).enabled = false; } public void Apply(Color color, float strength, bool enableLight, float multiplier) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00a2: 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_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_00b6: 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_0112: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) float num = ((DoorLockpickPlus.DoorTintStrength != null) ? Mathf.Clamp01(DoorLockpickPlus.DoorTintStrength.Value) : 0.55f); float num2 = ((DoorLockpickPlus.DoorOverlayAlpha != null) ? Mathf.Clamp01(DoorLockpickPlus.DoorOverlayAlpha.Value) : 0.18f); float num3 = ((DoorLockpickPlus.DoorEmissionStrength != null) ? Mathf.Max(0f, DoorLockpickPlus.DoorEmissionStrength.Value) : 1.15f); float num4 = ((DoorLockpickPlus.DoorLightStrength != null) ? Mathf.Max(0f, DoorLockpickPlus.DoorLightStrength.Value) : 0.55f); float num5 = Mathf.Max(0f, multiplier); Color val = Color.Lerp(Color.white, color, num * num5); Color val2 = color * num3 * strength * num5; foreach (Renderer renderer in renderers) { if (!((Object)(object)renderer == (Object)null)) { MaterialPropertyBlock val3 = blocks[renderer]; renderer.GetPropertyBlock(val3); val3.SetColor("_Color", val); val3.SetColor("_BaseColor", val); val3.SetColor("_EmissionColor", val2); val3.SetColor("_EmissiveColor", val2); renderer.SetPropertyBlock(val3); } } Color color2 = color; color2.a = num2 * num5; for (int i = 0; i < overlayObjects.Count; i++) { GameObject val4 = overlayObjects[i]; if (!((Object)(object)val4 == (Object)null)) { Renderer component = val4.GetComponent(); if ((Object)(object)component != (Object)null) { component.enabled = true; } if (i < overlayMaterials.Count && (Object)(object)overlayMaterials[i] != (Object)null) { SetMaterialColor(overlayMaterials[i], color2, num5); } } } if ((Object)(object)lightSource != (Object)null) { Bounds acceptedRendererBounds = GetAcceptedRendererBounds(); ((Component)lightSource).transform.position = ((Bounds)(ref acceptedRendererBounds)).center; lightSource.color = color; Light obj = lightSource; Vector3 extents = ((Bounds)(ref acceptedRendererBounds)).extents; obj.range = Mathf.Clamp(((Vector3)(ref extents)).magnitude * (isBigDoor ? 0.75f : 1.05f), 1.5f, isBigDoor ? 5.5f : 7f); lightSource.intensity = (enableLight ? Mathf.Clamp(num4 * strength * num5, 0f, isBigDoor ? 1.2f : 2.5f) : 0f); ((Behaviour)lightSource).enabled = enableLight && renderers.Count > 0; } } public void Clear() { foreach (Renderer renderer in renderers) { if (!((Object)(object)renderer == (Object)null)) { renderer.SetPropertyBlock((MaterialPropertyBlock)null); } } for (int i = 0; i < overlayObjects.Count; i++) { GameObject val = overlayObjects[i]; if (!((Object)(object)val == (Object)null)) { Renderer component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.enabled = false; } } } if ((Object)(object)lightSource != (Object)null) { ((Behaviour)lightSource).enabled = false; lightSource.intensity = 0f; } } private Bounds GetAcceptedRendererBounds() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_004d: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = default(Bounds); ((Bounds)(ref bounds))..ctor(((Component)this).transform.position, Vector3.one); bool flag = false; for (int i = 0; i < renderers.Count; i++) { Renderer val = renderers[i]; if (!((Object)(object)val == (Object)null)) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } return bounds; } private void SetMaterialColor(Material mat, Color color, float multiplier) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0069: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)mat == (Object)null)) { if (mat.HasProperty("_Color")) { mat.SetColor("_Color", color); } if (mat.HasProperty("_BaseColor")) { mat.SetColor("_BaseColor", color); } if (mat.HasProperty("_EmissionColor")) { mat.SetColor("_EmissionColor", color * (1f + multiplier)); } } } private void OnDestroy() { Clear(); for (int i = 0; i < overlayObjects.Count; i++) { if ((Object)(object)overlayObjects[i] != (Object)null) { Object.Destroy((Object)(object)overlayObjects[i]); } } overlayObjects.Clear(); for (int j = 0; j < overlayMaterials.Count; j++) { if ((Object)(object)overlayMaterials[j] != (Object)null) { Object.Destroy((Object)(object)overlayMaterials[j]); } } overlayMaterials.Clear(); if ((Object)(object)lightObject != (Object)null) { Object.Destroy((Object)(object)lightObject); lightObject = null; } } } internal class TriggerSnapshot { private readonly string hoverTip; private readonly string holdTip; private readonly bool interactable; private readonly bool holdInteraction; private readonly float timeToHold; private readonly float timeToHoldSpeedMultiplier; private readonly bool oneHandedItemAllowed; private readonly bool twoHandedItemAllowed; private readonly bool interactCooldown; private readonly float cooldownTime; private readonly bool triggerOnce; public TriggerSnapshot(InteractTrigger trigger) { hoverTip = trigger.hoverTip; holdTip = trigger.holdTip; interactable = trigger.interactable; holdInteraction = trigger.holdInteraction; timeToHold = trigger.timeToHold; timeToHoldSpeedMultiplier = trigger.timeToHoldSpeedMultiplier; oneHandedItemAllowed = trigger.oneHandedItemAllowed; twoHandedItemAllowed = trigger.twoHandedItemAllowed; interactCooldown = trigger.interactCooldown; cooldownTime = trigger.cooldownTime; triggerOnce = trigger.triggerOnce; } public void Restore(InteractTrigger trigger) { trigger.hoverTip = hoverTip; trigger.holdTip = holdTip; trigger.interactable = interactable; trigger.holdInteraction = holdInteraction; trigger.timeToHold = timeToHold; trigger.timeToHoldSpeedMultiplier = timeToHoldSpeedMultiplier; trigger.oneHandedItemAllowed = oneHandedItemAllowed; trigger.twoHandedItemAllowed = twoHandedItemAllowed; trigger.interactCooldown = interactCooldown; trigger.cooldownTime = cooldownTime; trigger.triggerOnce = triggerOnce; } } internal static class InteractTriggerUtil { private static readonly FieldInfo onInteractField = AccessTools.Field(typeof(InteractTrigger), "onInteract"); private static readonly FieldInfo onInteractEarlyField = AccessTools.Field(typeof(InteractTrigger), "onInteractEarly"); private static readonly FieldInfo onStopInteractField = AccessTools.Field(typeof(InteractTrigger), "onStopInteract"); private static readonly FieldInfo holdingInteractEventField = AccessTools.Field(typeof(InteractTrigger), "holdingInteractEvent"); private static readonly FieldInfo onCancelAnimationField = AccessTools.Field(typeof(InteractTrigger), "onCancelAnimation"); public static void MakeGameObjectARealInteractTrigger(GameObject obj) { if (!((Object)(object)obj == (Object)null)) { TrySetTag(obj, "InteractTrigger"); obj.layer = LayerUtil.InteractableLayer(); Collider component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { component.isTrigger = true; } Renderer component2 = obj.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.enabled = false; } } } private static void TrySetTag(GameObject obj, string tag) { try { obj.tag = tag; } catch { } } public static void ConfigureBaseTrigger(InteractTrigger trigger) { if (!((Object)(object)trigger == (Object)null)) { MakeGameObjectARealInteractTrigger(((Component)trigger).gameObject); trigger.interactable = true; trigger.oneHandedItemAllowed = true; trigger.twoHandedItemAllowed = true; trigger.holdInteraction = true; trigger.timeToHoldSpeedMultiplier = 1f; trigger.interactCooldown = true; trigger.cooldownTime = 0.5f; trigger.triggerOnce = false; trigger.stopAnimationString = "SA_stopAnimation"; trigger.animationWaitTime = 2f; trigger.lockPlayerPosition = true; trigger.disableTriggerMesh = true; EnsureEventObject(trigger, onInteractField); EnsureEventObject(trigger, onInteractEarlyField); EnsureEventObject(trigger, onStopInteractField); EnsureEventObject(trigger, holdingInteractEventField); EnsureEventObject(trigger, onCancelAnimationField); CopyIconFromScene(trigger); } } public static void CopyIconFromTriggers(InteractTrigger target, List templates) { if ((Object)(object)target == (Object)null) { return; } if (templates != null) { for (int i = 0; i < templates.Count; i++) { InteractTrigger val = templates[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)target)) { if ((Object)(object)val.hoverIcon != (Object)null) { target.hoverIcon = val.hoverIcon; } if ((Object)(object)val.disabledHoverIcon != (Object)null) { target.disabledHoverIcon = val.disabledHoverIcon; } if ((Object)(object)target.hoverIcon != (Object)null) { return; } } } } CopyIconFromScene(target); } public static void CopyIconFromScene(InteractTrigger target) { if ((Object)(object)target == (Object)null || (Object)(object)target.hoverIcon != (Object)null) { return; } InteractTrigger[] array = Object.FindObjectsOfType(); foreach (InteractTrigger val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)target) && (Object)(object)val.hoverIcon != (Object)null) { target.hoverIcon = val.hoverIcon; target.disabledHoverIcon = (((Object)(object)val.disabledHoverIcon != (Object)null) ? val.disabledHoverIcon : val.hoverIcon); break; } } } private static object EnsureEventObject(InteractTrigger trigger, FieldInfo field) { try { if ((Object)(object)trigger == (Object)null || field == null) { return null; } object obj = field.GetValue(trigger); if (obj == null) { obj = Activator.CreateInstance(field.FieldType); field.SetValue(trigger, obj); } return obj; } catch { return null; } } public static void AddInteractListener(InteractTrigger trigger, Action callback) { try { if ((Object)(object)trigger == (Object)null || callback == null || onInteractField == null) { return; } object obj = EnsureEventObject(trigger, onInteractField); if (obj == null) { return; } UnityAction val = callback.Invoke; MethodInfo method = obj.GetType().GetMethod("AddListener", new Type[1] { typeof(UnityAction) }); if (method != null) { method.Invoke(obj, new object[1] { val }); return; } MethodInfo[] methods = obj.GetType().GetMethods(); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != "AddListener")) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 1) { methodInfo.Invoke(obj, new object[1] { val }); break; } } } } catch (Exception ex) { if (DoorLockpickPlus.Log != null) { DoorLockpickPlus.Log.LogWarning((object)("Failed to add InteractTrigger listener: " + ex.Message)); } } } } internal static class BigDoorUtil { public static bool IsProbablyBigDoor(TerminalAccessibleObject obj) { if ((Object)(object)obj == (Object)null) { return false; } if (obj.isBigDoor) { return true; } string text = ((Object)((Component)obj).gameObject).name.ToLowerInvariant(); if (text.Contains("bigdoor") || text.Contains("big door")) { return true; } Transform parent = ((Component)obj).transform.parent; while ((Object)(object)parent != (Object)null) { string text2 = ((Object)parent).name.ToLowerInvariant(); if (text2.Contains("bigdoor") || text2.Contains("big door")) { return true; } parent = parent.parent; } return false; } public static bool IsOpen(TerminalAccessibleObject obj) { if ((Object)(object)obj == (Object)null) { return false; } return ReflectionUtil.GetBoolFieldExact(obj, "isDoorOpen"); } public static string GetObjectCode(TerminalAccessibleObject obj) { if ((Object)(object)obj == (Object)null) { return ""; } try { if (!string.IsNullOrEmpty(obj.objectCode)) { return obj.objectCode; } } catch { } return ""; } public static void ClearCooldown(TerminalAccessibleObject obj) { if (!((Object)(object)obj == (Object)null)) { ReflectionUtil.SetBoolFieldExact(obj, "inCooldown", value: false); ReflectionUtil.SetFloatFieldExact(obj, "currentCooldownTimer", 0f); } } public static void SendTerminalCommand(TerminalAccessibleObject obj) { if (!((Object)(object)obj == (Object)null)) { ClearCooldown(obj); ReflectionUtil.CallNoArgExact(obj, "CallFunctionFromTerminal"); } } public static void ForceSetOpen(TerminalAccessibleObject obj, bool open) { if (!((Object)(object)obj == (Object)null)) { ClearCooldown(obj); ReflectionUtil.SetBoolFieldExact(obj, "isDoorOpen", open); ReflectionUtil.CallBoolArgExact(obj, "SetDoorOpen", open); ReflectionUtil.CallBoolArgExact(obj, "SetDoorLocalClient", open); ReflectionUtil.CallBoolArgExact(obj, "SetDoorOpenClientRpc", open); ReflectionUtil.CallBoolArgExact(obj, "SetDoorOpenServerRpc", open); ReflectionUtil.SetBoolFieldExact(obj, "isDoorOpen", open); } } } internal static class AudioUtil { public static AudioClip GetAudioClip(object instance, string[] fieldNames) { if (instance == null || fieldNames == null) { return null; } for (int i = 0; i < fieldNames.Length; i++) { AudioClip fieldValueExact = ReflectionUtil.GetFieldValueExact(instance, fieldNames[i]); if ((Object)(object)fieldValueExact != (Object)null) { return fieldValueExact; } } return null; } } internal static class RendererUtil { public static bool IsVisibleDoorRenderer(Renderer renderer, bool bigDoor) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_00d8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)renderer == (Object)null) { return false; } if (!renderer.enabled || !((Component)renderer).gameObject.activeInHierarchy) { return false; } string lowerName = ((Object)((Component)renderer).gameObject).name.ToLowerInvariant(); string text = GetPath(((Component)renderer).transform).ToLowerInvariant(); string text2 = ((object)renderer).GetType().Name.ToLowerInvariant(); if (text2.Contains("particle") || text2.Contains("line") || text2.Contains("trail")) { return false; } if (ShouldSkipVisualName(lowerName) || ShouldSkipVisualName(text)) { return false; } Bounds bounds = renderer.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (((Vector3)(ref size)).sqrMagnitude <= 0.0001f) { return false; } MeshFilter component = ((Component)renderer).GetComponent(); SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if (((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null) && ((Object)(object)val == (Object)null || (Object)(object)val.sharedMesh == (Object)null)) { return false; } if (bigDoor && (text.Contains("doorcode") || text.Contains("map") || text.Contains("screen") || text.Contains("ui"))) { return false; } return true; } private static bool ShouldSkipVisualName(string lowerName) { if (string.IsNullOrEmpty(lowerName)) { return false; } return lowerName.Contains("trigger") || lowerName.Contains("collider") || lowerName.Contains("collision") || lowerName.Contains("hitbox") || lowerName.Contains("lockpickplus") || lowerName.Contains("interact") || lowerName.Contains("scan") || lowerName.Contains("node") || lowerName.Contains("radar") || lowerName.Contains("code") || lowerName.Contains("ui") || lowerName.Contains("audio") || lowerName.Contains("light") || lowerName.Contains("particle") || lowerName.Contains("spark") || lowerName.Contains("nav") || lowerName.Contains("bounds"); } private static string GetPath(Transform transform) { if ((Object)(object)transform == (Object)null) { return ""; } string text = ((Object)transform).name; Transform parent = transform.parent; int num = 0; while ((Object)(object)parent != (Object)null && num < 12) { text = ((Object)parent).name + "/" + text; parent = parent.parent; num++; } return text; } } internal static class LayerUtil { public static int InteractableLayer() { int num = LayerMask.NameToLayer("InteractableObject"); if (num >= 0) { return num; } num = LayerMask.NameToLayer("Interactable"); if (num >= 0) { return num; } return 0; } } internal static class BoundsUtil { public static Bounds GetBounds(GameObject root) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0175: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_008a: 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_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_011f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return new Bounds(Vector3.zero, Vector3.one); } Bounds bounds = default(Bounds); ((Bounds)(ref bounds))..ctor(root.transform.position, Vector3.one); bool flag = false; Renderer[] componentsInChildren = root.GetComponentsInChildren(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if (RendererUtil.IsVisibleDoorRenderer(val, bigDoor: true) || RendererUtil.IsVisibleDoorRenderer(val, bigDoor: false)) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } if (flag) { return bounds; } Collider[] componentsInChildren2 = root.GetComponentsInChildren(true); Collider[] array2 = componentsInChildren2; foreach (Collider val2 in array2) { if ((Object)(object)val2 == (Object)null) { continue; } string lowerName = ((Object)((Component)val2).gameObject).name.ToLowerInvariant(); if (!ShouldSkipBoundsName(lowerName)) { if (!flag) { bounds = val2.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val2.bounds); } } } if (flag) { return bounds; } return new Bounds(root.transform.position, Vector3.one * 3f); } public static List GetIndividualVisualBounds(GameObject root, bool bigDoor) { //IL_0049: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) List list = new List(); if ((Object)(object)root == (Object)null) { return list; } Renderer[] componentsInChildren = root.GetComponentsInChildren(true); Renderer[] array = componentsInChildren; Vector3 size; foreach (Renderer val in array) { if (RendererUtil.IsVisibleDoorRenderer(val, bigDoor)) { Bounds bounds = val.bounds; size = ((Bounds)(ref bounds)).size; if (!(((Vector3)(ref size)).sqrMagnitude <= 0.0001f)) { list.Add(bounds); } } } if (list.Count == 0) { Bounds bounds2 = GetBounds(root); size = ((Bounds)(ref bounds2)).size; if (((Vector3)(ref size)).sqrMagnitude > 0.0001f) { list.Add(bounds2); } } return list; } public static void EncapsulateTransformBounds(Transform transform, ref Bounds bounds, ref bool hasBounds) { //IL_0046: 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_0038: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform == (Object)null) { return; } Collider component = ((Component)transform).GetComponent(); if ((Object)(object)component != (Object)null) { if (!hasBounds) { bounds = component.bounds; hasBounds = true; } else { ((Bounds)(ref bounds)).Encapsulate(component.bounds); } return; } Renderer component2 = ((Component)transform).GetComponent(); if ((Object)(object)component2 != (Object)null) { if (!hasBounds) { bounds = component2.bounds; hasBounds = true; } else { ((Bounds)(ref bounds)).Encapsulate(component2.bounds); } } } private static bool ShouldSkipBoundsName(string lowerName) { if (string.IsNullOrEmpty(lowerName)) { return false; } return lowerName.Contains("trigger") || lowerName.Contains("lockpickplus") || lowerName.Contains("interact") || lowerName.Contains("scan") || lowerName.Contains("node") || lowerName.Contains("ui") || lowerName.Contains("audio") || lowerName.Contains("light"); } } internal static class ReflectionUtil { public static T GetFieldValueExact(object instance, string fieldName) where T : class { try { if (instance == null) { return null; } FieldInfo field = instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { return null; } object value = field.GetValue(instance); return value as T; } catch { return null; } } public static bool GetBoolFieldExact(object instance, string fieldName) { try { if (instance == null) { return false; } FieldInfo field = instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null || field.FieldType != typeof(bool)) { return false; } object value = field.GetValue(instance); if (value is bool) { return (bool)value; } } catch { } return false; } public static void SetBoolFieldExact(object instance, string fieldName, bool value) { try { if (instance != null) { FieldInfo field = instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null) && !(field.FieldType != typeof(bool))) { field.SetValue(instance, value); } } } catch { } } public static void SetFloatFieldExact(object instance, string fieldName, float value) { try { if (instance != null) { FieldInfo field = instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null) && !(field.FieldType != typeof(float))) { field.SetValue(instance, value); } } } catch { } } public static bool CallNoArgExact(object instance, string methodName) { try { if (instance == null) { return false; } MethodInfo method = instance.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null || method.GetParameters().Length != 0) { return false; } method.Invoke(instance, null); return true; } catch { return false; } } public static bool CallBoolArgExact(object instance, string methodName, bool value) { try { if (instance == null) { return false; } MethodInfo method = instance.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { return false; } ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length != 1 || parameters[0].ParameterType != typeof(bool)) { return false; } method.Invoke(instance, new object[1] { value }); return true; } catch { return false; } } }