using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CSync.Extensions; using CSync.Lib; using DunGen; using DunGen.Graph; using DunGen.Tags; using GameNetcodeStuff; using HarmonyLib; using LethalCCTV.NetcodePatcher; using LethalCompanyInputUtils.Api; using LethalLib.Modules; using LethalNetworkAPI; using Microsoft.CodeAnalysis; using TMPro; using Unity.Collections; using Unity.Netcode; using Unity.Netcode.Components; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.Video; using Y4NGZCompany.Bootstrap; using Y4NGZCompany.Core; using Y4NGZCompany.Core.Compat; using Y4NGZCompany.Facility.Cameras; using Y4NGZCompany.Facility.Cameras.Placement; using Y4NGZCompany.Facility.Cameras.Probe; using Y4NGZCompany.Facility.Interior; using Y4NGZCompany.Facility.Interior.Placement; using Y4NGZCompany.Facility.Interior.Placement.Authored; using Y4NGZCompany.Facility.Mainframe; using Y4NGZCompany.Facility.Security; using Y4NGZCompany.Facility.Shared; using Y4NGZCompany.Facility.Stash; using Y4NGZCompany.ShipSystems.Rendering; using Y4NGZCompany.ShipSystems.Surveillance; using Y4NGZCompany.ShipSystems.Surveillance.OutlineEffect; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("DunGen")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")] [assembly: IgnoresAccessChecksTo("EasyTextEffects")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")] [assembly: IgnoresAccessChecksTo("Unity.XR.Management")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LethalCCTV")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Y4NGZ surveillance and CCTV systems")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+6ae9e9f17528b47cbc796b51a05c6f7380dda81b")] [assembly: AssemblyProduct("LethalCCTV")] [assembly: AssemblyTitle("LethalCCTV")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LethalCCTV { [BepInPlugin("com.y4ngz.company.lethalcctv", "LethalCCTV", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class LethalCCTVPlugin : BaseUnityPlugin { public const string PluginGuid = "com.y4ngz.company.lethalcctv"; public const string PluginName = "LethalCCTV"; public const string PluginVersion = "1.0.1"; private SurveillanceBootstrap _host; internal const string HostObjectName = "LethalCCTV_Host"; public static LethalCCTVPlugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } private void Awake() { //IL_003c: 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_004a: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; DependencyVersionAudit.RunForLethalCCTV(((BaseUnityPlugin)this).Logger); NetcodeRuntimeBootstrap.Initialize(((BaseUnityPlugin)this).Logger, typeof(LethalCCTVPlugin).Assembly, true); GameObject val = new GameObject("LethalCCTV_Host") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)(object)val); _host = val.AddComponent(); _host.Initialize(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); Log.LogInfo((object)"LethalCCTV 1.0.1 loaded."); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "LethalCCTV"; public const string PLUGIN_NAME = "LethalCCTV"; public const string PLUGIN_VERSION = "1.0.1"; } } namespace Y4NGZCompany.ShipSystems.Surveillance { [HarmonyPatch(typeof(HUDManager), "PingScan_performed")] internal static class CameraOperatorPingScanPatch { [HarmonyPrefix] private static bool Prefix(ref CallbackContext context) { if (!MonitorFocus.IsFocused) { return true; } if (Y4NGZPlayerAnimationBridge.IsFirstPersonHandEditModeActive) { return false; } if (((CallbackContext)(ref context)).performed) { MonitorFocus.TriggerCameraContextOrScan(); } return false; } } [HarmonyPatch(typeof(HUDManager), "UpdateScanNodes")] internal static class CameraOperatorScanNodesPatch { [HarmonyPrefix] private static bool Prefix() { return !MonitorFocus.IsFocused; } } [HarmonyPatch(typeof(PlayerControllerB), "ActivateItem_performed")] internal static class CameraOperatorActivateItemPatch { [HarmonyPrefix] private static bool Prefix() { return !MonitorFocus.IsFocused; } } [HarmonyPatch(typeof(PlayerControllerB), "ActivateItem_canceled")] internal static class CameraOperatorActivateItemCancelPatch { [HarmonyPrefix] private static bool Prefix() { return !MonitorFocus.IsFocused; } } [HarmonyPatch(typeof(PlayerControllerB), "Jump_performed")] internal static class CameraOperatorJumpPerformedPatch { [HarmonyPrefix] private static bool Prefix(PlayerControllerB __instance) { return !MonitorFocus.ShouldSuppressPlayerInput(__instance); } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] internal static class CameraOperatorPlayerUpdatePatch { [HarmonyPrefix] private static void Prefix(PlayerControllerB __instance) { if (MonitorFocus.ShouldSuppressPlayerInput(__instance)) { MonitorFocus.ApplyFocusInputLock(__instance); } } } [HarmonyPatch(typeof(PlayerControllerB), "PlayerLookInput")] internal static class CameraOperatorPlayerLookInputPatch { [HarmonyPrefix] private static bool Prefix(PlayerControllerB __instance) { return !MonitorFocus.ShouldSuppressPlayerInput(__instance); } } internal static class CCTVAccessButton { private const string RootName = "LethalCCTV_AccessButton"; private const string TemplateChildName = "ButtonContainer/ButtonAnimContainer"; private const string RedButtonChildName = "RedButton"; private const string HoverTip = "View cameras : [E]"; private const string PressTriggerName = "press"; private const string GlassOpenBoolName = "GlassOpen"; private const float StateRefreshIntervalSeconds = 0.2f; private const float PressSfxVolume = 0.9f; private const string ScanNodeName = "LethalCCTV_AccessButtonScanNode"; private const string ScanNodeHeader = "CCTV Station"; private const string ScanNodeSubText = "View cameras"; private const int ScanNodeMaxRange = 8; private const int ScanNodeFallbackLayer = 22; private static GameObject _root; private static Animator _buttonAnimator; private static InteractTrigger _trigger; private static AudioSource _audio; private static AudioClip _pressSfx; private static UnityAction _listener; private static float _nextStateRefreshAt; private static bool _templateMissingLogged; private static bool _spawnLogged; internal static bool IsAvailable { get { if ((Object)(object)_root != (Object)null) { return (Object)(object)_trigger != (Object)null; } return false; } } internal static Transform Root { get { if (!((Object)(object)_root != (Object)null)) { return null; } return _root.transform; } } internal static Transform PressContactTransform { get { if (!((Object)(object)_trigger != (Object)null)) { return null; } return ((Component)_trigger).transform; } } internal static bool TryGetPressSurface(out Vector3 point, out Vector3 normal) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0104: 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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) point = Vector3.zero; normal = Vector3.up; Transform pressContactTransform = PressContactTransform; if ((Object)(object)pressContactTransform == (Object)null) { return false; } Vector3 bestAxis = pressContactTransform.up; float bestScore = Mathf.Abs(Vector3.Dot(bestAxis, Vector3.up)); ConsiderAxis(pressContactTransform.right); ConsiderAxis(pressContactTransform.forward); if (Vector3.Dot(bestAxis, Vector3.up) < 0f) { bestAxis = -bestAxis; } normal = ((((Vector3)(ref bestAxis)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref bestAxis)).normalized : Vector3.up); Renderer val = ((Component)pressContactTransform).GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)pressContactTransform).GetComponentInChildren(true); } if ((Object)(object)val == (Object)null) { point = pressContactTransform.position + normal * 0.015f; return true; } Bounds bounds = val.bounds; Vector3 extents = ((Bounds)(ref bounds)).extents; float num = Mathf.Abs(normal.x) * extents.x + Mathf.Abs(normal.y) * extents.y + Mathf.Abs(normal.z) * extents.z; point = ((Bounds)(ref bounds)).center + normal * num; return true; void ConsiderAxis(Vector3 candidate) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_001d: Unknown result type (might be due to invalid IL or missing references) float num2 = Mathf.Abs(Vector3.Dot(candidate, Vector3.up)); if (!(num2 <= bestScore)) { bestAxis = candidate; bestScore = num2; } } } internal static void Ensure(Transform stationRoot) { //IL_015c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)stationRoot == (Object)null || (Object)(object)_root != (Object)null) { return; } AudioClip pressSfx; Transform val = ResolveTemplateButtonContainer(out pressSfx); if ((Object)(object)val == (Object)null) { if (!_templateMissingLogged) { _templateMissingLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Access button template unavailable (teleporter unlockable prefab or ButtonContainer not found); red bezel button remains the CCTV entry."); } } return; } GameObject val2; try { val2 = Object.Instantiate(((Component)val).gameObject, stationRoot, false); } catch (Exception ex) { if (!_templateMissingLogged) { _templateMissingLogged = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Access button clone failed: " + ex.Message)); } } return; } ((Object)val2).name = "LethalCCTV_AccessButton"; _root = val2; _pressSfx = pressSfx; StripClonedBehaviours(val2); _buttonAnimator = val2.GetComponentInChildren(true); _audio = val2.AddComponent(); _audio.playOnAwake = false; _audio.spatialBlend = 1f; _audio.minDistance = 0.8f; _audio.maxDistance = 12f; WireInteractTrigger(val2); CCTVOperatorStation.ApplyAccessButtonPlacement(val2.transform); BuildScanNode(val2); if ((Object)(object)_buttonAnimator != (Object)null) { _buttonAnimator.SetBool("GlassOpen", true); } if (_spawnLogged) { return; } _spawnLogged = true; ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { string[] obj = new string[8] { $"[LethalCCTV] Access button spawned from teleporter template: local={val2.transform.localPosition} ", "trigger=", ((Object)(object)_trigger != (Object)null) ? "wired" : "MISSING", " animator=", null, null, null, null }; object obj2; if (!((Object)(object)_buttonAnimator != (Object)null)) { obj2 = "MISSING"; } else { RuntimeAnimatorController runtimeAnimatorController = _buttonAnimator.runtimeAnimatorController; obj2 = ((runtimeAnimatorController != null) ? ((Object)runtimeAnimatorController).name : null) ?? ""; } obj[4] = (string)obj2; obj[5] = " pressSfx="; obj[6] = (((Object)(object)_pressSfx != (Object)null) ? ((Object)_pressSfx).name : ""); obj[7] = "."; log3.LogInfo((object)string.Concat(obj)); } } internal static void Shutdown() { if ((Object)(object)_trigger != (Object)null && _listener != null && _trigger.onInteract != null) { ((UnityEvent)(object)_trigger.onInteract).RemoveListener(_listener); } if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _buttonAnimator = null; _trigger = null; _audio = null; _pressSfx = null; _listener = null; _nextStateRefreshAt = 0f; _spawnLogged = false; } internal static void Tick() { if ((Object)(object)_trigger == (Object)null || Time.unscaledTime < _nextStateRefreshAt) { return; } _nextStateRefreshAt = Time.unscaledTime + 0.2f; if ((Object)(object)_buttonAnimator != (Object)null) { try { _buttonAnimator.SetBool("GlassOpen", true); } catch { } } if (CCTVMonitorFeedSync.IsEntryAvailable(out var unavailableReason)) { _trigger.interactable = true; _trigger.hoverTip = "View cameras : [E]"; } else { _trigger.interactable = false; _trigger.disabledHoverTip = unavailableReason ?? string.Empty; } } internal static void PlayPressAnimation() { if ((Object)(object)_buttonAnimator != (Object)null) { try { _buttonAnimator.SetBool("GlassOpen", true); _buttonAnimator.ResetTrigger("press"); _buttonAnimator.SetTrigger("press"); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Access button press animation failed: " + ex.Message)); } } } if ((Object)(object)_audio != (Object)null && (Object)(object)_pressSfx != (Object)null) { _audio.PlayOneShot(_pressSfx, 0.9f); } } private static void BuildScanNode(GameObject clone) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) Transform val = (((Object)(object)_trigger != (Object)null) ? ((Component)_trigger).transform : clone.transform); GameObject val2 = new GameObject("LethalCCTV_AccessButtonScanNode"); val2.transform.SetParent(clone.transform, false); val2.transform.position = val.position; int num = LayerMask.NameToLayer("ScanNode"); val2.layer = ((num >= 0) ? num : 22); try { val2.tag = "DoNotSet"; } catch (UnityException) { } SphereCollider obj = val2.AddComponent(); ((Collider)obj).isTrigger = true; obj.radius = 0.3f; ScanNodeProperties obj2 = val2.AddComponent(); obj2.headerText = "CCTV Station"; obj2.subText = "View cameras"; obj2.minRange = 0; obj2.maxRange = 8; obj2.requiresLineOfSight = false; obj2.nodeType = 0; obj2.scrapValue = 0; obj2.creatureScanID = -1; } private static void OnPressed(PlayerControllerB player) { CCTVVanillaMonitorButtons.RequestEntry(player); } private static Transform ResolveTemplateButtonContainer(out AudioClip pressSfx) { pressSfx = null; StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.unlockablesList == (Object)null || instance.unlockablesList.unlockables == null) { return null; } for (int i = 0; i < instance.unlockablesList.unlockables.Count; i++) { GameObject val = instance.unlockablesList.unlockables[i]?.prefabObject; if ((Object)(object)val == (Object)null) { continue; } ShipTeleporter component = val.GetComponent(); if (!((Object)(object)component == (Object)null) && !component.isInverseTeleporter) { Transform val2 = val.transform.Find("ButtonContainer/ButtonAnimContainer"); if (!((Object)(object)val2 == (Object)null)) { pressSfx = component.buttonPressSFX; return val2; } } } return null; } private static void StripClonedBehaviours(GameObject clone) { MonoBehaviour[] componentsInChildren = clone.GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && (!(val is InteractTrigger) || !string.Equals(((Object)((Component)val).gameObject).name, "RedButton", StringComparison.Ordinal))) { Object.Destroy((Object)(object)val); } } Transform val2 = FindChildRecursive(clone.transform, "ButtonGlass"); if ((Object)(object)val2 != (Object)null) { Collider[] components = ((Component)val2).GetComponents(); for (int j = 0; j < components.Length; j++) { Object.Destroy((Object)(object)components[j]); } } } private static void WireInteractTrigger(GameObject clone) { Transform val = FindChildRecursive(clone.transform, "RedButton"); _trigger = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if ((Object)(object)_trigger == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Access button clone has no RedButton InteractTrigger; entry stays on the bezel button."); } return; } if (_trigger.onInteract != null) { int persistentEventCount = ((UnityEventBase)_trigger.onInteract).GetPersistentEventCount(); for (int i = 0; i < persistentEventCount; i++) { ((UnityEventBase)_trigger.onInteract).SetPersistentListenerState(i, (UnityEventCallState)0); } } _listener = OnPressed; ((UnityEvent)(object)_trigger.onInteract).AddListener(_listener); _trigger.hoverTip = "View cameras : [E]"; _trigger.interactable = true; } private static Transform FindChildRecursive(Transform root, string childName) { if ((Object)(object)root == (Object)null) { return null; } if (string.Equals(((Object)root).name, childName, StringComparison.Ordinal)) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindChildRecursive(root.GetChild(i), childName); if ((Object)(object)val != (Object)null) { return val; } } return null; } } internal static class CctvCommandTargetBridge { internal sealed class TargetInfo { internal Component Component; internal string DisplayName; internal string CommandHint; internal Vector3 Position; internal float Radius; } private const string ApiTypeName = "Y4NGZCompany.Facility.Security.CctvCommandTargetApi, LethalCCTV"; private static Type _apiType; private static bool _resolved; private static MethodInfo _describeTargetMethod; private static MethodInfo _getActiveTargetsMethod; private static MethodInfo _executeCommandMethod; internal static bool TryDescribeTarget(Component component, out TargetInfo info) { info = null; Resolve(); if (_describeTargetMethod == null || (Object)(object)component == (Object)null) { return false; } try { object descriptor = _describeTargetMethod.Invoke(null, new object[1] { component }); info = ReadDescriptor(descriptor); return info != null; } catch { return false; } } internal static List GetActiveTargets() { Resolve(); List list = new List(); if (_getActiveTargetsMethod == null) { return list; } try { if (!(_getActiveTargetsMethod.Invoke(null, Array.Empty()) is IEnumerable enumerable)) { return list; } foreach (object item in enumerable) { TargetInfo targetInfo = ReadDescriptor(item); if (targetInfo != null) { list.Add(targetInfo); } } } catch { } return list; } internal static bool TryExecuteCommand(Component component, string command, out string statusText) { statusText = "UNSUPPORTED TARGET"; Resolve(); if (_executeCommandMethod == null || (Object)(object)component == (Object)null) { return false; } try { object obj = _executeCommandMethod.Invoke(null, new object[2] { component, command ?? string.Empty }); if (obj == null) { statusText = "NO RESPONSE"; return false; } statusText = ReadString(obj, "StatusText", "COMMAND FAILED"); return ReadBool(obj, "Success", fallback: false); } catch { statusText = "COMMAND FAILED"; return false; } } internal static bool TryFindMainframeTarget(out Component target, out string displayName, out string commandHint) { target = null; displayName = "MAINFRAME"; commandHint = "hack"; Resolve(); if (_apiType == null) { return false; } try { object obj = null; PropertyInfo propertyInfo = _apiType.GetProperty("MainframeSupport", BindingFlags.Static | BindingFlags.Public) ?? _apiType.GetProperty("Mainframe", BindingFlags.Static | BindingFlags.Public); if (propertyInfo != null) { obj = propertyInfo.GetValue(null); } if (obj == null) { PropertyInfo propertyInfo2 = Type.GetType("Y4NGZCompany.Facility.Mainframe.MainframeSupport, LethalCCTV", throwOnError: false)?.GetProperty("Active", BindingFlags.Static | BindingFlags.Public); if (propertyInfo2 != null) { obj = propertyInfo2.GetValue(null); } } if (obj == null) { return false; } target = (Component)((obj is Component) ? obj : null); if ((Object)(object)target == (Object)null) { return false; } return true; } catch { return false; } } private static void Resolve() { if (!_resolved || !(_apiType != null)) { _resolved = true; _apiType = Type.GetType("Y4NGZCompany.Facility.Security.CctvCommandTargetApi, LethalCCTV", throwOnError: false); _describeTargetMethod = _apiType?.GetMethod("DescribeTarget", BindingFlags.Static | BindingFlags.Public); _getActiveTargetsMethod = _apiType?.GetMethod("GetActiveTargets", BindingFlags.Static | BindingFlags.Public); _executeCommandMethod = _apiType?.GetMethod("ExecuteCommand", BindingFlags.Static | BindingFlags.Public); } } private static TargetInfo ReadDescriptor(object descriptor) { //IL_0061: 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_006b: Unknown result type (might be due to invalid IL or missing references) if (descriptor == null) { return null; } Component val = ReadComponent(descriptor, "Target"); if ((Object)(object)val == (Object)null) { return null; } return new TargetInfo { Component = val, DisplayName = ReadString(descriptor, "DisplayName", "SUPPORT NODE"), CommandHint = ReadString(descriptor, "CommandHint", string.Empty), Position = ReadVector3(descriptor, "Position", val.transform.position), Radius = Mathf.Clamp(ReadFloat(descriptor, "Radius", 0.9f), 0.35f, 4f) }; } private static Component ReadComponent(object target, string memberName) { object obj = ReadMember(target, memberName); return (Component)((obj is Component) ? obj : null); } private static string ReadString(object target, string memberName, string fallback) { return (ReadMember(target, memberName) as string) ?? fallback; } private static bool ReadBool(object target, string memberName, bool fallback) { object obj = ReadMember(target, memberName); if (obj is bool) { return (bool)obj; } return fallback; } private static float ReadFloat(object target, string memberName, float fallback) { object obj = ReadMember(target, memberName); if (obj is float) { return (float)obj; } if (obj is double num) { return (float)num; } return fallback; } private static Vector3 ReadVector3(object target, string memberName, Vector3 fallback) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) object obj = ReadMember(target, memberName); if (obj is Vector3) { return (Vector3)obj; } return fallback; } private static object ReadMember(object target, string memberName) { if (target == null) { return null; } Type type = target.GetType(); PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public); if (property != null) { return property.GetValue(target); } return type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public)?.GetValue(target); } } internal static class CCTVFocusControlsOverlay { private static GameObject _root; private static Canvas _canvas; private static Image _background; private static RectTransform _panelRect; private static RectTransform _textRect; private static TextMeshProUGUI _text; private static string _lastText; private const float PanelPaddingX = 18f; private const float PanelPaddingY = 12f; private const float PanelMinWidth = 260f; private const float PanelMaxWidth = 620f; private const float PanelMinHeight = 56f; private const string PlayerControlsText = "CCTV CONTROLS\nMOUSE AIM CAMERA\nARROWS CAMERA LIST\nSPACE RADAR VIEW\nSPC+WHL RADAR ZOOM\nLMB PING\nRMB TARGET\nV HOLD WALKIE\nE/ESC EXIT"; private const string DebugControlsText = "\nH HIDE PANEL\nF1 EDIT MENU\nF2 CAMERA EDIT"; internal static Transform RootTransform { get { if (!((Object)(object)_root != (Object)null)) { return null; } return _root.transform; } } private static bool ConfiguredOn { get { if (SurveillanceBootstrap.Config?.ShowOperatorControlsOverlay != null) { return SurveillanceBootstrap.Config.ShowOperatorControlsOverlay.Value; } return false; } } private static bool OverlayEnabled { get { if (!ConfiguredOn) { return CCTVStickyNoteItem.RegistrationFailed; } return true; } } internal static void Tick() { if (!OverlayEnabled) { Shutdown(); return; } if (!MonitorFocus.IsFocused) { SetVisible(visible: false); return; } Ensure(); SetVisible(visible: true); RefreshText(); } internal static void Shutdown() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _canvas = null; _background = null; _panelRect = null; _textRect = null; _text = null; _lastText = null; } private static void Ensure() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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_0184: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_0212: 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_0229: 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_0261: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root != (Object)null)) { _root = new GameObject("LethalCCTV_FocusControlsOverlay", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); Object.DontDestroyOnLoad((Object)(object)_root); _canvas = _root.GetComponent(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 32760; CanvasScaler component = _root.GetComponent(); component.uiScaleMode = (ScaleMode)1; component.referenceResolution = new Vector2(1920f, 1080f); component.screenMatchMode = (ScreenMatchMode)0; component.matchWidthOrHeight = 0.5f; ((Behaviour)_root.GetComponent()).enabled = false; GameObject val = new GameObject("ControlsPanel", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent(_root.transform, false); _panelRect = val.GetComponent(); _panelRect.anchorMin = new Vector2(0f, 1f); _panelRect.anchorMax = new Vector2(0f, 1f); _panelRect.pivot = new Vector2(0f, 1f); _panelRect.anchoredPosition = new Vector2(26f, -86f); _panelRect.sizeDelta = new Vector2(260f, 56f); _background = val.GetComponent(); ((Graphic)_background).color = new Color(0f, 0f, 0f, 0.56f); ((Graphic)_background).raycastTarget = false; GameObject val2 = new GameObject("ControlsText", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val2.transform.SetParent(val.transform, false); _textRect = val2.GetComponent(); _textRect.anchorMin = Vector2.zero; _textRect.anchorMax = Vector2.one; _textRect.offsetMin = new Vector2(18f, 12f); _textRect.offsetMax = new Vector2(-18f, -12f); _text = val2.GetComponent(); ((Graphic)_text).raycastTarget = false; ((TMP_Text)_text).enableWordWrapping = false; ((TMP_Text)_text).richText = true; ((TMP_Text)_text).alignment = (TextAlignmentOptions)257; ((TMP_Text)_text).fontSize = 24f; ((TMP_Text)_text).lineSpacing = -7f; ((Graphic)_text).color = new Color(1f, 0.58f, 0.14f, 0.96f); TryAssignHudFont(_text); } } private static void RefreshText() { if ((Object)(object)_text == (Object)null) { return; } if (MonitorFocus.IsOperatorDebugToolsEnabled) { string cameraPlacementEditOverlayText = MonitorFocus.GetCameraPlacementEditOverlayText(); if (!string.IsNullOrWhiteSpace(cameraPlacementEditOverlayText)) { SetText(cameraPlacementEditOverlayText); return; } string stationEditMenuOverlayText = MonitorFocus.GetStationEditMenuOverlayText(); if (!string.IsNullOrWhiteSpace(stationEditMenuOverlayText)) { SetText(stationEditMenuOverlayText); return; } string firstPersonHandEditOverlayText = Y4NGZPlayerAnimationBridge.GetFirstPersonHandEditOverlayText(); if (!string.IsNullOrWhiteSpace(firstPersonHandEditOverlayText)) { SetText(firstPersonHandEditOverlayText); } else { SetText("CCTV CONTROLS\nMOUSE AIM CAMERA\nARROWS CAMERA LIST\nSPACE RADAR VIEW\nSPC+WHL RADAR ZOOM\nLMB PING\nRMB TARGET\nV HOLD WALKIE\nE/ESC EXIT\nH HIDE PANEL\nF1 EDIT MENU\nF2 CAMERA EDIT"); } } else { SetText("CCTV CONTROLS\nMOUSE AIM CAMERA\nARROWS CAMERA LIST\nSPACE RADAR VIEW\nSPC+WHL RADAR ZOOM\nLMB PING\nRMB TARGET\nV HOLD WALKIE\nE/ESC EXIT"); } } private static void SetText(string value) { if (!(value == _lastText)) { _lastText = value; ((TMP_Text)_text).text = value; ResizePanelToText(); } } private static void ResizePanelToText() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_panelRect == (Object)null) && !((Object)(object)_text == (Object)null)) { ((TMP_Text)_text).ForceMeshUpdate(true, false); Vector2 preferredValues = ((TMP_Text)_text).GetPreferredValues(((TMP_Text)_text).text, 584f, 0f); float num = Mathf.Clamp(Mathf.Ceil(preferredValues.x + 36f), 260f, 620f); float num2 = Mathf.Max(56f, Mathf.Ceil(preferredValues.y + 24f)); _panelRect.sizeDelta = new Vector2(num, num2); if ((Object)(object)_textRect != (Object)null) { _textRect.offsetMin = new Vector2(18f, 12f); _textRect.offsetMax = new Vector2(-18f, -12f); } } } private static void SetVisible(bool visible) { if ((Object)(object)_root != (Object)null && _root.activeSelf != visible) { _root.SetActive(visible); } } private static void TryAssignHudFont(TextMeshProUGUI target) { if ((Object)(object)target == (Object)null) { return; } try { HUDManager instance = HUDManager.Instance; TextMeshProUGUI[] array = (((Object)(object)instance != (Object)null) ? instance.controlTipLines : null); if (array != null && array.Length != 0 && (Object)(object)array[0] != (Object)null && (Object)(object)((TMP_Text)array[0]).font != (Object)null) { ((TMP_Text)target).font = ((TMP_Text)array[0]).font; } } catch { } } } [DefaultExecutionOrder(32000)] internal sealed class CCTVLocalCameraPositionStabilizer : MonoBehaviour { private PlayerControllerB _player; private Transform _playerRoot; private Transform _cameraTransform; private Vector3 _playerLocalPosition; private int _releaseLateUpdates = -1; internal void Initialize(PlayerControllerB player, Transform playerRoot, Transform cameraTransform, Vector3 playerLocalPosition) { //IL_0016: 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) _player = player; _playerRoot = playerRoot; _cameraTransform = cameraTransform; _playerLocalPosition = playerLocalPosition; _releaseLateUpdates = -1; ((Behaviour)this).enabled = true; } internal void ReleaseAfterLateUpdates(int lateUpdates) { _releaseLateUpdates = Mathf.Max(1, lateUpdates); ((Behaviour)this).enabled = true; } internal void ApplyNow() { //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) if (!((Object)(object)_playerRoot == (Object)null) && !((Object)(object)_cameraTransform == (Object)null)) { _cameraTransform.position = _playerRoot.TransformPoint(_playerLocalPosition); } } private void LateUpdate() { if (_releaseLateUpdates < 0) { return; } ApplyNow(); if (!((Object)(object)_player != (Object)null) || !Y4NGZPlayerAnimationBridge.IsLocalSessionActive(_player)) { _releaseLateUpdates--; if (_releaseLateUpdates <= 0) { ((Behaviour)this).enabled = false; Object.Destroy((Object)(object)this); } } } } [Serializable] public sealed class CCTVMarkerMessage { public int Id; public int Kind; public Vector3 Position; public float Radius; public int ColorKind; public string Label; public float Lifetime; public int CameraIndex; } internal static class CCTVMarkerManager { private sealed class MarkerVisual { public int Id; public int Kind; public Vector3 Position; public float Radius; public float ExpiresAt; public Color Color; public string Label; public RectTransform Root; public Image Top; public Image Bottom; public Image Left; public Image Right; public Image Dot; public TextMeshProUGUI Text; } private const float DEFAULT_SCAN_LIFETIME = 8f; private const float DEFAULT_PING_LIFETIME = 10f; private const float MAX_SCREEN_SIZE = 128f; private const float MIN_SCREEN_SIZE = 26f; private static readonly Color MARKER_GREEN = new Color(0.1f, 1f, 0.35f, 1f); private static readonly Color MARKER_RED = new Color(1f, 0.12f, 0.12f, 1f); private static GameObject _root; private static Canvas _canvas; private static LNetworkMessage _message; private static readonly List _markers = new List(32); private static readonly HashSet _seenIds = new HashSet(); private static int _nextMarkerId; internal static bool HasActiveMarkers => _markers.Count > 0; internal static void Initialize() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root != (Object)null)) { _root = new GameObject("LethalCCTV_WorldMarkers"); if ((Object)(object)SurveillanceBootstrap.Instance != (Object)null) { _root.transform.SetParent(((Component)SurveillanceBootstrap.Instance).transform, false); } else { Object.DontDestroyOnLoad((Object)(object)_root); } _canvas = _root.AddComponent(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 135; CanvasScaler obj = _root.AddComponent(); obj.uiScaleMode = (ScaleMode)1; obj.referenceResolution = new Vector2(1920f, 1080f); obj.matchWidthOrHeight = 0.5f; _message = LNetworkMessage.Connect("cctv_marker_v1", (Action)OnServerReceived, (Action)OnClientReceived, (Action)null); } } internal static void Shutdown() { ClearAll(); _message?.ClearSubscriptions(); _message = null; if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); _root = null; _canvas = null; } } internal static void ClearAll() { for (int i = 0; i < _markers.Count; i++) { if ((Object)(object)_markers[i]?.Root != (Object)null) { Object.Destroy((Object)(object)((Component)_markers[i].Root).gameObject); } } _markers.Clear(); _seenIds.Clear(); } internal static void PublishPing(Vector3 position, int cameraIndex) { //IL_0018: 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) Publish(new CCTVMarkerMessage { Id = NextId(), Kind = 1, Position = position, Radius = 0.55f, ColorKind = 0, Label = "CCTV PING", Lifetime = 10f, CameraIndex = cameraIndex }); } internal static void PublishContextMarker(Vector3 position, float radius, string label, int colorKind, int cameraIndex) { //IL_0018: 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) Publish(new CCTVMarkerMessage { Id = NextId(), Kind = 2, Position = position, Radius = Mathf.Clamp(radius, 0.35f, 4f), ColorKind = colorKind, Label = (string.IsNullOrEmpty(label) ? "CCTV TARGET" : label), Lifetime = 8f, CameraIndex = cameraIndex }); } internal static void Tick() { if ((Object)(object)_root == (Object)null) { return; } Camera camera = ResolveGameplayCamera(); bool isFocused = MonitorFocus.IsFocused; for (int num = _markers.Count - 1; num >= 0; num--) { MarkerVisual markerVisual = _markers[num]; if (markerVisual == null || Time.unscaledTime >= markerVisual.ExpiresAt) { if ((Object)(object)markerVisual?.Root != (Object)null) { Object.Destroy((Object)(object)((Component)markerVisual.Root).gameObject); } _markers.RemoveAt(num); } else { UpdateMarker(markerVisual, camera, isFocused); } } } private static int NextId() { int num = (int)(((Object)(object)GameNetworkManager.Instance?.localPlayerController != (Object)null) ? GameNetworkManager.Instance.localPlayerController.playerClientId : 0); _nextMarkerId++; return (num << 20) ^ _nextMarkerId ^ Mathf.RoundToInt(Time.realtimeSinceStartup * 1000f); } private static void Publish(CCTVMarkerMessage data) { AddLocalMarker(data); if (_message == null) { return; } try { _message.SendServer(data); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] CCTV marker stayed local: " + ex.Message)); } } } private static void OnServerReceived(CCTVMarkerMessage data, ulong _) { try { _message?.SendClients(data); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] CCTV marker server broadcast failed: " + ex.Message)); } } } private static void OnClientReceived(CCTVMarkerMessage data) { AddLocalMarker(data); } private static void AddLocalMarker(CCTVMarkerMessage data) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (data == null) { return; } Initialize(); if (!_seenIds.Contains(data.Id)) { _seenIds.Add(data.Id); MarkerVisual item = CreateMarkerVisual(data); _markers.Add(item); if (data.Kind == 0) { CCTVScanGlowManager.MarkScanTarget(data.Position, data.Radius, data.ColorKind, data.Lifetime); } } } private static MarkerVisual CreateMarkerVisual(CCTVMarkerMessage data) { //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_0041: 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_006b: 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_009a: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_014b: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"CCTVMarker_{data.Id}"); val.transform.SetParent(_root.transform, false); RectTransform val2 = val.AddComponent(); val2.anchorMin = new Vector2(0.5f, 0.5f); val2.anchorMax = new Vector2(0.5f, 0.5f); val2.pivot = new Vector2(0.5f, 0.5f); val2.sizeDelta = new Vector2(64f, 64f); Color color = ((data.ColorKind == 1) ? MARKER_RED : MARKER_GREEN); MarkerVisual markerVisual = new MarkerVisual { Id = data.Id, Kind = data.Kind, Position = data.Position, Radius = Mathf.Clamp(data.Radius, 0.25f, 4f), ExpiresAt = Time.unscaledTime + Mathf.Clamp(data.Lifetime, 1f, 15f), Color = color, Label = ((!string.IsNullOrEmpty(data.Label)) ? data.Label : ((data.Kind == 1) ? "PING" : "SCAN")), Root = val2 }; markerVisual.Top = CreateLine(val2, "Top", color); markerVisual.Bottom = CreateLine(val2, "Bottom", color); markerVisual.Left = CreateLine(val2, "Left", color); markerVisual.Right = CreateLine(val2, "Right", color); markerVisual.Dot = CreateLine(val2, "Dot", color); markerVisual.Text = CreateText(val2, "Label", markerVisual.Label, color); return markerVisual; } private static Image CreateLine(RectTransform parent, string name, Color color) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_004d: 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) GameObject val = new GameObject(name); val.transform.SetParent((Transform)(object)parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); Image obj2 = val.AddComponent(); ((Graphic)obj2).color = color; ((Graphic)obj2).raycastTarget = false; return obj2; } private static TextMeshProUGUI CreateText(RectTransform parent, string name, string text, Color color) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_00ab: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent((Transform)(object)parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0f); obj.anchorMax = new Vector2(0.5f, 0f); obj.pivot = new Vector2(0.5f, 1f); obj.anchoredPosition = new Vector2(0f, -8f); obj.sizeDelta = new Vector2(160f, 24f); TextMeshProUGUI obj2 = val.AddComponent(); ((TMP_Text)obj2).text = text; ((TMP_Text)obj2).fontSize = 13f; ((TMP_Text)obj2).fontStyle = (FontStyles)1; ((TMP_Text)obj2).alignment = (TextAlignmentOptions)514; ((Graphic)obj2).color = color; ((TMP_Text)obj2).enableWordWrapping = false; ((Graphic)obj2).raycastTarget = false; return obj2; } private static void UpdateMarker(MarkerVisual marker, Camera camera, bool hide) { //IL_0035: 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_0040: 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) //IL_005a: 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_0074: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_010a: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)marker?.Root == (Object)null) { return; } if (hide || (Object)(object)camera == (Object)null) { ((Component)marker.Root).gameObject.SetActive(false); return; } Vector3 val = camera.WorldToViewportPoint(marker.Position); if (val.z <= 0.05f || val.x < -0.08f || val.x > 1.08f || val.y < -0.08f || val.y > 1.08f) { ((Component)marker.Root).gameObject.SetActive(false); return; } ((Component)marker.Root).gameObject.SetActive(true); Transform transform = ((Component)_canvas).transform; RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null); float num; Rect rect; if (!((Object)(object)val2 != (Object)null)) { num = Screen.width; } else { rect = val2.rect; num = ((Rect)(ref rect)).width; } float num2 = num; float num3; if (!((Object)(object)val2 != (Object)null)) { num3 = Screen.height; } else { rect = val2.rect; num3 = ((Rect)(ref rect)).height; } float num4 = num3; marker.Root.anchoredPosition = new Vector2((val.x - 0.5f) * num2, (val.y - 0.5f) * num4); float num5 = Mathf.Max(1f, Vector3.Distance(((Component)camera).transform.position, marker.Position)); float num6 = ((marker.Kind == 1) ? 34f : Mathf.Clamp(marker.Radius / num5 * 1150f, 26f, 128f)); marker.Root.sizeDelta = new Vector2(num6, num6); ApplyMarkerShape(marker, num6); } private static void ApplyMarkerShape(MarkerVisual marker, float size) { //IL_0123: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: 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_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) float num = ((marker.Kind == 1) ? 5f : 4f); float num2 = size * 0.5f; if (marker.Kind == 1) { float num3 = Mathf.Clamp(size * 0.32f, 8f, 14f); SetLine(marker.Top, new Vector2(0f, num2 - num3 * 0.5f), new Vector2(num, num3)); SetLine(marker.Bottom, new Vector2(0f, 0f - num2 + num3 * 0.5f), new Vector2(num, num3)); SetLine(marker.Left, new Vector2(0f - num2 + num3 * 0.5f, 0f), new Vector2(num3, num)); SetLine(marker.Right, new Vector2(num2 - num3 * 0.5f, 0f), new Vector2(num3, num)); SetLine(marker.Dot, Vector2.zero, new Vector2(5f, 5f)); } else { float num4 = Mathf.Clamp(size * 0.34f, 12f, 34f); SetLine(marker.Top, new Vector2(0f - num2 + num4 * 0.5f, num2), new Vector2(num4, num)); SetLine(marker.Left, new Vector2(0f - num2, num2 - num4 * 0.5f), new Vector2(num, num4)); SetLine(marker.Bottom, new Vector2(num2 - num4 * 0.5f, 0f - num2), new Vector2(num4, num)); SetLine(marker.Right, new Vector2(num2, 0f - num2 + num4 * 0.5f), new Vector2(num, num4)); SetLine(marker.Dot, Vector2.zero, new Vector2(4f, 4f)); } if ((Object)(object)marker.Text != (Object)null) { ((TMP_Text)marker.Text).rectTransform.anchoredPosition = new Vector2(0f, 0f - num2 - 10f); ((Graphic)marker.Text).color = new Color(marker.Color.r, marker.Color.g, marker.Color.b, 0.95f); } } private static void SetLine(Image image, Vector2 position, Vector2 size) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)image == (Object)null)) { RectTransform rectTransform = ((Graphic)image).rectTransform; rectTransform.anchoredPosition = position; rectTransform.sizeDelta = size; } } private static Camera ResolveGameplayCamera() { PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val != (Object)null && (Object)(object)val.gameplayCamera != (Object)null) { return val.gameplayCamera; } return Camera.main; } } [Serializable] public sealed class CCTVFeedStateMessage { public byte Kind; public int PlayerId; public byte FeedCctv; public int OperatorId; public int ActiveSlot = -1; } internal static class CCTVMonitorFeedSync { private const string CHANNEL = "y4ngz_cctv_feed_v1"; private const byte KindRequestClaim = 1; private const byte KindRequestRelease = 2; private const byte KindRequestToggle = 3; private const byte KindState = 4; private const byte KindRequestActiveSlot = 5; private const float ClaimTimeoutSeconds = 1.5f; private static LNetworkMessage _message; private static bool _initialized; private static bool _feedCctv; private static int _operatorId = -1; private static bool _serverFeedCctv; private static int _serverOperatorId = -1; private static int _serverActiveSlot = -1; private static PlayerControllerB _claimPlayer; private static Action _claimConfirmed; private static Action _claimDenied; private static float _claimTimeoutAt; private static int _remoteActiveSlot = -1; private static int _lastSentActiveSlot = -1; internal static bool IsFeedCctv => _feedCctv; internal static bool HasOperator => _operatorId >= 0; internal static int OperatorId => _operatorId; internal static bool IsClaimPending => (Object)(object)_claimPlayer != (Object)null; internal static int RemoteActiveSlot => _remoteActiveSlot; internal static bool IsLocalOperator { get { PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val != (Object)null) { return _operatorId == (int)val.playerClientId; } return false; } } internal static void Initialize() { if (_initialized) { return; } _initialized = true; try { _message = LNetworkMessage.Connect("y4ngz_cctv_feed_v1", (Action)OnServerReceived, (Action)OnClientReceived, (Action)null); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Monitor feed sync channel 'y4ngz_cctv_feed_v1' connected."); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Monitor feed sync unavailable (feed state stays local): " + ex.Message)); } _message = null; } CCTVStationEvents.ChairEntered += OnLocalChairEntered; CCTVStationEvents.ChairExited += OnLocalChairExited; } internal static void Shutdown() { if (_initialized) { _initialized = false; CCTVStationEvents.ChairEntered -= OnLocalChairEntered; CCTVStationEvents.ChairExited -= OnLocalChairExited; _message?.ClearSubscriptions(); _message = null; ResetLocal("shutdown"); } } internal static void Tick() { if (!((Object)(object)_claimPlayer == (Object)null) && !(Time.unscaledTime < _claimTimeoutAt)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Feed sync claim timed out; failing open into local entry."); } PlayerControllerB claimPlayer = _claimPlayer; Action claimConfirmed = _claimConfirmed; ClearPendingClaim(); ApplyState(feedCctv: true, GetPlayerId(claimPlayer), "claim-timeout-failopen"); claimConfirmed?.Invoke(); } } internal static bool IsEntryAvailable(out string unavailableReason) { if (!CCTVTerminalUnlockable.IsPurchased()) { unavailableReason = "Requires CCTV terminal upgrade"; return false; } if (!IsShipLandedForCctv()) { unavailableReason = "Comes online once the ship has landed"; return false; } if (HasOperator && !IsLocalOperator) { unavailableReason = "In use by another employee"; return false; } if (MonitorFocus.IsFocused || MonitorFocus.IsEntryPoseSettleActive || IsClaimPending) { unavailableReason = string.Empty; return false; } unavailableReason = null; return true; } internal static bool IsFeedToggleAvailable() { if (CCTVTerminalUnlockable.IsPurchased() && !HasOperator && !IsClaimPending && !MonitorFocus.IsFocused) { return IsShipLandedForCctv(); } return false; } internal static bool IsShipLandedForCctv() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && instance.shipHasLanded && !instance.shipIsLeaving) { return !instance.inShipPhase; } return false; } internal static void RequestEntry(PlayerControllerB player, Action onConfirmed, Action onDenied) { if ((Object)(object)player == (Object)null || (Object)(object)_claimPlayer != (Object)null) { return; } if (HasOperator && !IsLocalOperator) { onDenied?.Invoke("Another employee is on the cameras."); return; } int playerId = GetPlayerId(player); if (playerId < 0) { onDenied?.Invoke("Player not ready."); return; } if (_message == null) { ApplyState(feedCctv: true, playerId, "offline-claim"); onConfirmed?.Invoke(); return; } _claimPlayer = player; _claimConfirmed = onConfirmed; _claimDenied = onDenied; _claimTimeoutAt = Time.unscaledTime + 1.5f; SendRequest(new CCTVFeedStateMessage { Kind = 1, PlayerId = playerId }); } internal static void NotifyLocalActiveSlotChanged(int slot) { if (!IsLocalOperator || slot == _lastSentActiveSlot) { return; } _lastSentActiveSlot = slot; if (_message == null) { _remoteActiveSlot = slot; return; } try { _message.SendServer(new CCTVFeedStateMessage { Kind = 5, PlayerId = _operatorId, ActiveSlot = slot }); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Active-slot sync stayed local: " + ex.Message)); } } } internal static void RequestFeedToggle(PlayerControllerB player) { if (IsFeedToggleAvailable()) { int playerId = GetPlayerId(player); if (_message == null) { ApplyState(!_feedCctv, _operatorId, "offline-toggle"); return; } SendRequest(new CCTVFeedStateMessage { Kind = 3, PlayerId = playerId }); } } internal static void ResetForOrbit(string reason) { _serverFeedCctv = false; _serverOperatorId = -1; _serverActiveSlot = -1; ClearPendingClaim(); ApplyState(feedCctv: false, -1, reason, -1); } private static void OnLocalChairEntered(PlayerControllerB player) { int playerId = GetPlayerId(player); if (playerId >= 0 && _operatorId != playerId) { if (_message == null) { ApplyState(feedCctv: true, playerId, "late-claim-offline"); return; } SendRequest(new CCTVFeedStateMessage { Kind = 1, PlayerId = playerId }); } } private static void OnLocalChairExited(PlayerControllerB player) { ReleaseLocalEntryClaim(player, "chair-exited"); } internal static void ReleaseLocalEntryClaim(PlayerControllerB player, string reason) { int num = GetPlayerId(player); if (num < 0 && IsLocalOperator) { num = _operatorId; } ClearPendingClaim(); if (num < 0) { return; } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)string.Format("[LethalCCTV] Releasing local CCTV entry claim ({0}) for player #{1}.", reason ?? "unspecified", num)); } if (_message == null) { if (_operatorId == num) { ApplyState(_feedCctv, -1, "offline-release-" + (reason ?? "unspecified")); } } else { SendRequest(new CCTVFeedStateMessage { Kind = 2, PlayerId = num }); } } private static void SendRequest(CCTVFeedStateMessage message) { try { _message.SendServer(message); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Feed sync request stayed local: " + ex.Message)); } switch (message.Kind) { case 1: { _ = _claimPlayer; Action claimConfirmed = _claimConfirmed; ClearPendingClaim(); ApplyState(feedCctv: true, message.PlayerId, "send-failed-claim"); claimConfirmed?.Invoke(); break; } case 2: if (_operatorId == message.PlayerId) { ApplyState(_feedCctv, -1, "send-failed-release"); } break; case 3: ApplyState(!_feedCctv, _operatorId, "send-failed-toggle"); break; } } } private static void OnServerReceived(CCTVFeedStateMessage data, ulong _) { if (data == null) { return; } switch (data.Kind) { default: return; case 1: if (_serverOperatorId < 0 || _serverOperatorId == data.PlayerId) { _serverOperatorId = data.PlayerId; _serverFeedCctv = true; _serverActiveSlot = -1; } break; case 2: if (_serverOperatorId == data.PlayerId) { _serverOperatorId = -1; } break; case 3: if (_serverOperatorId < 0) { _serverFeedCctv = !_serverFeedCctv; } break; case 5: if (_serverOperatorId == data.PlayerId) { _serverActiveSlot = data.ActiveSlot; } break; case 4: return; } BroadcastState(); } private static void BroadcastState() { try { _message?.SendClients(new CCTVFeedStateMessage { Kind = 4, PlayerId = -1, FeedCctv = (_serverFeedCctv ? ((byte)1) : ((byte)0)), OperatorId = _serverOperatorId, ActiveSlot = _serverActiveSlot }); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Feed sync broadcast failed: " + ex.Message)); } } } private static void OnClientReceived(CCTVFeedStateMessage data) { if (data != null && data.Kind == 4) { ApplyState(data.FeedCctv != 0, data.OperatorId, "network-state", data.ActiveSlot); } } private static void ApplyState(bool feedCctv, int operatorId, string reason, int? activeSlot = null) { bool num = _feedCctv != feedCctv; bool flag = _operatorId != operatorId; _feedCctv = feedCctv; _operatorId = operatorId; if (activeSlot.HasValue) { _remoteActiveSlot = activeSlot.Value; } if (operatorId < 0) { _lastSentActiveSlot = -1; } if (num || flag) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Monitor feed state applied (" + reason + "): feed=" + (feedCctv ? "cctv" : "vanilla") + " operator=" + ((operatorId < 0) ? "none" : ("#" + operatorId)) + ".")); } } ApplyFeedToDisplay(); ResolvePendingClaim(); } internal static void ApplyFeedToDisplay() { bool flag = _feedCctv && CCTVTerminalUnlockable.IsPurchased(); if (!flag || !MonitorFocus.IsStationFeedFlipPending) { CCTVVanillaMonitorDisplay.SetCctvModeActive(flag, announce: false); if (flag) { CCTVVanillaMonitorDisplay.PrimeMonitorOwnershipNow(renderNow: false); } } } private static void ResolvePendingClaim() { if (!((Object)(object)_claimPlayer == (Object)null)) { int playerId = GetPlayerId(_claimPlayer); if (_operatorId == playerId && playerId >= 0) { Action claimConfirmed = _claimConfirmed; ClearPendingClaim(); claimConfirmed?.Invoke(); } else if (HasOperator) { Action claimDenied = _claimDenied; ClearPendingClaim(); claimDenied?.Invoke("Another employee is on the cameras."); } } } private static void ClearPendingClaim() { _claimPlayer = null; _claimConfirmed = null; _claimDenied = null; _claimTimeoutAt = 0f; } private static void ResetLocal(string reason) { _serverFeedCctv = false; _serverOperatorId = -1; _serverActiveSlot = -1; ClearPendingClaim(); _feedCctv = false; _operatorId = -1; _remoteActiveSlot = -1; _lastSentActiveSlot = -1; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Monitor feed state reset locally (" + reason + ").")); } } private static int GetPlayerId(PlayerControllerB player) { if (!((Object)(object)player != (Object)null)) { return -1; } return (int)player.playerClientId; } } [HarmonyPatch(typeof(ManualCameraRenderer), "SwitchScreenButton")] internal static class CCTVMonitorModeButtonPatch { [HarmonyPriority(600)] private static bool Prefix(ManualCameraRenderer __instance) { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)__instance != (Object)(object)instance.mapScreen) { return true; } if (CCTVVanillaMonitorDisplay.IsGeneralImprovementsMonitorWallActive() && !CCTVVanillaMonitorDisplay.OwnsGeneralImprovementsMapScreen()) { return true; } return false; } } [HarmonyPatch] internal static class CCTVMonitorModeShipLeavePatch { [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "ShipLeave")] private static void OnShipLeave() { ResetForOrbit("ship-leave"); } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "ShipLeaveAutomatically")] private static void OnShipLeaveAutomatically() { ResetForOrbit("ship-leave-auto"); } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "Disconnect")] private static void OnDisconnect() { ResetForOrbit("disconnect"); } private static void ResetForOrbit(string reason) { MonitorFocus.ForceExit(reason); CCTVMonitorFeedSync.ResetForOrbit(reason); } } [HarmonyPatch(typeof(ManualCameraRenderer), "Update")] internal static class CCTVMonitorOwnershipManualCameraRendererUpdatePatch { private static bool Prefix(ManualCameraRenderer __instance) { if (!CCTVVanillaMonitorDisplay.ShouldSuppressVanillaMonitorRendererUpdate(__instance)) { return true; } CCTVVanillaMonitorDisplay.ReassertCctvScreenOwnershipAfterVanilla(); return false; } private static void Postfix() { CCTVVanillaMonitorDisplay.ReassertCctvScreenOwnershipAfterVanilla(); } } [HarmonyPatch(typeof(StartOfRound), "LateUpdate")] internal static class CCTVMonitorOwnershipStartOfRoundLateUpdatePatch { private static void Postfix() { CCTVVanillaMonitorDisplay.ReassertCctvScreenOwnershipAfterVanilla(); } } [Serializable] public sealed class CCTVOperatorAnimMessage { public byte Kind; public int PlayerId; public sbyte JoyX; public sbyte JoyY; public byte Arg; public int Yaw; } internal static class CCTVOperatorAnimSync { private const string CHANNEL = "y4ngz_cctv_anim_v1"; private const float JoystickSendInterval = 1f / 12f; private const float JoystickHeartbeatSeconds = 1f; private const float JoystickDiagnosticInterval = 1f; private const string MainframeDefaultStopTrigger = "SA_stopAnimation"; private const byte KindEnter = 1; private const byte KindExit = 2; private const byte KindCameraControl = 3; private const byte KindButtonPress = 4; private const byte KindSelectCamera = 5; private const byte KindRadarLook = 6; private const byte KindJoystick = 7; private const byte KindMainframeEnter = 8; private const byte KindMainframeExit = 9; private static LNetworkMessage _message; private static readonly Dictionary _remoteSessions = new Dictionary(); private static readonly HashSet _remoteMainframePlayers = new HashSet(); private static readonly List _endedSessionIds = new List(); private static readonly Dictionary _nextRemoteJoystickDiagnosticAt = new Dictionary(); private static readonly HashSet _remoteJoystickDiagnosticLogged = new HashSet(); private static float _nextJoystickSendAt; private static float _nextJoystickHeartbeatAt; private static float _nextLocalJoystickDiagnosticAt; private static sbyte _lastSentJoyX = sbyte.MaxValue; private static sbyte _lastSentJoyY = sbyte.MaxValue; private static bool _localJoystickDiagnosticLogged; internal static void Initialize() { if (_message != null) { return; } try { _message = LNetworkMessage.Connect("y4ngz_cctv_anim_v1", (Action)OnServerReceived, (Action)OnClientReceived, (Action)null); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Operator anim sync channel 'y4ngz_cctv_anim_v1' connected."); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Operator anim sync unavailable (animations stay local): " + ex.Message)); } _message = null; } } internal static void Shutdown() { foreach (KeyValuePair remoteSession in _remoteSessions) { remoteSession.Value?.EndImmediate("sync-shutdown"); } _remoteSessions.Clear(); foreach (int item in new List(_remoteMainframePlayers)) { ApplyRemoteMainframeExit(item, ResolvePlayer(item), "sync-shutdown"); } _remoteMainframePlayers.Clear(); _nextRemoteJoystickDiagnosticAt.Clear(); _remoteJoystickDiagnosticLogged.Clear(); _message?.ClearSubscriptions(); _message = null; } internal static void Tick() { if (_remoteSessions.Count == 0) { return; } _endedSessionIds.Clear(); foreach (KeyValuePair remoteSession in _remoteSessions) { OperatorAnimSession value = remoteSession.Value; if (value == null) { _endedSessionIds.Add(remoteSession.Key); continue; } value.Tick(); if (!value.IsActive && !value.IsWindingDown) { _endedSessionIds.Add(remoteSession.Key); } } for (int i = 0; i < _endedSessionIds.Count; i++) { _remoteSessions.Remove(_endedSessionIds[i]); } } internal static void TickLocalJoystickSend(OperatorAnimSession localSession) { //IL_002a: 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) if (_message != null && localSession != null && localSession.IsActive && localSession.CameraControlActive && !(Time.unscaledTime < _nextJoystickSendAt)) { sbyte b = QuantizeAxis(localSession.JoystickCommand.x); sbyte b2 = QuantizeAxis(localSession.JoystickCommand.y); bool num = b != _lastSentJoyX || b2 != _lastSentJoyY; bool flag = Time.unscaledTime >= _nextJoystickHeartbeatAt; if (num || flag) { _nextJoystickSendAt = Time.unscaledTime + 1f / 12f; _nextJoystickHeartbeatAt = Time.unscaledTime + 1f; _lastSentJoyX = b; _lastSentJoyY = b2; Send(new CCTVOperatorAnimMessage { Kind = 7, PlayerId = GetPlayerId(localSession.Player), JoyX = b, JoyY = b2 }); } } } internal static void SendEnter(PlayerControllerB player, int activeSlot) { _lastSentJoyX = sbyte.MaxValue; _lastSentJoyY = sbyte.MaxValue; _localJoystickDiagnosticLogged = false; _nextLocalJoystickDiagnosticAt = 0f; Send(new CCTVOperatorAnimMessage { Kind = 1, PlayerId = GetPlayerId(player), Arg = (byte)Mathf.Clamp(activeSlot, 0, 255) }); ReportOperatorNoiseToBundy(player); } internal static void SendExit(PlayerControllerB player) { Send(new CCTVOperatorAnimMessage { Kind = 2, PlayerId = GetPlayerId(player) }); } internal static void SendCameraControl(PlayerControllerB player, bool controlling) { Send(new CCTVOperatorAnimMessage { Kind = 3, PlayerId = GetPlayerId(player), Arg = (controlling ? ((byte)1) : ((byte)0)) }); } internal static void SendButtonPress(PlayerControllerB player, int buttonId) { Send(new CCTVOperatorAnimMessage { Kind = 4, PlayerId = GetPlayerId(player), Arg = (byte)Mathf.Clamp(buttonId, 0, 255) }); } internal static void SendSelectCamera(PlayerControllerB player, int slot) { Send(new CCTVOperatorAnimMessage { Kind = 5, PlayerId = GetPlayerId(player), Arg = (byte)Mathf.Clamp(slot, 0, 255) }); } internal static void SendRadarLook(PlayerControllerB player, bool looking) { Send(new CCTVOperatorAnimMessage { Kind = 6, PlayerId = GetPlayerId(player), Arg = (looking ? ((byte)1) : ((byte)0)) }); } internal static void SendMainframeEnter(PlayerControllerB player, short yaw) { Send(new CCTVOperatorAnimMessage { Kind = 8, PlayerId = GetPlayerId(player), Yaw = yaw }); ReportOperatorNoiseToBundy(player); } private static void ReportOperatorNoiseToBundy(PlayerControllerB player) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { BundyWorldNoiseBridge.Report(((Component)player).transform.position, 8, player); } } internal static void SendMainframeExit(PlayerControllerB player) { Send(new CCTVOperatorAnimMessage { Kind = 9, PlayerId = GetPlayerId(player) }); } private static void Send(CCTVOperatorAnimMessage message) { if (message == null) { return; } if (message.PlayerId < 0) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Operator anim sync send skipped: invalid player id for " + KindName(message.Kind) + ".")); } return; } LogLocalSend(message, _message != null); if (_message == null) { return; } try { _message.SendServer(message); } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogDebug((object)("[LethalCCTV] Operator anim message stayed local: " + ex.Message)); } } } private static int GetPlayerId(PlayerControllerB player) { if (!((Object)(object)player != (Object)null)) { return -1; } return (int)player.playerClientId; } private static PlayerControllerB ResolvePlayer(int playerId) { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || instance.allPlayerScripts == null) { return null; } if (playerId < 0 || playerId >= instance.allPlayerScripts.Length) { return null; } return instance.allPlayerScripts[playerId]; } private static sbyte QuantizeAxis(float value) { return (sbyte)Mathf.RoundToInt(Mathf.Clamp(value, -1f, 1f) * 127f); } private static void OnServerReceived(CCTVOperatorAnimMessage data, ulong _) { try { _message?.SendClients(data); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Operator anim server broadcast failed: " + ex.Message)); } } } private static void OnClientReceived(CCTVOperatorAnimMessage data) { //IL_01b4: Unknown result type (might be due to invalid IL or missing references) if (data == null) { return; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val != (Object)null && data.PlayerId == (int)val.playerClientId) { return; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || instance.allPlayerScripts == null || data.PlayerId < 0 || data.PlayerId >= instance.allPlayerScripts.Length) { return; } PlayerControllerB val2 = instance.allPlayerScripts[data.PlayerId]; if ((Object)(object)val2 == (Object)null) { return; } LogRemoteReceive(data); switch (data.Kind) { case 1: ApplyRemoteEnter(data.PlayerId, val2, data.Arg); break; case 2: { if (_remoteSessions.TryGetValue(data.PlayerId, out var value)) { value.BeginGracefulEnd("remote-exit"); } _nextRemoteJoystickDiagnosticAt.Remove(data.PlayerId); _remoteJoystickDiagnosticLogged.Remove(data.PlayerId); break; } case 3: GetRemoteSession(data.PlayerId)?.SetCameraControl(data.Arg != 0); break; case 4: GetRemoteSession(data.PlayerId)?.PressButton(data.Arg, isStandUp: false); break; case 5: GetRemoteSession(data.PlayerId)?.SelectCamera(data.Arg); break; case 6: GetRemoteSession(data.PlayerId)?.SetRadarLook(data.Arg != 0); break; case 7: GetRemoteSession(data.PlayerId)?.SetJoystickTargetAbsolute(new Vector2((float)data.JoyX / 127f, (float)data.JoyY / 127f)); break; case 8: ApplyRemoteMainframeEnter(data.PlayerId, val2, data.Yaw); break; case 9: ApplyRemoteMainframeExit(data.PlayerId, val2, "remote-exit"); break; } } private static void ApplyRemoteEnter(int playerId, PlayerControllerB player, int activeSlot) { if (_remoteSessions.TryGetValue(playerId, out var value)) { value?.EndImmediate("remote-reenter"); _remoteSessions.Remove(playerId); } _nextRemoteJoystickDiagnosticAt.Remove(playerId); _remoteJoystickDiagnosticLogged.Remove(playerId); OperatorAnimSession operatorAnimSession = new OperatorAnimSession(player, isLocal: false); if (operatorAnimSession.Begin(Y4NGZPlayerAnimationBridge.ResolveControllerShared(), enterFlourish: true)) { operatorAnimSession.SetActiveSlotQuiet(activeSlot); _remoteSessions[playerId] = operatorAnimSession; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] Remote operator anim session started for player #{playerId}."); } ReportOperatorNoiseToBundy(player); } } private static void ApplyRemoteMainframeEnter(int playerId, PlayerControllerB player, int yaw) { if ((Object)(object)player == (Object)null) { return; } ResolveVanillaTerminalAnimation(out var enterTrigger, out var _); short num = (short)Mathf.RoundToInt(Mathf.Repeat((float)yaw, 360f)); try { player.UpdateSpecialAnimationValue(true, num, 0f, false); player.inSpecialInteractAnimation = true; player.enteringSpecialAnimation = false; } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)$"[LethalCCTV][MainframeInteract] Remote mainframe enter failed for player #{playerId}: {ex.Message}"); } } TryTriggerPlayerAnimator(player, enterTrigger, "mainframe-enter"); _remoteMainframePlayers.Add(playerId); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV][MainframeInteract] Remote mainframe TypeOnTerminal stance entered for player #{playerId} yaw={num}."); } ReportOperatorNoiseToBundy(player); } private static void ApplyRemoteMainframeExit(int playerId, PlayerControllerB player, string reason) { if ((Object)(object)player != (Object)null) { ResolveVanillaTerminalAnimation(out var _, out var stopTrigger); TryTriggerPlayerAnimator(player, stopTrigger, "mainframe-exit"); try { player.UpdateSpecialAnimationValue(false, (short)0, 0f, false); player.inSpecialInteractAnimation = false; player.enteringSpecialAnimation = false; } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)$"[LethalCCTV][MainframeInteract] Remote mainframe exit failed for player #{playerId}: {ex.Message}"); } } } _remoteMainframePlayers.Remove(playerId); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)string.Format("[LethalCCTV][MainframeInteract] Remote mainframe TypeOnTerminal stance exited for player #{0} reason='{1}'.", playerId, reason ?? "unspecified")); } } private static void ResolveVanillaTerminalAnimation(out string enterTrigger, out string stopTrigger) { enterTrigger = null; stopTrigger = "SA_stopAnimation"; try { Terminal val = Object.FindObjectOfType(); InteractTrigger val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if (!((Object)(object)val2 == (Object)null)) { if (!string.IsNullOrWhiteSpace(val2.animationString)) { enterTrigger = val2.animationString; } if (!string.IsNullOrWhiteSpace(val2.stopAnimationString)) { stopTrigger = val2.stopAnimationString; } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] Remote vanilla terminal animation probe failed: " + ex.Message)); } } } private static void TryTriggerPlayerAnimator(PlayerControllerB player, string trigger, string phase) { if ((Object)(object)player == (Object)null || (Object)(object)player.playerBodyAnimator == (Object)null || string.IsNullOrWhiteSpace(trigger)) { return; } try { if (AnimatorHasTrigger(player.playerBodyAnimator, trigger)) { player.playerBodyAnimator.ResetTrigger(trigger); player.playerBodyAnimator.SetTrigger(trigger); } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] Remote animator " + phase + " trigger '" + trigger + "' failed: " + ex.Message)); } } } private static bool AnimatorHasTrigger(Animator animator, string trigger) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 if ((Object)(object)animator == (Object)null || string.IsNullOrWhiteSpace(trigger)) { return false; } try { AnimatorControllerParameter[] parameters = animator.parameters; for (int i = 0; i < parameters.Length; i++) { if ((int)parameters[i].type == 9 && string.Equals(parameters[i].name, trigger, StringComparison.Ordinal)) { return true; } } } catch { } return false; } private static OperatorAnimSession GetRemoteSession(int playerId) { if (!_remoteSessions.TryGetValue(playerId, out var value) || !value.IsActive) { return null; } return value; } private static void LogLocalSend(CCTVOperatorAnimMessage message, bool channelReady) { if (message.Kind != 7 || ShouldLogLocalJoystick(message)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] Operator anim sync SEND {FormatMessage(message)} channelReady={channelReady}."); } } } private static bool ShouldLogLocalJoystick(CCTVOperatorAnimMessage message) { if (message.Kind != 7) { return true; } if (!_localJoystickDiagnosticLogged || Time.unscaledTime >= _nextLocalJoystickDiagnosticAt) { _localJoystickDiagnosticLogged = true; _nextLocalJoystickDiagnosticAt = Time.unscaledTime + 1f; return true; } return false; } private static void LogRemoteReceive(CCTVOperatorAnimMessage message) { if (message.Kind == 7) { bool num = _remoteJoystickDiagnosticLogged.Contains(message.PlayerId); _nextRemoteJoystickDiagnosticAt.TryGetValue(message.PlayerId, out var value); if (num && Time.unscaledTime < value) { return; } _remoteJoystickDiagnosticLogged.Add(message.PlayerId); _nextRemoteJoystickDiagnosticAt[message.PlayerId] = Time.unscaledTime + 1f; } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Operator anim sync RECV " + FormatMessage(message) + ".")); } } private static string FormatMessage(CCTVOperatorAnimMessage message) { if (message == null) { return ""; } if (message.Kind == 7) { return $"{KindName(message.Kind)} player=#{message.PlayerId} " + $"joy=({(float)message.JoyX / 127f:F2},{(float)message.JoyY / 127f:F2})"; } if (message.Kind == 8) { return $"{KindName(message.Kind)} player=#{message.PlayerId} yaw={message.Yaw}"; } return $"{KindName(message.Kind)} player=#{message.PlayerId} arg={message.Arg}"; } private static string KindName(byte kind) { return kind switch { 1 => "Enter", 2 => "Exit", 3 => "CameraControl", 4 => "ButtonPress", 5 => "SelectCamera", 6 => "RadarLook", 7 => "Joystick", 8 => "MainframeEnter", 9 => "MainframeExit", _ => "Unknown(" + kind + ")", }; } } [HarmonyPatch(typeof(PlayerControllerB), "UpdatePlayerAnimationsToOtherClients")] internal static class CCTVOperatorAnimSyncSuppressPatch { private static bool Prefix(PlayerControllerB __instance) { return !Y4NGZPlayerAnimationBridge.IsLocalSessionActive(__instance); } } internal static class CCTVOperatorInteractionsBridge { private sealed class CctvOperatorManifest { public string interactionId; public string bundleInternalName; public CctvLocalViewmodelManifest localViewmodel; public CctvBodyManifest body; } private sealed class CctvLocalViewmodelManifest { public string bundleFileName; public string prefabAssetName; public string controllerAssetName; } private sealed class CctvBodyManifest { public bool enabled; public string bundleFileName; public string controllerAssetName; } private static class ManifestJson { internal static bool TryParseObject(string json, out Dictionary value, out string error) { value = null; if (string.IsNullOrWhiteSpace(json)) { error = "detail='empty document'"; return false; } try { int index = 0; object obj = ParseValue(json, ref index); SkipWhitespace(json, ref index); if (index != json.Length) { throw new FormatException($"trailing content at offset {index}"); } value = obj as Dictionary; if (value == null) { error = "detail='document root is not a JSON object'"; return false; } error = string.Empty; return true; } catch (Exception ex) { error = "detail='" + ex.GetType().Name + ": " + ex.Message + "'"; return false; } } internal static bool TryReadObject(Dictionary owner, string key, out Dictionary value) { value = ((owner != null && owner.TryGetValue(key, out var value2)) ? (value2 as Dictionary) : null); return value != null; } internal static string ReadString(Dictionary owner, string key) { if (owner == null || !owner.TryGetValue(key, out var value)) { return null; } return value as string; } internal static bool ReadBool(Dictionary owner, string key) { bool flag = default(bool); int num; if (owner != null && owner.TryGetValue(key, out var value)) { if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private static object ParseValue(string json, ref int index) { SkipWhitespace(json, ref index); if (index >= json.Length) { throw new FormatException("unexpected end of document"); } return json[index] switch { '{' => ParseObject(json, ref index), '[' => ParseArray(json, ref index), '"' => ParseString(json, ref index), _ => ParseLiteral(json, ref index), }; } private static Dictionary ParseObject(string json, ref int index) { Dictionary dictionary = new Dictionary(StringComparer.Ordinal); index++; SkipWhitespace(json, ref index); if (index < json.Length && json[index] == '}') { index++; return dictionary; } while (true) { SkipWhitespace(json, ref index); if (index >= json.Length || json[index] != '"') { throw new FormatException($"expected a member name at offset {index}"); } string text = ParseString(json, ref index); SkipWhitespace(json, ref index); if (index >= json.Length || json[index] != ':') { throw new FormatException("expected ':' after member '" + text + "'"); } index++; dictionary[text] = ParseValue(json, ref index); SkipWhitespace(json, ref index); if (index >= json.Length) { throw new FormatException("unterminated object"); } if (json[index] != ',') { break; } index++; } if (json[index] == '}') { index++; return dictionary; } throw new FormatException($"expected ',' or '}}' at offset {index}"); } private static List ParseArray(string json, ref int index) { List list = new List(); index++; SkipWhitespace(json, ref index); if (index < json.Length && json[index] == ']') { index++; return list; } while (true) { list.Add(ParseValue(json, ref index)); SkipWhitespace(json, ref index); if (index >= json.Length) { throw new FormatException("unterminated array"); } if (json[index] != ',') { break; } index++; } if (json[index] == ']') { index++; return list; } throw new FormatException($"expected ',' or ']' at offset {index}"); } private static string ParseString(string json, ref int index) { index++; StringBuilder stringBuilder = new StringBuilder(); while (index < json.Length) { char c = json[index++]; switch (c) { case '"': return stringBuilder.ToString(); default: stringBuilder.Append(c); continue; case '\\': break; } if (index >= json.Length) { break; } char c2 = json[index++]; switch (c2) { case '"': stringBuilder.Append('"'); break; case '\\': stringBuilder.Append('\\'); break; case '/': stringBuilder.Append('/'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'n': stringBuilder.Append('\n'); break; case 'r': stringBuilder.Append('\r'); break; case 't': stringBuilder.Append('\t'); break; case 'u': if (index + 4 > json.Length) { throw new FormatException($"truncated \\u escape at offset {index}"); } stringBuilder.Append((char)ushort.Parse(json.Substring(index, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture)); index += 4; break; default: throw new FormatException($"unsupported escape '\\{c2}' at offset {index}"); } } throw new FormatException("unterminated string"); } private static object ParseLiteral(string json, ref int index) { int num = index; while (index < json.Length && !IsLiteralTerminator(json[index])) { index++; } string text = json.Substring(num, index - num).Trim(); if (text.Length == 0) { throw new FormatException($"expected a value at offset {num}"); } if (string.Equals(text, "true", StringComparison.Ordinal)) { return true; } if (string.Equals(text, "false", StringComparison.Ordinal)) { return false; } if (string.Equals(text, "null", StringComparison.Ordinal)) { return null; } return text; } private static bool IsLiteralTerminator(char c) { if (c != ',' && c != '}' && c != ']') { return char.IsWhiteSpace(c); } return true; } private static void SkipWhitespace(string json, ref int index) { while (index < json.Length && char.IsWhiteSpace(json[index])) { index++; } } } internal const float EnterClipLengthSeconds = 1.1f; internal const float EnterPressContactSeconds = 11f / 30f; internal const float ExitClipLengthSeconds = 0.87f; private const string PackId = "y4ngz.cctv.operator"; private const string WorldInteractionId = "y4ngz.cctv.operator"; private const string WorldManifestFileName = "y4ngz-cctv-operator.manifest.json"; private const string WorldBundleFileName = "y4ngz-cctv-playeranimations.lethalbundle"; private const string WorldBundleInternalName = "y4ngzcctvplayeranimations"; private const string WorldControllerName = "Y4NGZ_CCTV_PlayerMetarig"; private const string ViewmodelInteractionId = "y4ngz.cctv.operator.viewmodel"; private const string ViewmodelManifestFileName = "y4ngz-cctv-operator-viewmodel.manifest.json"; private const string ViewmodelBundleFileName = "y4ngz-cctv-viewmodel.animationbundle"; private const string ViewmodelBundleInternalName = "y4ngzcctvviewmodel"; private const string ViewmodelPrefabName = "Y4NGZ_CCTV_LocalViewmodel"; private const string ViewmodelControllerName = "Y4NGZ_CCTV_LocalViewmodel"; private const float RegistrationRetrySeconds = 5f; private static readonly BindingFlags ApiFlags = BindingFlags.Static | BindingFlags.Public; private static bool _typesResolved; private static bool _packRegistered; private static bool _resolutionFailureLogged; private static bool _packFailureLogged; private static bool _transientRegistrationLogged; private static float _nextRegistrationRetryAt; private static Type _apiType; private static Type _packDefinitionType; private static Type _interactionDefinitionType; private static Type _presentationKindType; private static Type _requestType; private static Type _handleType; private static Type _stopReasonType; private static MethodInfo _tryRegisterInteractionPack; private static MethodInfo _tryStartInteraction; private static MethodInfo _tryBeginInteractionExit; private static MethodInfo _tryStopInteraction; private static MethodInfo _isInteractionActive; private static MethodInfo _trySetInteractionBool; private static MethodInfo _trySetInteractionInt; private static MethodInfo _tryFireInteractionTrigger; internal static bool ConfigEnabled { get { if (SurveillanceBootstrap.Config?.UseInteractionsApiOperatorSession != null) { return SurveillanceBootstrap.Config.UseInteractionsApiOperatorSession.Value; } return true; } } internal static void Initialize() { if (ConfigEnabled) { TryRegisterPack(forceRetry: true, out var _); } } internal static void Tick() { if (ConfigEnabled && !_packRegistered) { TryRegisterPack(forceRetry: false, out var _); } } internal static void Shutdown() { _typesResolved = false; _packRegistered = false; _resolutionFailureLogged = false; _packFailureLogged = false; _transientRegistrationLogged = false; _nextRegistrationRetryAt = 0f; _apiType = null; _packDefinitionType = null; _interactionDefinitionType = null; _presentationKindType = null; _requestType = null; _handleType = null; _stopReasonType = null; _tryRegisterInteractionPack = null; _tryStartInteraction = null; _tryBeginInteractionExit = null; _tryStopInteraction = null; _isInteractionActive = null; _trySetInteractionBool = null; _trySetInteractionInt = null; _tryFireInteractionTrigger = null; } internal static bool TryStart(PlayerControllerB player, bool useDedicatedLocalViewmodel, out object handle, out string reason) { handle = null; reason = string.Empty; if (!ConfigEnabled) { reason = "kill_switch_disabled"; return false; } if ((Object)(object)player == (Object)null) { reason = "player_missing"; return false; } if (!TryRegisterPack(forceRetry: true, out reason)) { return false; } try { object obj = Activator.CreateInstance(_requestType); SetProperty(obj, "Player", player); SetProperty(obj, "PackId", "y4ngz.cctv.operator"); SetProperty(obj, "InteractionId", useDedicatedLocalViewmodel ? "y4ngz.cctv.operator.viewmodel" : "y4ngz.cctv.operator"); object[] array = new object[3] { obj, null, null }; bool num = (bool)_tryStartInteraction.Invoke(null, array); handle = array[1]; reason = (array[2] as string) ?? string.Empty; if (!num || handle == null) { handle = null; if (string.IsNullOrWhiteSpace(reason)) { reason = "interaction_start_rejected"; } return false; } if (!TrySetBool(handle, "Y4NGZ_CCTV_Seated", value: true)) { TryStop(handle, "Interrupted"); handle = null; reason = "seated_parameter_rejected"; return false; } return true; } catch (Exception e) { reason = "interaction_start_exception:" + Unwrap(e); handle = null; return false; } } internal static bool TryBeginExit(object handle, out string reason) { reason = string.Empty; if (handle == null || !_typesResolved || _tryBeginInteractionExit == null) { reason = "interaction_exit_api_unavailable"; return false; } try { object[] array = new object[2] { handle, null }; bool result = (bool)_tryBeginInteractionExit.Invoke(null, array); reason = (array[1] as string) ?? string.Empty; return result; } catch (Exception e) { reason = "interaction_exit_exception:" + Unwrap(e); return false; } } internal static bool TryStop(object handle, string stopReasonName) { if (handle == null || !_typesResolved || _tryStopInteraction == null) { return false; } try { object obj = Enum.Parse(_stopReasonType, string.IsNullOrWhiteSpace(stopReasonName) ? "Interrupted" : stopReasonName); return (bool)_tryStopInteraction.Invoke(null, new object[2] { handle, obj }); } catch (Exception e) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][ApiPort] stop_failed handle=" + FormatHandle(handle) + " reason='" + Unwrap(e) + "'.")); } return false; } } internal static bool IsActive(object handle) { if (handle == null || !_typesResolved || _isInteractionActive == null) { return false; } try { return (bool)_isInteractionActive.Invoke(null, new object[1] { handle }); } catch (Exception e) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][ApiPort] active_check_failed handle=" + FormatHandle(handle) + " reason='" + Unwrap(e) + "'.")); } return false; } } internal static bool TrySetBool(object handle, string parameterName, bool value) { return InvokeParameterMethod(_trySetInteractionBool, handle, parameterName, value); } internal static bool TrySetInt(object handle, string parameterName, int value) { return InvokeParameterMethod(_trySetInteractionInt, handle, parameterName, value); } internal static bool TryFireTrigger(object handle, string parameterName) { if (handle == null || string.IsNullOrWhiteSpace(parameterName) || !_typesResolved || _tryFireInteractionTrigger == null) { return false; } try { return (bool)_tryFireInteractionTrigger.Invoke(null, new object[2] { handle, parameterName }); } catch { return false; } } internal static string FormatHandle(object handle) { if (handle == null) { return ""; } return handle.ToString(); } private static bool TryRegisterPack(bool forceRetry, out string reason) { reason = string.Empty; if (_packRegistered) { return true; } if (!ConfigEnabled) { reason = "kill_switch_disabled"; return false; } if (!forceRetry && Time.realtimeSinceStartup < _nextRegistrationRetryAt) { reason = "registration_retry_throttled"; return false; } if (!TryResolveApi(out reason)) { ScheduleRegistrationRetry(); return false; } string pluginDirectory = GetPluginDirectory(); string text = Path.Combine(pluginDirectory, "y4ngz-cctv-operator.manifest.json"); string text2 = Path.Combine(pluginDirectory, "y4ngz-cctv-playeranimations.lethalbundle"); string text3 = Path.Combine(pluginDirectory, "y4ngz-cctv-operator-viewmodel.manifest.json"); string text4 = Path.Combine(pluginDirectory, "y4ngz-cctv-viewmodel.animationbundle"); string[] array = new string[4] { text, text2, text3, text4 }; for (int i = 0; i < array.Length; i++) { if (!File.Exists(array[i])) { reason = "pack_asset_missing:" + array[i]; LogPackFailureOnce(reason); ScheduleRegistrationRetry(); return false; } } try { string text5 = File.ReadAllText(text); string text6 = File.ReadAllText(text3); if (!TryParseManifest(text5, out var manifest, out var detail)) { reason = "manifest_parse_failed:" + text + " " + detail; LogPackFailureOnce(reason); ScheduleRegistrationRetry(); return false; } if (!TryParseManifest(text6, out var manifest2, out detail)) { reason = "manifest_parse_failed:" + text3 + " " + detail; LogPackFailureOnce(reason); ScheduleRegistrationRetry(); return false; } if (!ValidateWorldManifest(manifest, out detail)) { reason = "manifest_contract_mismatch:" + text + " " + detail; LogPackFailureOnce(reason); ScheduleRegistrationRetry(); return false; } if (!ValidateViewmodelManifest(manifest2, out detail)) { reason = "manifest_contract_mismatch:" + text3 + " " + detail; LogPackFailureOnce(reason); ScheduleRegistrationRetry(); return false; } object value = CreateInteractionDefinition("y4ngz.cctv.operator", "BodyWorld", text5); object value2 = CreateInteractionDefinition("y4ngz.cctv.operator.viewmodel", "DedicatedLocalViewmodel", text6); Array array2 = Array.CreateInstance(_interactionDefinitionType, 2); array2.SetValue(value, 0); array2.SetValue(value2, 1); object obj = Activator.CreateInstance(_packDefinitionType); SetProperty(obj, "PackId", "y4ngz.cctv.operator"); SetProperty(obj, "Version", "1.0.0"); SetProperty(obj, "AssetRootPath", pluginDirectory); SetProperty(obj, "Interactions", array2); object[] array3 = new object[2] { obj, null }; bool flag = (bool)_tryRegisterInteractionPack.Invoke(null, array3); reason = (array3[1] as string) ?? string.Empty; if (!flag && string.Equals(reason, "pack_already_registered", StringComparison.OrdinalIgnoreCase)) { flag = true; } if (!flag) { if (reason.IndexOf("not_initialized", StringComparison.OrdinalIgnoreCase) >= 0) { _nextRegistrationRetryAt = Time.realtimeSinceStartup + 5f; if (!_transientRegistrationLogged) { _transientRegistrationLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ApiPort] pack_registration_deferred reason='" + reason + "'; retrying after Interactions initializes.")); } } return false; } LogPackFailureOnce("registration_failed:" + reason); ScheduleRegistrationRetry(); return false; } _packRegistered = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV][ApiPort] pack_registered pack='y4ngz.cctv.operator' worldBundle='" + text2 + "' worldController='Y4NGZ_CCTV_PlayerMetarig' viewmodelBundle='" + text4 + "' viewmodelPrefab='Y4NGZ_CCTV_LocalViewmodel'.")); } return true; } catch (Exception e) { reason = "registration_exception:" + Unwrap(e); LogPackFailureOnce(reason); ScheduleRegistrationRetry(); return false; } } private static object CreateInteractionDefinition(string interactionId, string presentationKind, string manifestJson) { object? obj = Activator.CreateInstance(_interactionDefinitionType); SetProperty(obj, "InteractionId", interactionId); SetProperty(obj, "PresentationKind", Enum.Parse(_presentationKindType, presentationKind)); SetProperty(obj, "ManifestJson", manifestJson); return obj; } private static bool TryResolveApi(out string reason) { reason = string.Empty; if (_typesResolved) { return true; } try { _apiType = FindType("Y4NGZInteractions.InteractionAnimationApi.LCInteractionAnimationAPI"); _packDefinitionType = FindType("Y4NGZInteractions.InteractionAnimationApi.InteractionAnimationPackDefinition"); _interactionDefinitionType = FindType("Y4NGZInteractions.InteractionAnimationApi.InteractionAnimationDefinition"); _presentationKindType = FindType("Y4NGZInteractions.InteractionAnimationApi.InteractionAnimationPresentationKind"); _requestType = FindType("Y4NGZInteractions.InteractionAnimationApi.InteractionAnimationRequest"); _handleType = FindType("Y4NGZInteractions.InteractionAnimationApi.InteractionAnimationHandle"); _stopReasonType = FindType("Y4NGZInteractions.InteractionAnimationApi.InteractionAnimationStopReason"); if (_apiType == null || _packDefinitionType == null || _interactionDefinitionType == null || _presentationKindType == null || _requestType == null || _handleType == null || _stopReasonType == null) { reason = "required_api_types_missing"; LogResolutionFailureOnce(reason); return false; } _tryRegisterInteractionPack = _apiType.GetMethod("TryRegisterInteractionPack", ApiFlags, null, new Type[2] { _packDefinitionType, typeof(string).MakeByRefType() }, null); _tryStartInteraction = _apiType.GetMethod("TryStartInteraction", ApiFlags, null, new Type[3] { _requestType, _handleType.MakeByRefType(), typeof(string).MakeByRefType() }, null); _tryBeginInteractionExit = _apiType.GetMethod("TryBeginInteractionExit", ApiFlags, null, new Type[2] { _handleType, typeof(string).MakeByRefType() }, null); _tryStopInteraction = _apiType.GetMethod("TryStopInteraction", ApiFlags, null, new Type[2] { _handleType, _stopReasonType }, null); _isInteractionActive = _apiType.GetMethod("IsInteractionActive", ApiFlags, null, new Type[1] { _handleType }, null); _trySetInteractionBool = _apiType.GetMethod("TrySetInteractionBool", ApiFlags, null, new Type[3] { _handleType, typeof(string), typeof(bool) }, null); _trySetInteractionInt = _apiType.GetMethod("TrySetInteractionInt", ApiFlags, null, new Type[3] { _handleType, typeof(string), typeof(int) }, null); _tryFireInteractionTrigger = _apiType.GetMethod("TryFireInteractionTrigger", ApiFlags, null, new Type[2] { _handleType, typeof(string) }, null); if (_tryRegisterInteractionPack == null || _tryStartInteraction == null || _tryBeginInteractionExit == null || _tryStopInteraction == null || _isInteractionActive == null || _trySetInteractionBool == null || _trySetInteractionInt == null || _tryFireInteractionTrigger == null) { reason = "required_api_methods_missing"; LogResolutionFailureOnce(reason); return false; } _typesResolved = true; return true; } catch (Exception e) { reason = "api_resolution_exception:" + Unwrap(e); LogResolutionFailureOnce(reason); return false; } } private static bool InvokeParameterMethod(MethodInfo method, object handle, string parameterName, object value) { if (handle == null || string.IsNullOrWhiteSpace(parameterName) || !_typesResolved || method == null) { return false; } try { return (bool)method.Invoke(null, new object[3] { handle, parameterName, value }); } catch { return false; } } private static void ScheduleRegistrationRetry() { _nextRegistrationRetryAt = Time.realtimeSinceStartup + 5f; } private static Type FindType(string fullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type = assemblies[i].GetType(fullName, throwOnError: false); if (type != null) { return type; } } return null; } private static void SetProperty(object target, string propertyName, object value) { PropertyInfo propertyInfo = target?.GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public); if (propertyInfo == null || !propertyInfo.CanWrite) { throw new MissingMemberException(target?.GetType().FullName, propertyName); } propertyInfo.SetValue(target, value, null); } private static string GetPluginDirectory() { string directoryName = Path.GetDirectoryName(typeof(CCTVOperatorInteractionsBridge).Assembly.Location); if (!string.IsNullOrWhiteSpace(directoryName)) { return directoryName; } return AppDomain.CurrentDomain.BaseDirectory; } private static string Unwrap(Exception e) { Exception ex = ((e is TargetInvocationException && e.InnerException != null) ? e.InnerException : e); return ex.GetType().Name + ": " + ex.Message; } private static void LogResolutionFailureOnce(string reason) { if (!_resolutionFailureLogged) { _resolutionFailureLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][ApiPort] api_unavailable reason='" + reason + "'.")); } } } private static void LogPackFailureOnce(string reason) { if (!_packFailureLogged) { _packFailureLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][ApiPort] pack_unavailable reason='" + reason + "'.")); } } } private static bool TryParseManifest(string json, out CctvOperatorManifest manifest, out string detail) { manifest = null; if (!ManifestJson.TryParseObject(json, out var value, out detail)) { return false; } manifest = new CctvOperatorManifest { interactionId = ManifestJson.ReadString(value, "interactionId"), bundleInternalName = ManifestJson.ReadString(value, "bundleInternalName") }; if (ManifestJson.TryReadObject(value, "body", out var value2)) { manifest.body = new CctvBodyManifest { enabled = ManifestJson.ReadBool(value2, "enabled"), bundleFileName = ManifestJson.ReadString(value2, "bundleFileName"), controllerAssetName = ManifestJson.ReadString(value2, "controllerAssetName") }; } if (ManifestJson.TryReadObject(value, "localViewmodel", out var value3)) { manifest.localViewmodel = new CctvLocalViewmodelManifest { bundleFileName = ManifestJson.ReadString(value3, "bundleFileName"), prefabAssetName = ManifestJson.ReadString(value3, "prefabAssetName"), controllerAssetName = ManifestJson.ReadString(value3, "controllerAssetName") }; } detail = string.Empty; return true; } private static bool ValidateWorldManifest(CctvOperatorManifest manifest, out string detail) { if (!RequireSection(manifest, "manifest", out detail)) { return false; } if (!RequireField(manifest.interactionId, "y4ngz.cctv.operator", "interactionId", ignoreCase: true, out detail)) { return false; } if (!RequireField(manifest.bundleInternalName, "y4ngzcctvplayeranimations", "bundleInternalName", ignoreCase: true, out detail)) { return false; } if (!RequireSection(manifest.body, "body", out detail)) { return false; } if (!manifest.body.enabled) { detail = "field=body.enabled expected='True' actual='False'"; return false; } if (!RequireField(manifest.body.bundleFileName, "y4ngz-cctv-playeranimations.lethalbundle", "body.bundleFileName", ignoreCase: true, out detail)) { return false; } return RequireField(manifest.body.controllerAssetName, "Y4NGZ_CCTV_PlayerMetarig", "body.controllerAssetName", ignoreCase: false, out detail); } private static bool ValidateViewmodelManifest(CctvOperatorManifest manifest, out string detail) { if (!RequireSection(manifest, "manifest", out detail)) { return false; } if (!RequireField(manifest.interactionId, "y4ngz.cctv.operator.viewmodel", "interactionId", ignoreCase: true, out detail)) { return false; } if (!RequireField(manifest.bundleInternalName, "y4ngzcctvviewmodel", "bundleInternalName", ignoreCase: true, out detail)) { return false; } if (!RequireSection(manifest.localViewmodel, "localViewmodel", out detail)) { return false; } if (!RequireField(manifest.localViewmodel.bundleFileName, "y4ngz-cctv-viewmodel.animationbundle", "localViewmodel.bundleFileName", ignoreCase: true, out detail)) { return false; } if (!RequireField(manifest.localViewmodel.prefabAssetName, "Y4NGZ_CCTV_LocalViewmodel", "localViewmodel.prefabAssetName", ignoreCase: false, out detail)) { return false; } return RequireField(manifest.localViewmodel.controllerAssetName, "Y4NGZ_CCTV_LocalViewmodel", "localViewmodel.controllerAssetName", ignoreCase: false, out detail); } private static bool RequireSection(object section, string field, out string detail) { if (section != null) { detail = string.Empty; return true; } detail = "field=" + field + " expected='object' actual=''"; return false; } private static bool RequireField(string actual, string expected, string field, bool ignoreCase, out string detail) { StringComparison comparisonType = (ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); if (string.Equals(actual, expected, comparisonType)) { detail = string.Empty; return true; } detail = "field=" + field + " expected='" + expected + "' actual='" + (actual ?? "") + "' comparison=" + (ignoreCase ? "OrdinalIgnoreCase" : "Ordinal"); return false; } } internal sealed class CCTVOperatorRuntimePose : MonoBehaviour { private const float PoseBlendInSpeed = 7.5f; private const float PoseBlendOutSpeed = 6f; private const float ButtonPressReleaseSpeed = 6f; private PlayerControllerB _player; private Animator _animator; private Transform _bodyTransform; private Vector3 _savedBodyLocalPosition; private Quaternion _savedBodyLocalRotation; private bool _savedApplyRootMotion; private bool _savedAnimatorEnabled; private bool _canDriveBodyTransform; private bool _useIkFallback; private bool _sessionActive; private bool _easingOut; private bool _cameraControlActive; private float _poseWeight; private float _buttonPressBlend; private Vector2 _joystick; private bool _loggedSetup; internal static CCTVOperatorRuntimePose Attach(PlayerControllerB player, Animator animator) { if ((Object)(object)player == (Object)null || (Object)(object)animator == (Object)null) { return null; } CCTVOperatorRuntimePose cCTVOperatorRuntimePose = ((Component)animator).GetComponent(); if ((Object)(object)cCTVOperatorRuntimePose == (Object)null) { cCTVOperatorRuntimePose = ((Component)animator).gameObject.AddComponent(); } return cCTVOperatorRuntimePose; } internal void BeginSession(PlayerControllerB player, Animator animator, bool useIkFallback) { //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_00d8: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) EndSession("replaced"); _player = player; _animator = animator; _bodyTransform = (((Object)(object)animator != (Object)null) ? ((Component)animator).transform : null); _sessionActive = (Object)(object)_player != (Object)null && (Object)(object)_animator != (Object)null; _useIkFallback = useIkFallback; _easingOut = false; _cameraControlActive = false; _poseWeight = 0f; _buttonPressBlend = 0f; _joystick = Vector2.zero; _loggedSetup = false; if (_sessionActive) { _savedAnimatorEnabled = ((Behaviour)_animator).enabled; _savedApplyRootMotion = _animator.applyRootMotion; _savedBodyLocalPosition = (((Object)(object)_bodyTransform != (Object)null) ? _bodyTransform.localPosition : Vector3.zero); _savedBodyLocalRotation = (((Object)(object)_bodyTransform != (Object)null) ? _bodyTransform.localRotation : Quaternion.identity); _canDriveBodyTransform = (Object)(object)CCTVOperatorStation.OperatorPoseAnchor != (Object)null; ((Behaviour)_animator).enabled = true; _animator.applyRootMotion = false; Tick(Vector2.zero, controllingCamera: false); } } internal void BeginEaseOut() { if (_sessionActive) { _easingOut = true; } } internal void EndSession(string reason) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!_sessionActive) { return; } if ((Object)(object)_bodyTransform != (Object)null && _canDriveBodyTransform) { try { _bodyTransform.localPosition = _savedBodyLocalPosition; _bodyTransform.localRotation = _savedBodyLocalRotation; } catch { } } if ((Object)(object)_animator != (Object)null) { try { _animator.applyRootMotion = _savedApplyRootMotion; ((Behaviour)_animator).enabled = _savedAnimatorEnabled; _animator.Update(0f); } catch { } } _player = null; _animator = null; _bodyTransform = null; _canDriveBodyTransform = false; _useIkFallback = false; _sessionActive = false; _easingOut = false; _cameraControlActive = false; _poseWeight = 0f; _buttonPressBlend = 0f; _joystick = Vector2.zero; } internal void SetCameraControl(bool active) { _cameraControlActive = active; } internal void PulseButtonPress() { if (_sessionActive) { _buttonPressBlend = 1f; } } internal void Tick(Vector2 joystick, bool controllingCamera) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (_sessionActive && !((Object)(object)_animator == (Object)null) && !((Object)(object)_player == (Object)null)) { if (_player.isPlayerDead || !_player.isPlayerControlled) { EndSession("player-invalid"); return; } _cameraControlActive = controllingCamera; _joystick = joystick; float num = Mathf.Max(Time.unscaledDeltaTime, 0.004166667f); float num2 = (_easingOut ? 0f : 1f); float num3 = ((num2 > _poseWeight) ? 7.5f : 6f); _poseWeight = Mathf.Lerp(_poseWeight, num2, 1f - Mathf.Exp((0f - num3) * num)); _buttonPressBlend = Mathf.Lerp(_buttonPressBlend, 0f, 1f - Mathf.Exp(-6f * num)); DriveBodyPose(); LogSetupOnce(); } } private void LateUpdate() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (_sessionActive) { Tick(_joystick, _cameraControlActive); } } private void OnAnimatorIK(int layerIndex) { //IL_0097: 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_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0105: 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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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) if (_sessionActive && _useIkFallback && !((Object)(object)_animator == (Object)null) && !((Object)(object)_animator.avatar == (Object)null) && _animator.avatar.isHuman) { Transform rightHandTarget = CCTVOperatorStation.RightHandTarget; Transform leftHandIdleTarget = CCTVOperatorStation.LeftHandIdleTarget; Transform leftHandPressTarget = CCTVOperatorStation.LeftHandPressTarget; Transform lookTarget = CCTVOperatorStation.LookTarget; if ((Object)(object)rightHandTarget != (Object)null) { float num = Mathf.Clamp01(_poseWeight); _animator.SetIKPositionWeight((AvatarIKGoal)3, num); _animator.SetIKRotationWeight((AvatarIKGoal)3, num); _animator.SetIKPosition((AvatarIKGoal)3, rightHandTarget.position); _animator.SetIKRotation((AvatarIKGoal)3, rightHandTarget.rotation); } if ((Object)(object)leftHandIdleTarget != (Object)null || (Object)(object)leftHandPressTarget != (Object)null) { Transform obj = (((Object)(object)leftHandIdleTarget != (Object)null) ? leftHandIdleTarget : leftHandPressTarget); Transform val = (((Object)(object)leftHandPressTarget != (Object)null) ? leftHandPressTarget : leftHandIdleTarget); float num2 = Mathf.Clamp01(_buttonPressBlend); Vector3 val2 = Vector3.Lerp(obj.position, val.position, num2); Quaternion val3 = Quaternion.Slerp(obj.rotation, val.rotation, num2); float num3 = Mathf.Clamp01(_poseWeight * 0.92f); _animator.SetIKPositionWeight((AvatarIKGoal)2, num3); _animator.SetIKRotationWeight((AvatarIKGoal)2, num3); _animator.SetIKPosition((AvatarIKGoal)2, val2); _animator.SetIKRotation((AvatarIKGoal)2, val3); } if ((Object)(object)lookTarget != (Object)null) { _animator.SetLookAtWeight(Mathf.Clamp01(_poseWeight) * 0.45f, 0.08f, 0.42f, 0f, 0.55f); _animator.SetLookAtPosition(lookTarget.position); } } } private void DriveBodyPose() { //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_003d: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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) if (!_canDriveBodyTransform || (Object)(object)_bodyTransform == (Object)null) { return; } Transform operatorPoseAnchor = CCTVOperatorStation.OperatorPoseAnchor; Transform parent = _bodyTransform.parent; if (!((Object)(object)operatorPoseAnchor == (Object)null)) { Vector3 val = (((Object)(object)parent != (Object)null) ? parent.TransformPoint(_savedBodyLocalPosition) : _savedBodyLocalPosition); Quaternion val2 = (((Object)(object)parent != (Object)null) ? (parent.rotation * _savedBodyLocalRotation) : _savedBodyLocalRotation); Vector3 position = operatorPoseAnchor.position; Quaternion val3 = operatorPoseAnchor.rotation; if (!_useIkFallback) { position.y = val.y; val3 = val2; } _bodyTransform.SetPositionAndRotation(Vector3.Lerp(val, position, _poseWeight), Quaternion.Slerp(val2, val3, _poseWeight)); } } private void LogSetupOnce() { if (!_loggedSetup) { _loggedSetup = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV] Operator pose driver active: bodyDrive={_canDriveBodyTransform}, " + string.Format("ikFallback={0} (authored controller {1}).", _useIkFallback, (!_useIkFallback) ? "in use" : "missing"))); } } } private void OnDestroy() { EndSession("component-destroyed"); } } internal static class CCTVOperatorStation { private sealed class ControlGeometryCandidate { internal Transform Transform; internal string Path; internal Bounds Bounds; internal float CenterDistance; internal float ClosestDistance; internal float MaxAxis; internal string Source; } [Serializable] internal sealed class StationPlacementProfile { public List placements = new List(); } [Serializable] internal sealed class StationPlacementRecord { public string target; public Vector3 localPosition; public Vector3 localEuler; public Vector3 localScale; } private static bool _focusAnchorAimApplied; private static bool _radarAimRejectionLogged; private static MeshRenderer _radarScreenRenderer; private static Vector3 _radarScreenCenterLocal; private static bool _radarScreenCenterResolved; private const float RadarScreenCenterRetryIntervalSeconds = 3f; private static float _nextRadarScreenCenterResolveAt; private const float RadarAimMaxAngleFromFocusDeg = 60f; private const string RootName = "LethalCCTV_VanillaOperatorStation"; private const string MonitorWallPath = "Environment/HangarShip/ShipModels2b/MonitorWall"; private const string LowerRightMonitorPath = "Environment/HangarShip/ShipModels2b/MonitorWall/SingleScreen"; private const float StationDistanceFromMonitor = 1.28f; private const float StationDropFromTopMonitor = 3.18f; private const float StationSlotOffsetFromDeadline = 1.45f; private const string StationPropsBundleFile = "y4ngz-cctv-stationprops.stationbundle"; private const string StationPropsBundleName = "y4ngz-cctv-stationprops"; private const string AccessButtonPressClipAssetName = "Y4NGZ_CCTV_ButtonPress"; private static readonly Vector3 AccessButtonLocalPosition = new Vector3(0.489f, 1.089f, 1.025f); private static readonly Vector3 AccessButtonLocalEuler = new Vector3(270f, 0.3f, 0f); private static readonly Vector3 AccessButtonLocalScale = new Vector3(0.487f, 0.487f, 0.487f); private static readonly Vector3 NoteLocalPosition = new Vector3(1.33f, 2.53f, 1.37f); private static readonly Vector3 NoteLocalEuler = new Vector3(351.47f, 263.85f, 0f); private static readonly Vector3 NoteLocalScale = Vector3.one * 0.104262345f; private const float BrakeLeverCardinalTiltDeg = 14f; private const float JoystickIdleAfterSeconds = 0.16f; private const float JoystickRestEpsilonSqr = 1E-05f; private static readonly Vector3 FocusLocalPosition = new Vector3(-0.011f, 1.817f, 0.552f); private static readonly Vector3 FocusLocalEuler = new Vector3(7.16f, 71.26f, 349.43f); private static readonly Vector3 RadarFocusLocalPosition = FocusLocalPosition; private static readonly Vector3 RadarFocusLocalEuler = new Vector3(358.49f, 133.75f, 342.72f); private static readonly Vector3 OperatorPoseLocalPosition = new Vector3(0.04f, 1.12f, 0.56f); private static readonly Vector3 OperatorPoseLocalEuler = new Vector3(0f, 87f, 0f); private static readonly Vector3 PlayerRootLocalPosition = new Vector3(OperatorPoseLocalPosition.x, 0f, OperatorPoseLocalPosition.z); private static readonly Vector3 PlayerRootLocalEuler = OperatorPoseLocalEuler; private const float DefaultThrottleLeftOffsetMeters = 0.72f; private const float ThrottleNearbyTransformRadius = 1.5f; private const float ThrottleNearbyRendererCenterRadius = 1.1f; private const float ThrottleNearbyRendererClosestRadius = 0.65f; private const float ThrottleNearbyRendererMaxAxis = 1.3f; private const float ThrottleNearbyRendererMaxVerticalDelta = 0.95f; private const float ThrottleRendererCandidateDumpRadius = 1.8f; private const float ControlGeometryCandidateRadius = 2.25f; private const int ControlGeometryRendererDumpLimit = 60; private const int ControlGeometryColliderDumpLimit = 40; private static GameObject _root; private static Transform _focusViewAnchor; private static Transform _radarViewAnchor; private static Transform _playerRootAnchor; private static Transform _operatorPoseAnchor; private static Transform _noteAnchor; private static CCTVStationPlacementEditor _placementEditor; private static float _nextProbeAt; private static float _debugStationSpawnUntil; private static AssetBundle _stationPropsBundle; private static bool _stationPropsBundleLoadAttempted; private static bool _warnedStationPropsBundleMissing; private static bool _defaultThrottlePlacementCaptured; private static Vector3 _defaultThrottleLocalPosition; private static Vector3 _defaultThrottleLocalEuler; private static Vector3 _defaultThrottleLocalScale; private static Vector3 _defaultThrottleWorldPosition; private static Quaternion _defaultThrottleWorldRotation; private static Vector3 _defaultThrottleWorldScale; private static Transform _throttleTransform; private static readonly List _throttleSecondaryTargets = new List(); private static readonly List _throttleSecondaryDefaultWorld = new List(); private static readonly List _throttleSecondaryDefaultWorldRotations = new List(); private static readonly List _throttleSecondaryDefaultLocalScales = new List(); private static bool _throttleHierarchyDumped; private static bool _throttleRendererCandidatesDumped; private static bool _stationEventsSubscribed; private static Transform _joystickTiltPivot; private static Transform _rightHandTarget; private static Transform _leftHandIdleTarget; private static Transform _leftHandPressTarget; private static Transform _lookTarget; private static Quaternion _joystickTiltBaseLocalRotation = Quaternion.identity; private static Vector3 _joystickTiltNeutralLocalAxis = Vector3.up; private static readonly CCTVJoystickPhaseDriver _joystickPhase = new CCTVJoystickPhaseDriver(); private static float _lastJoystickMoveAt; private static bool _joystickCameraControlActive; private static float _nextBrakeLeverControlResolveAt; private static readonly float[] BrakeLeverResolveBackoffSeconds = new float[3] { 1f, 5f, 15f }; private static int _brakeLeverResolveFailures; private const float FocusAnchorAimIntervalSeconds = 5f; private static float _nextFocusAnchorAimAt; private static bool _warnedBrakeLeverControlMissing; private static bool _loggedBrakeLeverControlRig; private static string _rightHandGripSource = "unresolved"; private static bool _controlGeometryDumpedOnEnter; private static AudioClip _accessButtonPressClip; private static bool _accessButtonPressClipLoadAttempted; private static Transform _monitorWallCache; private static int _pendingWarmupStep; private static StationPlacementProfile _placementProfile; private static bool _placementProfileLoaded; internal static bool IsReady => (Object)(object)_root != (Object)null; internal static Transform FocusViewAnchor => _focusViewAnchor; internal static Transform RadarViewAnchor => _radarViewAnchor; internal static Transform PlayerRootAnchor { get { if (!((Object)(object)_playerRootAnchor != (Object)null)) { return _operatorPoseAnchor; } return _playerRootAnchor; } } internal static Transform OperatorPoseAnchor => _operatorPoseAnchor; internal static Transform NoteAnchor => _noteAnchor; internal static Transform JoystickTiltPivot => _joystickTiltPivot; internal static Transform RightHandTarget => _rightHandTarget; internal static Transform LeftHandIdleTarget => _leftHandIdleTarget; internal static Transform LeftHandPressTarget => _leftHandPressTarget; internal static Transform LookTarget => _lookTarget; internal static bool IsDebugPlacementActive { get { if (_placementEditor != null) { return _placementEditor.IsActive; } return false; } } private static string PlacementProfilePath => Y4NGZCompanyPaths.LocalDataFile("cctv-station-placements.local.json"); internal static bool TryResolveLeverGripPoint(out Vector3 point, out string source) { //IL_003e: 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_0029: 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) EnsureBrakeLeverControlRig(); Transform val = (((Object)(object)_rightHandTarget != (Object)null) ? _rightHandTarget : _joystickTiltPivot); if ((Object)(object)val == (Object)null) { point = Vector3.zero; source = "unresolved"; return false; } point = val.position; source = (((Object)(object)_rightHandTarget != (Object)null) ? _rightHandGripSource : "lever-pivot-fallback"); return true; } internal static bool TryResolveRadarMonitorScreenCenter(out Vector3 center) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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) if (_radarScreenCenterResolved && (Object)(object)_radarScreenRenderer != (Object)null && !HasRadarScreenSurfaceMoved()) { center = ((Component)_radarScreenRenderer).transform.TransformPoint(_radarScreenCenterLocal); return true; } center = Vector3.zero; if (Time.unscaledTime < _nextRadarScreenCenterResolveAt) { return false; } _nextRadarScreenCenterResolveAt = Time.unscaledTime + 3f; _radarScreenCenterResolved = false; if (!TryResolveRadarMonitorSurface(out _radarScreenRenderer, out var materialIndex, out var generalImprovementsScreen) || (Object)(object)_radarScreenRenderer == (Object)null) { _radarScreenRenderer = null; return false; } if (!TryResolveRadarMonitorScreenCenterUncached(_radarScreenRenderer, materialIndex, generalImprovementsScreen, out center)) { return false; } _radarScreenCenterLocal = ((Component)_radarScreenRenderer).transform.InverseTransformPoint(center); _radarScreenCenterResolved = true; return true; } private static bool HasRadarScreenSurfaceMoved() { if (!CCTVVanillaMonitorDisplay.TryGetBoundRadarScreen(out var renderer, out var _, out var generalImprovementsScreen)) { return false; } if (generalImprovementsScreen && (Object)(object)renderer != (Object)null) { return (Object)(object)renderer != (Object)(object)_radarScreenRenderer; } return false; } private static bool TryResolveRadarMonitorScreenCenterUncached(MeshRenderer renderer, int materialIndex, bool generalImprovementsScreen, out Vector3 center) { //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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) //IL_0053: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) center = Vector3.zero; if ((Object)(object)renderer == (Object)null) { return false; } if (TryResolveScreenFaceBounds(renderer, materialIndex, generalImprovementsScreen, out var bounds)) { center = ((Bounds)(ref bounds)).center; if (IsPlausibleShipWorldPoint(center)) { return true; } } Bounds bounds2 = ((Renderer)renderer).bounds; center = ((Bounds)(ref bounds2)).center; return IsPlausibleShipWorldPoint(center); } private static int ResolveRadarMonitorMaterialIndex(MeshRenderer renderer) { if ((Object)(object)renderer == (Object)null) { return -1; } try { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return -1; } int num = ((((Renderer)renderer).sharedMaterials != null) ? ((Renderer)renderer).sharedMaterials.Length : 0); ManualCameraRenderer[] array = (ManualCameraRenderer[])(object)new ManualCameraRenderer[2] { instance.insideCameraScreen, instance.securityCameraScreen }; foreach (ManualCameraRenderer val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.mesh != (Object)(object)renderer) && val.materialIndex >= 0 && val.materialIndex < num) { return val.materialIndex; } } } catch { } return -1; } private static void CreateAnchors(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //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_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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_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_00a3: 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_00b3: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("CCTVStationFocusViewAnchor"); val.transform.SetParent(parent, false); val.transform.localPosition = FocusLocalPosition; val.transform.localRotation = Quaternion.Euler(FocusLocalEuler); _focusViewAnchor = val.transform; GameObject val2 = new GameObject("CCTVStationRadarViewAnchor"); val2.transform.SetParent(parent, false); val2.transform.localPosition = RadarFocusLocalPosition; val2.transform.localRotation = Quaternion.Euler(RadarFocusLocalEuler); _radarViewAnchor = val2.transform; GameObject val3 = new GameObject("CCTVStationPlayerRootAnchor"); val3.transform.SetParent(parent, false); val3.transform.localPosition = PlayerRootLocalPosition; val3.transform.localRotation = Quaternion.Euler(PlayerRootLocalEuler); _playerRootAnchor = val3.transform; GameObject val4 = new GameObject("CCTVStationOperatorPoseAnchor"); val4.transform.SetParent(parent, false); val4.transform.localPosition = OperatorPoseLocalPosition; val4.transform.localRotation = Quaternion.Euler(OperatorPoseLocalEuler); _operatorPoseAnchor = val4.transform; EnsureNoteAnchor(); _focusAnchorAimApplied = false; } internal static Transform EnsureNoteAnchor() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null) { return null; } if ((Object)(object)_noteAnchor == (Object)null) { GameObject val = new GameObject("CCTVStationNoteAnchor"); val.transform.SetParent(_root.transform, false); _noteAnchor = val.transform; ApplyNotePlacement(_noteAnchor); } return _noteAnchor; } internal static void EnsureFocusAnchorAimed(bool force = false) { if (!((Object)(object)_root == (Object)null) && !((Object)(object)_focusViewAnchor == (Object)null)) { _focusAnchorAimApplied = true; EnsureRadarAnchorAimed(force); } } internal static bool ShouldUseExactStationFocusPose(Transform anchor) { if ((Object)(object)anchor == (Object)null) { return false; } if ((Object)(object)anchor == (Object)(object)_focusViewAnchor) { return true; } if ((Object)(object)anchor == (Object)(object)_radarViewAnchor) { return true; } return false; } internal static void EnsureRadarAnchorAimed(bool force = false) { if (!((Object)(object)_radarViewAnchor == (Object)null) && !((Object)(object)_focusViewAnchor == (Object)null) && !IsEditingDebugPlacement("radar") && !HasSavedPlacement("radar") && (force || _focusAnchorAimApplied)) { AimRadarAnchorFromFocusDefault(); } } private static void AimRadarAnchorFromFocusDefault() { //IL_003e: 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) //IL_0061: 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_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_00ce: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_0199: 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_016b: 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) if ((Object)(object)_radarViewAnchor == (Object)null || (Object)(object)_focusViewAnchor == (Object)null || HasSavedPlacement("radar") || IsEditingDebugPlacement("radar")) { return; } _radarViewAnchor.position = _focusViewAnchor.position; _radarViewAnchor.localScale = Vector3.one; _radarViewAnchor.rotation = _focusViewAnchor.rotation * Quaternion.Euler(RadarFocusLocalEuler.x - FocusLocalEuler.x, RadarFocusLocalEuler.y - FocusLocalEuler.y, RadarFocusLocalEuler.z - FocusLocalEuler.z); if (!TryResolveRadarMonitorScreenCenter(out var center)) { return; } Vector3 val = _focusViewAnchor.position; Vector3 val2 = _focusViewAnchor.forward; if (MonitorFocus.TryGetStationFocusPresentationEye(out var position, out var rotation)) { val = position; val2 = rotation * Vector3.forward; } Vector3 val3 = center - val; if (((Vector3)(ref val3)).sqrMagnitude <= 0.0001f || ((Vector3)(ref val2)).sqrMagnitude <= 0.0001f) { return; } ((Vector3)(ref val3)).Normalize(); float num = Vector3.Angle(((Vector3)(ref val2)).normalized, val3); if (num > 60f) { if (!_radarAimRejectionLogged) { _radarAimRejectionLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogMessage((object)($"[LethalCCTV][RadarAim] rejected screen-center aim {num:0.0}deg off the CCTV view " + $"(bound={60f:0}deg center={FormatVector(center)} eye={FormatVector(val)}); " + "holding the authored offset. Author one with F1 > 6 to override.")); } } } else { _radarAimRejectionLogged = false; _radarViewAnchor.rotation = Quaternion.LookRotation(val3, Vector3.up); } } private static Vector3 ResolveMainMonitorInward(Vector3 screenCenter) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) Vector3 result = Vector3.zero; if ((Object)(object)_root != (Object)null) { result = _root.transform.position - screenCenter; result.y = 0f; if (((Vector3)(ref result)).sqrMagnitude >= 0.0001f) { return result; } } try { StartOfRound instance = StartOfRound.Instance; RectTransform val = (((Object)(object)instance != (Object)null && (Object)(object)instance.screenLevelDescription != (Object)null) ? ((TMP_Text)instance.screenLevelDescription).rectTransform : null); RectTransform val2 = (RectTransform)(((Object)(object)val != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); RectTransform val3 = (((Object)(object)val2 != (Object)null) ? val2 : val); if ((Object)(object)val3 != (Object)null) { result = ResolveInteriorDirection(ResolveShipTransform(), screenCenter, ((Transform)val3).forward); result.y = 0f; if (((Vector3)(ref result)).sqrMagnitude >= 0.0001f) { return result; } } } catch { } Transform val4 = ResolveShipTransform(); result = (((Object)(object)val4 != (Object)null) ? (val4.position - screenCenter) : Vector3.back); result.y = 0f; return result; } internal static bool TryResolveMainMonitorScreenFrame(out Vector3 center, out Vector3 normal, out Vector3 right, out Vector3 up, out float halfWidth, out float halfHeight) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_0126: 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_0133: 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_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) center = Vector3.zero; normal = Vector3.zero; right = Vector3.right; up = Vector3.up; halfWidth = 0f; halfHeight = 0f; if (TryResolveMainMonitorSurface(out var renderer, out var materialIndex, out var generalImprovementsScreen) && (Object)(object)renderer != (Object)null && TryResolveScreenFaceBounds(renderer, materialIndex, generalImprovementsScreen, out var bounds)) { center = ((Bounds)(ref bounds)).center; if (IsPlausibleShipWorldPoint(center) && TryBuildScreenFrameFromBounds(bounds, center, out normal, out right, out up, out halfWidth, out halfHeight)) { return true; } } if (IsGeneralImprovementsWallVisible()) { return false; } try { StartOfRound instance = StartOfRound.Instance; RectTransform val = (((Object)(object)instance != (Object)null && (Object)(object)instance.screenLevelDescription != (Object)null) ? ((TMP_Text)instance.screenLevelDescription).rectTransform : null); RectTransform val2 = (RectTransform)(((Object)(object)val != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); RectTransform val3 = (((Object)(object)val2 != (Object)null) ? val2 : val); if ((Object)(object)val3 != (Object)null) { Vector3[] array = (Vector3[])(object)new Vector3[4]; val3.GetWorldCorners(array); center = (array[0] + array[1] + array[2] + array[3]) * 0.25f; if (IsPlausibleShipWorldPoint(center) && TryBuildScreenFrameFromCorners(array, center, ((Transform)val3).forward, ((Transform)val3).right, ((Transform)val3).up, out normal, out right, out up, out halfWidth, out halfHeight)) { return true; } } } catch { } return false; } private static bool TryBuildScreenFrameFromBounds(Bounds bounds, Vector3 center, out Vector3 normal, out Vector3 right, out Vector3 up, out float halfWidth, out float halfHeight) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011d: 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_0127: 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_012d: 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_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) normal = ResolveMainMonitorInward(center); if (((Vector3)(ref normal)).sqrMagnitude < 0.0001f) { right = Vector3.right; up = Vector3.up; halfWidth = 0f; halfHeight = 0f; return false; } ((Vector3)(ref normal)).Normalize(); right = Vector3.Cross(Vector3.up, normal); if (((Vector3)(ref right)).sqrMagnitude < 0.0001f) { right = Vector3.Cross(Vector3.forward, normal); } if (((Vector3)(ref right)).sqrMagnitude < 0.0001f) { right = Vector3.right; } ((Vector3)(ref right)).Normalize(); up = Vector3.Cross(normal, right); if (((Vector3)(ref up)).sqrMagnitude < 0.0001f) { up = Vector3.up; } else { ((Vector3)(ref up)).Normalize(); } Vector3 extents = ((Bounds)(ref bounds)).extents; halfWidth = 0f; halfHeight = 0f; for (int i = -1; i <= 1; i += 2) { for (int j = -1; j <= 1; j += 2) { for (int k = -1; k <= 1; k += 2) { Vector3 val = center + new Vector3(extents.x * (float)i, extents.y * (float)j, extents.z * (float)k) - center; halfWidth = Mathf.Max(halfWidth, Mathf.Abs(Vector3.Dot(val, right))); halfHeight = Mathf.Max(halfHeight, Mathf.Abs(Vector3.Dot(val, up))); } } } if (halfWidth > 0.1f) { return halfHeight > 0.08f; } return false; } private static bool TryBuildScreenFrameFromCorners(Vector3[] corners, Vector3 center, Vector3 candidateNormal, Vector3 candidateRight, Vector3 candidateUp, out Vector3 normal, out Vector3 right, out Vector3 up, out float halfWidth, out float halfHeight) { //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) //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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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) //IL_009d: 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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_00fb: 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_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_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) normal = ResolveInteriorDirection(ResolveShipTransform(), center, candidateNormal); if (((Vector3)(ref normal)).sqrMagnitude < 0.0001f) { normal = ResolveMainMonitorInward(center); } if (((Vector3)(ref normal)).sqrMagnitude < 0.0001f) { right = Vector3.right; up = Vector3.up; halfWidth = 0f; halfHeight = 0f; return false; } ((Vector3)(ref normal)).Normalize(); right = Vector3.ProjectOnPlane(candidateRight, normal); if (((Vector3)(ref right)).sqrMagnitude < 0.0001f) { right = Vector3.Cross(Vector3.up, normal); } if (((Vector3)(ref right)).sqrMagnitude < 0.0001f) { right = Vector3.right; } ((Vector3)(ref right)).Normalize(); up = Vector3.ProjectOnPlane(candidateUp, normal); if (((Vector3)(ref up)).sqrMagnitude < 0.0001f) { up = Vector3.Cross(normal, right); } if (((Vector3)(ref up)).sqrMagnitude < 0.0001f) { up = Vector3.up; } ((Vector3)(ref up)).Normalize(); halfWidth = 0f; halfHeight = 0f; int num = 0; while (corners != null && num < corners.Length) { Vector3 val = corners[num] - center; halfWidth = Mathf.Max(halfWidth, Mathf.Abs(Vector3.Dot(val, right))); halfHeight = Mathf.Max(halfHeight, Mathf.Abs(Vector3.Dot(val, up))); num++; } if (halfWidth > 0.1f) { return halfHeight > 0.08f; } return false; } private static bool TryResolveMainMonitorSurface(out MeshRenderer renderer, out int materialIndex, out bool generalImprovementsScreen) { if ((CCTVVanillaMonitorDisplay.TryGetBoundFeedScreen(out renderer, out materialIndex, out generalImprovementsScreen) & generalImprovementsScreen) && (Object)(object)renderer != (Object)null) { return true; } generalImprovementsScreen = false; if (IsGeneralImprovementsWallVisible()) { renderer = null; materialIndex = -1; return false; } renderer = TryResolveLowerLeftMonitorRenderer(); if ((Object)(object)renderer == (Object)null) { materialIndex = -1; return false; } materialIndex = ResolveLowerLeftMonitorMaterialIndex(renderer); return true; } private static bool TryResolveRadarMonitorSurface(out MeshRenderer renderer, out int materialIndex, out bool generalImprovementsScreen) { if ((CCTVVanillaMonitorDisplay.TryGetBoundRadarScreen(out renderer, out materialIndex, out generalImprovementsScreen) & generalImprovementsScreen) && (Object)(object)renderer != (Object)null) { return true; } generalImprovementsScreen = false; if (IsGeneralImprovementsWallVisible()) { renderer = null; materialIndex = -1; return false; } renderer = TryResolveLowerRightMonitorRenderer(); if ((Object)(object)renderer == (Object)null) { materialIndex = -1; return false; } materialIndex = ResolveRadarMonitorMaterialIndex(renderer); return true; } private static bool IsGeneralImprovementsWallVisible() { if (GeneralImprovementsMonitorCompat.IsLoaded) { return GeneralImprovementsMonitorCompat.AreBetterMonitorsActive(); } return false; } private static bool TryResolveScreenFaceBounds(MeshRenderer renderer, int materialIndex, bool allowWholeMeshBounds, out Bounds bounds) { //IL_0001: 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) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) bounds = default(Bounds); if ((Object)(object)renderer == (Object)null) { return false; } int num; try { num = ((((Renderer)renderer).sharedMaterials != null) ? ((Renderer)renderer).sharedMaterials.Length : 0); } catch { num = 0; } if (num > 1 && materialIndex >= 0 && materialIndex < num && TryResolveRendererSubmeshBounds(renderer, materialIndex, out bounds)) { return true; } if (!allowWholeMeshBounds) { return false; } bounds = ((Renderer)renderer).bounds; Vector3 size = ((Bounds)(ref bounds)).size; return ((Vector3)(ref size)).sqrMagnitude > 1E-06f; } private static MeshRenderer TryResolveLowerLeftMonitorRenderer() { try { Transform val = (((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.elevatorTransform != (Object)null) ? StartOfRound.Instance.elevatorTransform.Find("ShipModels2b/MonitorWall/Cube.001") : null); if ((Object)(object)val != (Object)null) { MeshRenderer component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { return component; } } } catch { } GameObject val2 = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube.001"); if (!((Object)(object)val2 != (Object)null)) { return null; } return val2.GetComponent(); } private static MeshRenderer TryResolveLowerRightMonitorRenderer() { GameObject val = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/SingleScreen"); MeshRenderer val2 = (((Object)(object)val != (Object)null) ? val.GetComponent() : null); if ((Object)(object)val2 != (Object)null) { return val2; } Transform val3 = (((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.elevatorTransform != (Object)null) ? StartOfRound.Instance.elevatorTransform.Find("ShipModels2b/MonitorWall/SingleScreen") : null); if ((Object)(object)val3 != (Object)null) { MeshRenderer component = ((Component)val3).GetComponent(); if ((Object)(object)component != (Object)null) { return component; } } StartOfRound instance = StartOfRound.Instance; MeshRenderer val4 = MonitorWallScreenOrNull(((Object)(object)instance != (Object)null) ? instance.insideCameraScreen : null); if ((Object)(object)val4 != (Object)null) { return val4; } return MonitorWallScreenOrNull(((Object)(object)instance != (Object)null) ? instance.securityCameraScreen : null); } private static MeshRenderer MonitorWallScreenOrNull(ManualCameraRenderer driver) { MeshRenderer val = (((Object)(object)driver != (Object)null) ? driver.mesh : null); if ((Object)(object)val == (Object)null) { return null; } MeshRenderer val2 = TryResolveLowerLeftMonitorRenderer(); if ((Object)(object)val == (Object)(object)val2) { return null; } string text = ((Object)((Component)val).gameObject).name ?? string.Empty; if (text.IndexOf("Button", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Door", StringComparison.OrdinalIgnoreCase) >= 0) { return null; } if (!IsUnderMonitorWall(((Component)val).transform)) { return null; } return val; } private static bool IsUnderMonitorWall(Transform transform) { Transform val = (((Object)(object)transform != (Object)null) ? transform.parent : null); while ((Object)(object)val != (Object)null) { if (string.Equals(((Object)val).name, "MonitorWall", StringComparison.Ordinal)) { return true; } val = val.parent; } return false; } private static int ResolveLowerLeftMonitorMaterialIndex(MeshRenderer renderer) { int num; try { num = (((Object)(object)renderer != (Object)null && ((Renderer)renderer).sharedMaterials != null) ? ((Renderer)renderer).sharedMaterials.Length : 0); } catch { num = 0; } try { StartOfRound instance = StartOfRound.Instance; ManualCameraRenderer val = (((Object)(object)instance != (Object)null) ? instance.mapScreen : null); if ((Object)(object)val != (Object)null && (Object)(object)val.mesh == (Object)(object)renderer && val.materialIndex >= 0 && val.materialIndex < num) { return val.materialIndex; } } catch { } if (num <= 1) { return -1; } return 1; } private static bool TryResolveRendererSubmeshBounds(MeshRenderer renderer, int materialIndex, out Bounds bounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); if ((Object)(object)renderer == (Object)null || materialIndex < 0) { return false; } MeshFilter component = ((Component)renderer).GetComponent(); Mesh val = (((Object)(object)component != (Object)null) ? component.sharedMesh : null); if ((Object)(object)val == (Object)null || materialIndex >= val.subMeshCount) { return false; } if (!val.isReadable) { return false; } int[] indices; try { indices = val.GetIndices(materialIndex); } catch { return false; } Vector3[] vertices = val.vertices; if (indices == null || indices.Length == 0 || vertices == null || vertices.Length == 0) { return false; } bool flag = false; Transform transform = ((Component)renderer).transform; foreach (int num in indices) { if (num >= 0 && num < vertices.Length) { Vector3 val2 = transform.TransformPoint(vertices[num]); if (!flag) { bounds = new Bounds(val2, Vector3.zero); flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val2); } } } return flag; } private static bool IsPlausibleShipWorldPoint(Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_008c: Unknown result type (might be due to invalid IL or missing references) if (float.IsNaN(point.x) || float.IsNaN(point.y) || float.IsNaN(point.z) || float.IsInfinity(point.x) || float.IsInfinity(point.y) || float.IsInfinity(point.z)) { return false; } Transform val = ResolveShipTransform(); if ((Object)(object)val != (Object)null && Mathf.Abs(point.y - val.position.y) > 12f) { return false; } if (point.y > -10f) { return point.y < 25f; } return false; } private static bool TryResolveStationPose(out Transform ship, out Vector3 worldPosition, out Quaternion worldRotation, out string source) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0241: 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_024d: 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_025c: 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_0266: 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_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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_00e8: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_012b: 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_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_0148: 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_0152: 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_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_011c: 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) ship = ResolveShipTransform(); worldPosition = Vector3.zero; worldRotation = Quaternion.identity; source = "unresolved"; if ((Object)(object)ship == (Object)null) { return false; } StartOfRound instance = StartOfRound.Instance; RectTransform val = (((Object)(object)instance != (Object)null && (Object)(object)instance.profitQuotaMonitorBGImage != (Object)null) ? ((Graphic)instance.profitQuotaMonitorBGImage).rectTransform : null); RectTransform val2 = (((Object)(object)instance != (Object)null && (Object)(object)instance.deadlineMonitorBGImage != (Object)null) ? ((Graphic)instance.deadlineMonitorBGImage).rectTransform : null); if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null) { Vector3 val3 = ((Transform)val2).position - ((Transform)val).position; if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { val3 = ((Transform)val2).right * 0.75f; } Vector3 val4 = ((Transform)val).position + val3 * 1.45f; Vector3 val5 = ResolveInteriorDirection(ship, val4, ((Transform)val2).forward); Vector3 val6 = -val5; val6.y = 0f; if (((Vector3)(ref val6)).sqrMagnitude < 0.0001f) { val6 = ship.forward; } ((Vector3)(ref val6)).Normalize(); worldPosition = val4 + val5 * 1.28f + Vector3.down * 3.18f; worldRotation = Quaternion.LookRotation(val6, Vector3.up) * Quaternion.Euler(0f, -90f, 0f); source = "top-monitor-ui monitorTarget=" + FormatVector(val4) + " inward=" + FormatVector(val5) + " profitWorld=" + FormatVector(((Transform)val).position) + " deadlineWorld=" + FormatVector(((Transform)val2).position); return true; } Transform val7 = ResolveMonitorWall(); if ((Object)(object)val7 == (Object)null) { return false; } Vector3 position = val7.position; Vector3 val8 = ResolveInteriorDirection(ship, position, val7.forward); Vector3 val9 = -val8; val9.y = 0f; if (((Vector3)(ref val9)).sqrMagnitude < 0.0001f) { val9 = ship.forward; } ((Vector3)(ref val9)).Normalize(); worldPosition = position + val8 * 1.28f + Vector3.down * 1.2f; worldRotation = Quaternion.LookRotation(val9, Vector3.up) * Quaternion.Euler(0f, -90f, 0f); source = "monitor-wall-fallback monitorWallWorld=" + FormatVector(position) + " inward=" + FormatVector(val8); return true; } private static Vector3 ResolveInteriorDirection(Transform ship, Vector3 monitorTarget, Vector3 candidateNormal) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0075: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_006b: Unknown result type (might be due to invalid IL or missing references) Vector3 val = candidateNormal; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = ship.forward; } val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.forward; } ((Vector3)(ref val)).Normalize(); Vector3 position = ship.position; try { ShipTeleporter val2 = Object.FindObjectOfType(); if ((Object)(object)val2 != (Object)null) { position = ((Component)val2).transform.position; } } catch { position = ship.position; } Vector3 val3 = position - monitorTarget; val3.y = 0f; if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { return val; } if (!(Vector3.Dot(val3, val) >= 0f)) { return -val; } return val; } private static Transform ResolveShipTransform() { if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.elevatorTransform != (Object)null) { return StartOfRound.Instance.elevatorTransform; } GameObject val = GameObject.Find("Environment/HangarShip"); if (!((Object)(object)val != (Object)null)) { return null; } return val.transform; } private static Transform ResolveMonitorWall() { if ((Object)(object)_monitorWallCache != (Object)null) { return _monitorWallCache; } Transform val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.elevatorTransform : null); Transform val2 = (((Object)(object)val != (Object)null) ? val.Find("ShipModels2b/MonitorWall") : null); if ((Object)(object)val2 == (Object)null) { GameObject obj = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall"); val2 = ((obj != null) ? obj.transform : null); } _monitorWallCache = val2; return val2; } internal static void Ensure() { Ensure(allowUnpurchasedForDebug: false); } private static void Ensure(bool allowUnpurchasedForDebug) { //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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) EnsureStationEventSubscriptions(); if ((Object)(object)_root != (Object)null) { Scene scene = _root.scene; if (((Scene)(ref scene)).IsValid() && _root.activeInHierarchy) { if (!allowUnpurchasedForDebug && !CCTVTerminalUnlockable.IsPurchased() && !IsDebugStationSpawnActive()) { Shutdown(); return; } RunPendingWarmupStep(); CCTVAccessButton.Ensure(_root.transform); return; } Shutdown(); } if ((!allowUnpurchasedForDebug && !CCTVTerminalUnlockable.IsPurchased()) || Time.unscaledTime < _nextProbeAt) { return; } _nextProbeAt = Time.unscaledTime + 1f; long timestamp = Stopwatch.GetTimestamp(); if (TryResolveStationPose(out var ship, out var worldPosition, out var worldRotation, out var source) && !((Object)(object)ResolveMonitorWall() == (Object)null)) { double num = TicksToMs(Stopwatch.GetTimestamp() - timestamp); _root = new GameObject("LethalCCTV_VanillaOperatorStation"); _root.transform.SetParent(ship, true); _root.transform.SetPositionAndRotation(worldPosition, worldRotation); _root.transform.localScale = Vector3.one; EnsureStationEventSubscriptions(); timestamp = Stopwatch.GetTimestamp(); CreateAnchors(_root.transform); ApplySavedStationPlacements(); EnsureFocusAnchorAimed(); double num2 = TicksToMs(Stopwatch.GetTimestamp() - timestamp); timestamp = Stopwatch.GetTimestamp(); ConfigureBrakeLeverControlRig(); CCTVAccessButton.Ensure(_root.transform); double num3 = TicksToMs(Stopwatch.GetTimestamp() - timestamp); _pendingWarmupStep = 1; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)($"[LethalCCTV.Timing] station spawn pass split: pose={num:F1}ms anchors={num2:F1}ms " + $"controlRig={num3:F1}ms; warmups deferred to the next frames (#280).")); } ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] Vanilla CCTV standing operator station spawned from " + source + ". rootWorld=" + FormatVector(_root.transform.position) + " rootLocal=" + FormatVector(_root.transform.localPosition) + " rootEuler=" + FormatVector(_root.transform.eulerAngles) + " control=" + GetPath(_joystickTiltPivot) + " interactTarget=vanilla-red-monitor-button.")); } } } private static void RunPendingWarmupStep() { if (_pendingWarmupStep != 0) { int pendingWarmupStep = _pendingWarmupStep; long timestamp = Stopwatch.GetTimestamp(); if (pendingWarmupStep == 1) { Y4NGZPlayerAnimationBridge.WarmUpAuthoredController(); _pendingWarmupStep = 2; } else { MonitorFocus.PrewarmFocusHudScan(); _pendingWarmupStep = 0; } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)($"[LethalCCTV.Timing] station warmup step {pendingWarmupStep} " + "(" + ((pendingWarmupStep == 1) ? "authored controller" : "focus HUD scan") + ") took " + $"{TicksToMs(Stopwatch.GetTimestamp() - timestamp):F1}ms (#280).")); } } } private static double TicksToMs(long ticks) { return (double)ticks * 1000.0 / (double)Stopwatch.Frequency; } internal static void Shutdown() { //IL_006d: 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_008d: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) ClearStationEventSubscriptions(); _placementEditor?.Cancel(); CCTVAccessButton.Shutdown(); if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _pendingWarmupStep = 0; _focusViewAnchor = null; _radarViewAnchor = null; _playerRootAnchor = null; _operatorPoseAnchor = null; _noteAnchor = null; _focusAnchorAimApplied = false; _radarAimRejectionLogged = false; _radarScreenRenderer = null; _radarScreenCenterLocal = Vector3.zero; _radarScreenCenterResolved = false; _nextRadarScreenCenterResolveAt = 0f; _defaultThrottlePlacementCaptured = false; _defaultThrottleWorldPosition = Vector3.zero; _throttleTransform = null; _throttleSecondaryTargets.Clear(); _throttleSecondaryDefaultWorld.Clear(); _throttleSecondaryDefaultWorldRotations.Clear(); _throttleSecondaryDefaultLocalScales.Clear(); _throttleHierarchyDumped = false; _throttleRendererCandidatesDumped = false; _joystickTiltPivot = null; _rightHandTarget = null; _leftHandIdleTarget = null; _leftHandPressTarget = null; _lookTarget = null; _joystickTiltBaseLocalRotation = Quaternion.identity; _joystickPhase.Reset(); _lastJoystickMoveAt = 0f; _joystickCameraControlActive = false; _nextBrakeLeverControlResolveAt = 0f; _nextFocusAnchorAimAt = 0f; _monitorWallCache = null; _brakeLeverResolveFailures = 0; _warnedBrakeLeverControlMissing = false; _loggedBrakeLeverControlRig = false; _controlGeometryDumpedOnEnter = false; } private static void EnsureStationEventSubscriptions() { if (!_stationEventsSubscribed) { CCTVStationEvents.ChairEntered += OnStationChairEntered; CCTVStationEvents.ChairExited += OnStationChairExited; CCTVStationEvents.CameraControlChanged += OnStationCameraControlChanged; CCTVStationEvents.JoystickMoved += OnStationJoystickMoved; _stationEventsSubscribed = true; } } private static void ClearStationEventSubscriptions() { if (_stationEventsSubscribed) { CCTVStationEvents.ChairEntered -= OnStationChairEntered; CCTVStationEvents.ChairExited -= OnStationChairExited; CCTVStationEvents.CameraControlChanged -= OnStationCameraControlChanged; CCTVStationEvents.JoystickMoved -= OnStationJoystickMoved; _stationEventsSubscribed = false; } } private static void OnStationChairEntered(PlayerControllerB _) { _joystickCameraControlActive = false; ResetJoystickMotionTarget(immediate: true); UpdateJoystickMotion(force: true); if (SurveillanceBootstrap.Config != null && (SurveillanceBootstrap.Config.ReconLoggingEnabled.Value || SurveillanceBootstrap.Config.PlacementDebugLoggingEnabled.Value) && !_controlGeometryDumpedOnEnter) { _controlGeometryDumpedOnEnter = true; DumpControlGeometry("station-enter"); } } private static void OnStationChairExited(PlayerControllerB _) { _joystickCameraControlActive = false; ResetJoystickMotionTarget(); } private static void OnStationCameraControlChanged(bool active) { _joystickCameraControlActive = active; if (!active) { ResetJoystickMotionTarget(); } } private static void OnStationJoystickMoved(Vector2 appliedDeltaDeg) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) _lastJoystickMoveAt = Time.unscaledTime; _joystickPhase.SetRequested(appliedDeltaDeg); } private static AssetBundle TryGetStationPropsBundle() { if ((Object)(object)_stationPropsBundle != (Object)null) { return _stationPropsBundle; } if (_stationPropsBundleLoadAttempted) { return null; } _stationPropsBundleLoadAttempted = true; _stationPropsBundle = FindAlreadyLoadedStationPropsBundle(); if ((Object)(object)_stationPropsBundle != (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] CCTV station props bundle reused from an already-loaded AssetBundle instance (likely LethalLevelLoader)."); } return _stationPropsBundle; } string pluginDirectory = GetPluginDirectory(); string[] array = new string[2] { Path.Combine(pluginDirectory ?? string.Empty, "y4ngz-cctv-stationprops.stationbundle"), Path.Combine(pluginDirectory ?? string.Empty, "Assets", "y4ngz-cctv-stationprops.stationbundle") }; foreach (string text in array) { if (string.IsNullOrWhiteSpace(text) || !File.Exists(text)) { continue; } try { _stationPropsBundle = AssetBundle.LoadFromFile(text); if ((Object)(object)_stationPropsBundle != (Object)null) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] CCTV station props bundle loaded from '" + text + "'.")); } return _stationPropsBundle; } ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV] AssetBundle.LoadFromFile returned null for station props bundle '" + text + "' (duplicate load by another mod?).")); } } catch (Exception ex) { ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogWarning((object)("[LethalCCTV] Station props bundle load failed for '" + text + "': " + ex.Message)); } } } if (!_warnedStationPropsBundleMissing) { _warnedStationPropsBundleMissing = true; ManualLogSource log5 = SurveillanceBootstrap.Log; if (log5 != null) { log5.LogWarning((object)("[LethalCCTV] Station props bundle 'y4ngz-cctv-stationprops.stationbundle' could not be loaded from '" + pluginDirectory + "'; the provided rolling chair / joystick prefabs are unavailable and generated fallback props will be used.")); } } return null; } private static AssetBundle FindAlreadyLoadedStationPropsBundle() { try { foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { if ((Object)(object)allLoadedAssetBundle != (Object)null && string.Equals(((Object)allLoadedAssetBundle).name, "y4ngz-cctv-stationprops", StringComparison.OrdinalIgnoreCase)) { return allLoadedAssetBundle; } } } catch { } return null; } private static AudioClip LoadAudioClipAsset(AssetBundle bundle, string assetName) { if ((Object)(object)bundle == (Object)null || string.IsNullOrWhiteSpace(assetName)) { return null; } AudioClip val = bundle.LoadAsset(assetName); if ((Object)(object)val != (Object)null) { return val; } val = bundle.LoadAsset(assetName + ".mp3"); if ((Object)(object)val != (Object)null) { return val; } string[] allAssetNames = bundle.GetAllAssetNames(); if (allAssetNames == null) { return null; } foreach (string text in allAssetNames) { if (string.Equals(Path.GetFileNameWithoutExtension(text), assetName, StringComparison.OrdinalIgnoreCase)) { val = bundle.LoadAsset(text); if ((Object)(object)val != (Object)null) { return val; } } } return null; } internal static AudioClip GetButtonPressClip() { if (_accessButtonPressClipLoadAttempted) { return _accessButtonPressClip; } _accessButtonPressClipLoadAttempted = true; AssetBundle val = TryGetStationPropsBundle(); if ((Object)(object)val == (Object)null) { return null; } _accessButtonPressClip = LoadAudioClipAsset(val, "Y4NGZ_CCTV_ButtonPress") ?? LoadAudioClipAsset(val, "press"); if ((Object)(object)_accessButtonPressClip != (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] CCTV button press audio loaded from 'y4ngz-cctv-stationprops.stationbundle' asset='" + ((Object)_accessButtonPressClip).name + "'.")); } } else { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)"[LethalCCTV] Station props bundle did not contain button press audio; monitor buttons will interact silently."); } } return _accessButtonPressClip; } internal static void TickStation() { EnsureStationEventSubscriptions(); EnsureBrakeLeverControlRig(); UpdateJoystickMotion(); if (Time.unscaledTime >= _nextFocusAnchorAimAt) { _nextFocusAnchorAimAt = Time.unscaledTime + 5f; EnsureFocusAnchorAimed(); } _placementEditor?.Tick(); } internal static void StartDebugPlacement(string targetName) { AllowDebugStationSpawn(2f); Ensure(allowUnpurchasedForDebug: true); string text = NormalizePlacementTarget(targetName); if (text == "focus" || text == "radar") { EnsureFocusAnchorAimed(force: true); EnsureRadarAnchorAimed(force: true); } GetPlacementEditor().Start(targetName); } internal static bool IsEditingDebugPlacement(string targetName) { if (_placementEditor != null) { return _placementEditor.IsEditingTarget(targetName); } return false; } internal static bool CancelDebugPlacement() { if (_placementEditor == null || !_placementEditor.IsActive) { return false; } _placementEditor.Cancel(); return true; } private static void AllowDebugStationSpawn(float seconds) { _debugStationSpawnUntil = Mathf.Max(_debugStationSpawnUntil, Time.unscaledTime + Mathf.Max(0f, seconds)); } private static bool IsDebugStationSpawnActive() { if (_placementEditor == null || !_placementEditor.IsActive) { return Time.unscaledTime < _debugStationSpawnUntil; } return true; } internal static void DumpControlGeometry(string reason = "manual") { //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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) try { EnsureBrakeLeverControlRig(); StartMatchLever val = null; try { val = ResolveStartMatchLever(); } catch { val = null; } Vector3 val2 = ResolveControlGeometryAnchor(val); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] --- CCTV control geometry dump (" + reason + ") anchor=" + FormatVectorPrecise(val2) + " ---")); } ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] frames root=" + GetPath(((Object)(object)_root != (Object)null) ? _root.transform : null) + " pose=" + GetPath(_operatorPoseAnchor) + " focus=" + GetPath(_focusViewAnchor) + " lever=" + GetPath(_joystickTiltPivot))); } LogControlTransform("stationRoot", ((Object)(object)_root != (Object)null) ? _root.transform : null); LogControlTransform("focusViewAnchor", _focusViewAnchor); LogControlTransform("radarViewAnchor", _radarViewAnchor); LogControlTransform("operatorPoseAnchor", _operatorPoseAnchor); LogControlTransform("joystickTiltPivot", _joystickTiltPivot); LogControlTransform("rightHandTarget", _rightHandTarget); LogControlTransform("leftHandIdleTarget", _leftHandIdleTarget); LogControlTransform("leftHandPressTarget", _leftHandPressTarget); LogControlTransform("lookTarget", _lookTarget); if ((Object)(object)val == (Object)null) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)"[LethalCCTV] StartMatchLever was not found during control geometry dump."); } } else { LogControlTransform("startMatchLever", ((Component)val).transform); LogControlTransform("startMatchLever.trigger", ((Object)(object)val.triggerScript != (Object)null) ? ((Component)val.triggerScript).transform : null); LogControlTransform("startMatchLever.playerPositionNode", ((Object)(object)val.triggerScript != (Object)null) ? val.triggerScript.playerPositionNode : null); LogControlTransform("startMatchLever.leverAnimatorObject", ((Object)(object)val.leverAnimatorObject != (Object)null) ? ((Component)val.leverAnimatorObject).transform : null); } List candidates = CollectControlRendererCandidates(val2); DumpControlCandidates("renderer", candidates, 60); List candidates2 = CollectControlColliderCandidates(val2); DumpControlCandidates("collider", candidates2, 40); ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogInfo((object)"[LethalCCTV] --- end CCTV control geometry dump ---"); } } catch (Exception ex) { ManualLogSource log5 = SurveillanceBootstrap.Log; if (log5 != null) { log5.LogWarning((object)("[LethalCCTV] CCTV control geometry dump failed: " + ex.Message)); } } } private static Vector3 ResolveControlGeometryAnchor(StartMatchLever lever) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_002f: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)lever != (Object)null && (Object)(object)lever.leverAnimatorObject != (Object)null) { Transform transform = ((Component)lever.leverAnimatorObject).transform; if (TryGetRendererBounds(transform, out var bounds)) { return ((Bounds)(ref bounds)).center; } return transform.position; } if ((Object)(object)_joystickTiltPivot != (Object)null) { if (TryGetRendererBounds(_joystickTiltPivot, out var bounds2)) { return ((Bounds)(ref bounds2)).center; } return _joystickTiltPivot.position; } if ((Object)(object)lever != (Object)null) { return ((Component)lever).transform.position; } if ((Object)(object)_operatorPoseAnchor != (Object)null) { return _operatorPoseAnchor.position; } if ((Object)(object)_root != (Object)null) { return _root.transform.position; } return Vector3.zero; } private static void LogControlTransform(string label, Transform transform) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_008f: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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_0151: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: 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_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] GEOM " + label + ": ")); } return; } LogControlPoint(label, transform.position, GetPath(transform)); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] GEOM " + label + ".rotation worldEuler=" + FormatVectorPrecise(transform.eulerAngles) + " localEuler=" + FormatVectorPrecise(transform.localEulerAngles) + " lossyScale=" + FormatVectorPrecise(transform.lossyScale))); } if (TryGetRendererBounds(transform, out var bounds)) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)("[LethalCCTV] GEOM " + label + ".bounds size=" + FormatVectorPrecise(((Bounds)(ref bounds)).size) + " center=" + FormatPointInFrames(((Bounds)(ref bounds)).center))); } LogControlPoint(label + ".boundsTop", ((Bounds)(ref bounds)).center + Vector3.up * ((Bounds)(ref bounds)).extents.y, null); Vector3 val = (((Object)(object)_operatorPoseAnchor != (Object)null) ? (_operatorPoseAnchor.position - ((Bounds)(ref bounds)).center) : (((Object)(object)_root != (Object)null) ? (-_root.transform.forward) : Vector3.forward)); val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = (((Object)(object)_root != (Object)null) ? (-_root.transform.forward) : Vector3.forward); } ((Vector3)(ref val)).Normalize(); float num = Mathf.Max(((Bounds)(ref bounds)).extents.x, ((Bounds)(ref bounds)).extents.z); LogControlPoint(label + ".boundsTowardOperator", ((Bounds)(ref bounds)).center + val * num, null); } } private static List CollectControlRendererCandidates(Vector3 anchor) { //IL_003c: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) List list = new List(); Renderer[] array; try { array = Resources.FindObjectsOfTypeAll(); } catch { return list; } foreach (Renderer val in array) { if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null) { continue; } Scene scene = ((Component)val).gameObject.scene; if (((Scene)(ref scene)).IsValid()) { Bounds bounds; try { bounds = val.bounds; } catch { continue; } AddControlGeometryCandidate(list, ((Component)val).transform, bounds, anchor, "renderer"); } } SortControlGeometryCandidates(list); return list; } private static List CollectControlColliderCandidates(Vector3 anchor) { //IL_003c: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) List list = new List(); Collider[] array; try { array = Resources.FindObjectsOfTypeAll(); } catch { return list; } foreach (Collider val in array) { if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null) { continue; } Scene scene = ((Component)val).gameObject.scene; if (((Scene)(ref scene)).IsValid()) { Bounds bounds; try { bounds = val.bounds; } catch { continue; } AddControlGeometryCandidate(list, ((Component)val).transform, bounds, anchor, "collider"); } } SortControlGeometryCandidates(list); return list; } private static void AddControlGeometryCandidate(List candidates, Transform transform, Bounds bounds, Vector3 anchor, string source) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0049: 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_0061: 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_00d0: Unknown result type (might be due to invalid IL or missing references) if (candidates == null || (Object)(object)transform == (Object)null) { return; } string path = GetPath(transform); if (!IsControlGeometryPathInScope(path)) { return; } float num = Vector3.Distance(((Bounds)(ref bounds)).ClosestPoint(anchor), anchor); if (!(num > 2.25f)) { Vector3 size = ((Bounds)(ref bounds)).size; float num2 = Mathf.Max(size.x, Mathf.Max(size.y, size.z)); float num3 = Vector3.Distance(((Bounds)(ref bounds)).center, anchor); bool flag = PathLooksLikeControlGeometry(path); bool flag2 = num2 <= 0.55f; bool flag3 = num <= 0.35f || num3 <= 0.95f; if ((flag || flag2 || flag3) && (flag || !(num2 > 1.5f)) && !(num2 <= 0.001f)) { candidates.Add(new ControlGeometryCandidate { Transform = transform, Path = path, Bounds = bounds, CenterDistance = num3, ClosestDistance = num, MaxAxis = num2, Source = source }); } } } private static void SortControlGeometryCandidates(List candidates) { candidates?.Sort(delegate(ControlGeometryCandidate a, ControlGeometryCandidate b) { int num = a.ClosestDistance.CompareTo(b.ClosestDistance); return (num == 0) ? a.CenterDistance.CompareTo(b.CenterDistance) : num; }); } private static void DumpControlCandidates(string source, List candidates, int limit) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) int num = candidates?.Count ?? 0; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] GEOM {source}Candidates count={num} dumpLimit={limit}"); } if (num == 0) { return; } int num2 = Mathf.Min(num, limit); for (int i = 0; i < num2; i++) { ControlGeometryCandidate controlGeometryCandidate = candidates[i]; if (controlGeometryCandidate != null) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)($"[LethalCCTV] GEOM {source}[{i}] path={controlGeometryCandidate.Path} " + "center=" + FormatPointInFrames(((Bounds)(ref controlGeometryCandidate.Bounds)).center) + " size=" + FormatVectorPrecise(((Bounds)(ref controlGeometryCandidate.Bounds)).size) + " " + $"centerDist={controlGeometryCandidate.CenterDistance:F3} closest={controlGeometryCandidate.ClosestDistance:F3} " + $"maxAxis={controlGeometryCandidate.MaxAxis:F3} source={controlGeometryCandidate.Source}")); } Vector3 world = ((Bounds)(ref controlGeometryCandidate.Bounds)).center + Vector3.up * ((Bounds)(ref controlGeometryCandidate.Bounds)).extents.y; Vector3 val = (((Object)(object)_operatorPoseAnchor != (Object)null) ? (_operatorPoseAnchor.position - ((Bounds)(ref controlGeometryCandidate.Bounds)).center) : (((Object)(object)_root != (Object)null) ? (-_root.transform.forward) : Vector3.forward)); val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = (((Object)(object)_root != (Object)null) ? (-_root.transform.forward) : Vector3.forward); } ((Vector3)(ref val)).Normalize(); Vector3 world2 = ((Bounds)(ref controlGeometryCandidate.Bounds)).center + val * Mathf.Max(((Bounds)(ref controlGeometryCandidate.Bounds)).extents.x, ((Bounds)(ref controlGeometryCandidate.Bounds)).extents.z); ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)($"[LethalCCTV] GEOM {source}[{i}].top={FormatPointInFrames(world)} " + "nearFace=" + FormatPointInFrames(world2))); } } } } private static bool IsControlGeometryPathInScope(string path) { if (string.IsNullOrWhiteSpace(path)) { return false; } if (path.IndexOf("Environment/HangarShip", StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf("LethalCCTV_VanillaOperatorStation", StringComparison.OrdinalIgnoreCase) < 0) { return PathLooksLikeControlGeometry(path); } return true; } private static bool PathLooksLikeControlGeometry(string path) { if (string.IsNullOrWhiteSpace(path)) { return false; } if (path.IndexOf("button", StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf("switch", StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf("knob", StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf("dial", StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf("lever", StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf("brake", StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf("gear", StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf("throttle", StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf("start", StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf("control", StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf("panel", StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf("red", StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf("green", StringComparison.OrdinalIgnoreCase) < 0) { return path.IndexOf("blue", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static void LogControlPoint(string label, Vector3 world, string path) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) string text = (string.IsNullOrWhiteSpace(path) ? string.Empty : (" path=" + path)); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] GEOM " + label + text + " " + FormatPointInFrames(world))); } } private static string FormatPointInFrames(Vector3 world) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) return "world=" + FormatVectorPrecise(world) + " rootLocal=" + FormatLocalPoint(((Object)(object)_root != (Object)null) ? _root.transform : null, world) + " poseLocal=" + FormatLocalPoint(_operatorPoseAnchor, world) + " focusLocal=" + FormatLocalPoint(_focusViewAnchor, world) + " leverLocal=" + FormatLocalPoint(_joystickTiltPivot, world); } private static string FormatLocalPoint(Transform frame, Vector3 world) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)frame != (Object)null)) { return ""; } return FormatVectorPrecise(frame.InverseTransformPoint(world)); } private static string FormatVector(Vector3 value) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"({value.x:0.00}, {value.y:0.00}, {value.z:0.00})"; } private static string FormatVectorPrecise(Vector3 value) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"({value.x:0.000}, {value.y:0.000}, {value.z:0.000})"; } 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++ < 32) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private static string GetPluginDirectory() { try { string location = typeof(SurveillanceBootstrap).Assembly.Location; return string.IsNullOrWhiteSpace(location) ? null : Path.GetDirectoryName(location); } catch { return null; } } private static void ResetJoystickMotionTarget(bool immediate = false) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (immediate) { _joystickPhase.Reset(); } else { _joystickPhase.SetRequested(Vector2.zero); } _lastJoystickMoveAt = Time.unscaledTime; } private static void UpdateJoystickMotion(bool force = false) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_joystickTiltPivot == (Object)null) { return; } int num; if (_joystickCameraControlActive) { num = ((Time.unscaledTime - _lastJoystickMoveAt > 0.16f) ? 1 : 0); if (num == 0) { goto IL_003c; } } else { num = 1; } _joystickPhase.SetRequested(Vector2.zero); goto IL_003c; IL_003c: if (force) { _joystickPhase.SetImmediate(Vector2.zero); } Vector2 joystick = _joystickPhase.Tick(Mathf.Max(Time.unscaledDeltaTime, 0.004166667f)); if (((uint)num | (force ? 1u : 0u)) == 0 || !(((Vector2)(ref joystick)).sqrMagnitude <= 1E-05f)) { ApplyJoystickTiltPose(joystick); } } private static void ApplyJoystickTiltPose(Vector2 joystick) { //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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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_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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_joystickTiltPivot == (Object)null) { return; } Quaternion joystickBaseWorldRotation = GetJoystickBaseWorldRotation(); Quaternion joystickWorldRotation = joystickBaseWorldRotation; float num = Mathf.Clamp01(((Vector2)(ref joystick)).magnitude); if (num > 0.0001f) { Vector3 val = joystickBaseWorldRotation * _joystickTiltNeutralLocalAxis; Vector3 val2 = ((Vector3)(ref val)).normalized; if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.up; } if (TryResolveJoystickTiltDirection(joystick, val2, out var tiltDirection)) { float num2 = 0.2443461f * num; Vector3 val3 = val2 * Mathf.Cos(num2) + tiltDirection * Mathf.Sin(num2); if (((Vector3)(ref val3)).sqrMagnitude > 0.0001f) { joystickWorldRotation = Quaternion.FromToRotation(val2, ((Vector3)(ref val3)).normalized) * joystickBaseWorldRotation; } } } SetJoystickWorldRotation(joystickWorldRotation); } private static Quaternion GetJoystickBaseWorldRotation() { //IL_000d: 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_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_0027: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_joystickTiltPivot == (Object)null) { return Quaternion.identity; } Transform parent = _joystickTiltPivot.parent; if (!((Object)(object)parent != (Object)null)) { return _joystickTiltBaseLocalRotation; } return parent.rotation * _joystickTiltBaseLocalRotation; } private static void SetJoystickWorldRotation(Quaternion worldRotation) { //IL_0043: 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_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_0033: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_joystickTiltPivot == (Object)null)) { Transform parent = _joystickTiltPivot.parent; if ((Object)(object)parent != (Object)null) { _joystickTiltPivot.localRotation = Quaternion.Inverse(parent.rotation) * worldRotation; } else { _joystickTiltPivot.rotation = worldRotation; } } } private static bool TryResolveJoystickTiltDirection(Vector2 joystick, Vector3 neutralAxis, out Vector3 tiltDirection) { //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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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) //IL_0031: 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_0033: 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_004d: 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) tiltDirection = Vector3.zero; ResolveJoystickMotionBasis(out var operatorRight, out var operatorForward); Vector3 val = operatorRight * joystick.x + operatorForward * joystick.y; val = Vector3.ProjectOnPlane(val, neutralAxis); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { return false; } tiltDirection = ((Vector3)(ref val)).normalized; return true; } private static void ResolveJoystickMotionBasis(out Vector3 operatorRight, out Vector3 operatorForward) { //IL_0069: 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_006e: 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_007d: 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_009d: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) Transform val = (((Object)(object)_operatorPoseAnchor != (Object)null) ? _operatorPoseAnchor : (((Object)(object)_focusViewAnchor != (Object)null) ? _focusViewAnchor : (((Object)(object)_root != (Object)null) ? _root.transform : (((Object)(object)_joystickTiltPivot != (Object)null) ? _joystickTiltPivot : null)))); operatorRight = (((Object)(object)val != (Object)null) ? val.right : Vector3.right); operatorForward = (((Object)(object)val != (Object)null) ? val.forward : Vector3.forward); if (((Vector3)(ref operatorRight)).sqrMagnitude < 0.0001f) { operatorRight = Vector3.right; } if (((Vector3)(ref operatorForward)).sqrMagnitude < 0.0001f) { operatorForward = Vector3.forward; } ((Vector3)(ref operatorRight)).Normalize(); ((Vector3)(ref operatorForward)).Normalize(); } private static void EnsureBrakeLeverControlRig() { if ((Object)(object)_rightHandTarget != (Object)null && (Object)(object)_joystickTiltPivot != (Object)null) { _brakeLeverResolveFailures = 0; } else if (!(Time.unscaledTime < _nextBrakeLeverControlResolveAt)) { int num = Mathf.Min(_brakeLeverResolveFailures, BrakeLeverResolveBackoffSeconds.Length - 1); _nextBrakeLeverControlResolveAt = Time.unscaledTime + BrakeLeverResolveBackoffSeconds[num]; if (_brakeLeverResolveFailures < BrakeLeverResolveBackoffSeconds.Length) { _brakeLeverResolveFailures++; } ConfigureBrakeLeverControlRig(); } } private static void ConfigureBrakeLeverControlRig() { //IL_00be: Unknown result type (might be due to invalid IL or missing references) Transform val = (_joystickTiltPivot = ResolveBrakeLeverControlTransform()); CaptureJoystickTiltBasePose(val); CreateOperatorHandTargets(val); _joystickPhase.Reset(); _lastJoystickMoveAt = Time.unscaledTime; _joystickCameraControlActive = false; if ((Object)(object)val == (Object)null) { if (!_warnedBrakeLeverControlMissing) { _warnedBrakeLeverControlMissing = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Vanilla brake lever control transform was not found; CCTV hand targets will use the station root until it resolves."); } } } else if (!_loggedBrakeLeverControlRig) { _loggedBrakeLeverControlRig = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogMessage((object)("[LethalCCTV][LeverGrip] control=" + GetPath(val) + " source=" + _rightHandGripSource + " world=" + (((Object)(object)_rightHandTarget != (Object)null) ? FormatVector(_rightHandTarget.position) : "") + ".")); } } } private static Transform ResolveBrakeLeverControlTransform() { try { StartMatchLever val = ResolveStartMatchLever(); if ((Object)(object)val != (Object)null) { if ((Object)(object)val.leverAnimatorObject != (Object)null) { return ((Component)val.leverAnimatorObject).transform; } if ((Object)(object)val.triggerScript != (Object)null && (Object)(object)val.triggerScript.playerPositionNode != (Object)null) { return val.triggerScript.playerPositionNode; } if ((Object)(object)val.triggerScript != (Object)null) { return ((Component)val.triggerScript).transform; } return ((Component)val).transform; } } catch { } return ResolveThrottleTransform(); } private static StartMatchLever ResolveStartMatchLever() { Transform val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.elevatorTransform : null); if ((Object)(object)val != (Object)null) { StartMatchLever componentInChildren = ((Component)val).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { return componentInChildren; } } return Object.FindObjectOfType(); } private static void CaptureJoystickTiltBasePose(Transform pivot) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0070: 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) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_009d: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) _joystickTiltBaseLocalRotation = (((Object)(object)pivot != (Object)null) ? pivot.localRotation : Quaternion.identity); _joystickTiltNeutralLocalAxis = Vector3.up; if (!((Object)(object)pivot == (Object)null)) { Quaternion val = (((Object)(object)pivot.parent != (Object)null) ? (pivot.parent.rotation * _joystickTiltBaseLocalRotation) : _joystickTiltBaseLocalRotation); Vector3 val2 = ResolveJoystickNeutralWorldAxis(pivot, val); if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = val * Vector3.up; } if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.up; } _joystickTiltNeutralLocalAxis = Quaternion.Inverse(val) * ((Vector3)(ref val2)).normalized; if (((Vector3)(ref _joystickTiltNeutralLocalAxis)).sqrMagnitude < 0.0001f) { _joystickTiltNeutralLocalAxis = Vector3.up; } else { ((Vector3)(ref _joystickTiltNeutralLocalAxis)).Normalize(); } } } private static Vector3 ResolveJoystickNeutralWorldAxis(Transform pivot, Quaternion baseWorldRotation) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_00e6: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_00d3: 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_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_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) //IL_003f: 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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_008e: 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_0093: Unknown result type (might be due to invalid IL or missing references) Vector3 best = Vector3.zero; float bestDistance = 0f; Vector3 position = pivot.position; Bounds bounds; try { Renderer[] componentsInChildren = ((Component)pivot).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Vector3 worldCenter; if (!((Object)(object)componentsInChildren[i] != (Object)null)) { worldCenter = position; } else { bounds = componentsInChildren[i].bounds; worldCenter = ((Bounds)(ref bounds)).center; } ConsiderJoystickAxisCandidate(worldCenter, position, ref best, ref bestDistance); } } catch { } try { Collider[] componentsInChildren2 = ((Component)pivot).GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren2.Length; j++) { Vector3 worldCenter2; if (!((Object)(object)componentsInChildren2[j] != (Object)null)) { worldCenter2 = position; } else { bounds = componentsInChildren2[j].bounds; worldCenter2 = ((Bounds)(ref bounds)).center; } ConsiderJoystickAxisCandidate(worldCenter2, position, ref best, ref bestDistance); } } catch { } if (bestDistance > 0.025f) { if (Vector3.Dot(best, Vector3.up) < -0.05f) { best = -best; } return ((Vector3)(ref best)).normalized; } Vector3 val = baseWorldRotation * Vector3.up; if (Vector3.Dot(val, Vector3.up) < -0.05f) { val = -val; } if (!(((Vector3)(ref val)).sqrMagnitude > 0.0001f)) { return Vector3.up; } return ((Vector3)(ref val)).normalized; } private static void ConsiderJoystickAxisCandidate(Vector3 worldCenter, Vector3 pivotPosition, ref Vector3 best, ref float bestDistance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_001a: 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) Vector3 val = worldCenter - pivotPosition; float magnitude = ((Vector3)(ref val)).magnitude; if (!(magnitude <= bestDistance)) { bestDistance = magnitude; best = val; } } private static bool TryResolveJoystickGripCenter(Transform pivot, out Vector3 gripCenter, out string source) { //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_001a: 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) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_003e: 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) //IL_0052: 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_00d7: 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) gripCenter = Vector3.zero; source = null; if ((Object)(object)pivot == (Object)null) { return false; } Vector3 neutralAxis = pivot.rotation * _joystickTiltNeutralLocalAxis; if (((Vector3)(ref neutralAxis)).sqrMagnitude < 0.0001f) { neutralAxis = pivot.up; } if (((Vector3)(ref neutralAxis)).sqrMagnitude < 0.0001f) { neutralAxis = Vector3.up; } ((Vector3)(ref neutralAxis)).Normalize(); float bestScore = float.NegativeInfinity; try { Renderer[] componentsInChildren = ((Component)pivot).GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { ConsiderJoystickGripCandidate(pivot, ((Component)val).transform, val.bounds, neutralAxis, "renderer", ref bestScore, ref gripCenter, ref source); } } } catch { } try { Collider[] componentsInChildren2 = ((Component)pivot).GetComponentsInChildren(true); foreach (Collider val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null)) { ConsiderJoystickGripCandidate(pivot, ((Component)val2).transform, val2.bounds, neutralAxis, "collider", ref bestScore, ref gripCenter, ref source); } } } catch { } return source != null; } private static void ConsiderJoystickGripCandidate(Transform pivot, Transform candidateTransform, Bounds bounds, Vector3 neutralAxis, string kind, ref float bestScore, ref Vector3 bestPoint, ref string bestSource) { //IL_0002: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0126: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Bounds)(ref bounds)).center - pivot.position; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 0.015f || magnitude > 0.75f) { return; } float num = Vector3.Dot(val, neutralAxis); if (num < 0.005f) { return; } Vector3 val2 = val - neutralAxis * num; float magnitude2 = ((Vector3)(ref val2)).magnitude; float num2 = Mathf.Max(((Bounds)(ref bounds)).size.x, Mathf.Max(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z)); if (!(magnitude2 > 0.25f) && !(num2 > 0.75f)) { string text = (((Object)(object)candidateTransform != (Object)null) ? (((Object)candidateTransform).name ?? string.Empty) : string.Empty).ToLowerInvariant(); float num3 = ((text.Contains("knob") || text.Contains("grip") || text.Contains("handle") || text.Contains("ball")) ? 0.08f : 0f); float num4 = num + num3 - magnitude2 * 0.2f; if (!(num4 <= bestScore)) { bestScore = num4; bestPoint = ((Bounds)(ref bounds)).center; bestSource = kind + ":" + GetPath(candidateTransform); } } } private static void CreateOperatorHandTargets(Transform joystickRoot) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0174: 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_01a6: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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) DestroyTarget(ref _rightHandTarget); DestroyTarget(ref _leftHandIdleTarget); DestroyTarget(ref _leftHandPressTarget); DestroyTarget(ref _lookTarget); if ((Object)(object)_root == (Object)null) { return; } Transform val = (((Object)(object)_joystickTiltPivot != (Object)null) ? _joystickTiltPivot : joystickRoot); if ((Object)(object)val == (Object)null) { val = _root.transform; } _rightHandTarget = CreateTarget(val, "CCTVOperator_RightHandTarget", new Vector3(0f, 0.42f, 0f), new Vector3(72f, 0f, 88f)); _rightHandGripSource = "authored-pivot-offset"; if ((Object)(object)_rightHandTarget != (Object)null && TryResolveJoystickGripCenter(val, out var gripCenter, out var source)) { float num = Vector3.Distance(_rightHandTarget.position, val.position); if (Vector3.Distance(gripCenter, val.position) >= Mathf.Max(0.015f, num * 0.65f)) { _rightHandTarget.position = gripCenter; _rightHandGripSource = source; } } _leftHandIdleTarget = CreateTarget(_root.transform, "CCTVOperator_LeftHandIdleTarget", new Vector3(0.67f, 1.42f, 0.54f), new Vector3(82f, 4f, -98f)); _leftHandPressTarget = CreateTarget(_root.transform, "CCTVOperator_LeftHandPressTarget", new Vector3(0.67f, 1.42f, 0.54f), new Vector3(82f, 4f, -98f)); _lookTarget = CreateTarget(_root.transform, "CCTVOperator_LookTarget", new Vector3(0.45f, 1.5f, -0.08f), Vector3.zero); } private static void DestroyTarget(ref Transform target) { if ((Object)(object)target != (Object)null) { Object.Destroy((Object)(object)((Component)target).gameObject); } target = null; } private static Transform CreateTarget(Transform parent, string name, Vector3 localPosition, Vector3 localEuler) { //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_0013: 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_001f: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localPosition = localPosition; val.transform.localRotation = Quaternion.Euler(localEuler); val.transform.localScale = Vector3.one; return val.transform; } private static CCTVStationPlacementEditor GetPlacementEditor() { if (_placementEditor == null) { _placementEditor = new CCTVStationPlacementEditor(); } return _placementEditor; } internal static bool TryGetDebugPlacementTarget(string targetName, out Transform target, out string normalizedTarget) { normalizedTarget = NormalizePlacementTarget(targetName); target = null; switch (normalizedTarget) { case "throttle": target = ResolveThrottleTransform(); return (Object)(object)target != (Object)null; case "focus": target = _focusViewAnchor; return (Object)(object)target != (Object)null; case "radar": target = _radarViewAnchor; return (Object)(object)target != (Object)null; case "player": target = PlayerRootAnchor; return (Object)(object)target != (Object)null; case "pose": target = _operatorPoseAnchor; return (Object)(object)target != (Object)null; case "button": if ((Object)(object)_root != (Object)null) { CCTVAccessButton.Ensure(_root.transform); } target = CCTVAccessButton.Root; return (Object)(object)target != (Object)null; default: return false; } } internal static void SaveDebugPlacement(string targetName, Transform target) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00d7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return; } string text = NormalizePlacementTarget(targetName); if (string.IsNullOrWhiteSpace(text)) { return; } StationPlacementRecord stationPlacementRecord = new StationPlacementRecord { target = text, localPosition = target.localPosition, localEuler = target.localEulerAngles, localScale = NormalizePlacementScale(target.localScale) }; UpsertPlacement(stationPlacementRecord); if (!SavePlacementProfile(text)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogError((object)("[LethalCCTV] FAILED to save CCTV station placement target=" + text + "; the on-disk profile does not contain it. Path: " + PlacementProfilePath)); } return; } ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogMessage((object)("[LethalCCTV] Saved CCTV station placement target=" + text + " pos=" + FormatVector(stationPlacementRecord.localPosition) + " euler=" + FormatVector(stationPlacementRecord.localEuler) + " scale=" + FormatVector(stationPlacementRecord.localScale) + ".")); } } internal static StationPlacementRecord GetDefaultPlacementRecord(string targetName, Transform target) { //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022a: 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_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019f: 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) return NormalizePlacementTarget(targetName) switch { "throttle" => CaptureDefaultThrottlePlacement(target), "focus" => new StationPlacementRecord { target = "focus", localPosition = FocusLocalPosition, localEuler = FocusLocalEuler, localScale = Vector3.one }, "radar" => new StationPlacementRecord { target = "radar", localPosition = RadarFocusLocalPosition, localEuler = RadarFocusLocalEuler, localScale = Vector3.one }, "player" => new StationPlacementRecord { target = "player", localPosition = PlayerRootLocalPosition, localEuler = PlayerRootLocalEuler, localScale = Vector3.one }, "pose" => new StationPlacementRecord { target = "pose", localPosition = OperatorPoseLocalPosition, localEuler = OperatorPoseLocalEuler, localScale = Vector3.one }, "button" => new StationPlacementRecord { target = "button", localPosition = AccessButtonLocalPosition, localEuler = AccessButtonLocalEuler, localScale = AccessButtonLocalScale }, "note" => new StationPlacementRecord { target = "note", localPosition = NoteLocalPosition, localEuler = NoteLocalEuler, localScale = NoteLocalScale }, _ => null, }; } internal static void ApplyAccessButtonPlacement(Transform buttonRoot) { if (!((Object)(object)buttonRoot == (Object)null)) { if (!TryGetSavedPlacement("button", out var record) || record == null) { record = GetDefaultPlacementRecord("button", buttonRoot); } if (record != null) { ApplyPlacementRecord(buttonRoot, record); } } } internal static void ApplyNotePlacement(Transform noteAnchor) { if (!((Object)(object)noteAnchor == (Object)null)) { if (!TryGetSavedPlacement("note", out var record) || record == null) { record = GetDefaultPlacementRecord("note", noteAnchor); } if (record != null) { ApplyPlacementRecord(noteAnchor, record); } } } internal static string SaveShipScopedPlacement(string objectKind, string objectId, Transform source, string metadataJson) { //IL_0030: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) if (!IsAuthoredNoteKind(objectKind)) { return null; } if ((Object)(object)source == (Object)null) { return "save failed: no source transform"; } Transform val = EnsureNoteAnchor(); if ((Object)(object)val == (Object)null) { return "save failed: CCTV station root not spawned yet (load into the ship first)"; } val.SetPositionAndRotation(source.position, source.rotation); SaveDebugPlacement("note", val); string text = CCTVStickyNoteItem.RespawnForAuthoring(); return "saved cctv note anchor local pos=" + FormatVector(val.localPosition) + " euler=" + FormatVector(val.localEulerAngles) + "; " + text; } internal static bool TryGetShipScopedSavedPose(string objectKind, string objectId, out Vector3 worldPosition, out Quaternion worldRotation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_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_003f: 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) worldPosition = Vector3.zero; worldRotation = Quaternion.identity; if (!IsAuthoredNoteKind(objectKind)) { return false; } Transform val = EnsureNoteAnchor(); if ((Object)(object)val == (Object)null) { return false; } worldPosition = val.position; worldRotation = val.rotation; return true; } internal static string DeleteShipScopedPlacement(string objectKind, string objectId) { if (!IsAuthoredNoteKind(objectKind)) { return null; } bool num = RemovePlacement("note"); Transform val = EnsureNoteAnchor(); if ((Object)(object)val != (Object)null) { ApplyNotePlacement(val); } if (!num) { return "no saved cctv note placement; anchor holds the code default"; } string text = CCTVStickyNoteItem.RespawnForAuthoring(); return "deleted the saved cctv note placement; anchor reset to the code default; " + text; } private static bool IsAuthoredNoteKind(string objectKind) { return string.Equals(AuthoredInteriorPlacementKinds.Normalize(objectKind), "cctv-note", StringComparison.OrdinalIgnoreCase); } private static bool RemovePlacement(string targetName) { EnsurePlacementProfileLoaded(); string text = NormalizePlacementTarget(targetName); if (string.IsNullOrWhiteSpace(text) || _placementProfile?.placements == null) { return false; } bool flag = false; for (int num = _placementProfile.placements.Count - 1; num >= 0; num--) { StationPlacementRecord stationPlacementRecord = _placementProfile.placements[num]; if (stationPlacementRecord != null && string.Equals(NormalizePlacementTarget(stationPlacementRecord.target), text, StringComparison.OrdinalIgnoreCase)) { _placementProfile.placements.RemoveAt(num); flag = true; } } if (!flag) { return false; } if (!SavePlacementProfile()) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogError((object)("[LethalCCTV] FAILED to remove CCTV station placement target=" + text + "; the on-disk profile still disagrees with memory. Path: " + PlacementProfilePath)); } return false; } return true; } private static void ApplySavedStationPlacements() { ApplySavedPlacement("focus", _focusViewAnchor); if (HasSavedPlacement("radar")) { ApplySavedPlacement("radar", _radarViewAnchor); } else { AimRadarAnchorFromFocusDefault(); } ApplySavedPlacement("player", _playerRootAnchor); ApplySavedPlacement("pose", _operatorPoseAnchor); } private static void ApplySavedPlacement(string targetName, Transform target) { if (!((Object)(object)target == (Object)null)) { string targetName2 = NormalizePlacementTarget(targetName); if (!TryGetSavedPlacement(targetName2, out var record)) { record = GetDefaultPlacementRecord(targetName2, target); } ApplyPlacementRecord(target, record); } } private static void ApplyPlacementRecord(Transform target, StationPlacementRecord record) { //IL_000f: 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_0020: 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) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null) && record != null) { target.localPosition = record.localPosition; target.localRotation = Quaternion.Euler(record.localEuler); target.localScale = NormalizePlacementScale(record.localScale); } } private static bool HasSavedPlacement(string targetName) { StationPlacementRecord record; return TryGetSavedPlacement(targetName, out record); } internal static void SyncThrottleSecondaryTargetsToPrimary(Transform primary) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_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_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_003e: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00d5: 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_00e3: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: 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_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_011d: 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_0126: 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_0131: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)primary == (Object)null || !_defaultThrottlePlacementCaptured || _throttleSecondaryTargets.Count == 0) { return; } Quaternion val = primary.rotation * Quaternion.Inverse(_defaultThrottleWorldRotation); Vector3 val2 = DivideScale(primary.lossyScale, _defaultThrottleWorldScale); Vector3 val3 = DivideScale(primary.localScale, _defaultThrottleLocalScale); int num = Mathf.Min(_throttleSecondaryTargets.Count, Mathf.Min(_throttleSecondaryDefaultWorld.Count, Mathf.Min(_throttleSecondaryDefaultWorldRotations.Count, _throttleSecondaryDefaultLocalScales.Count))); for (int i = 0; i < num; i++) { Transform val4 = _throttleSecondaryTargets[i]; if (!((Object)(object)val4 == (Object)null)) { Vector3 val5 = Quaternion.Inverse(_defaultThrottleWorldRotation) * (_throttleSecondaryDefaultWorld[i] - _defaultThrottleWorldPosition); Vector3 val6 = primary.position + primary.rotation * Vector3.Scale(val5, val2); Quaternion val7 = val * _throttleSecondaryDefaultWorldRotations[i]; Vector3 localScale = NormalizePlacementScale(Vector3.Scale(_throttleSecondaryDefaultLocalScales[i], val3)); val4.SetPositionAndRotation(val6, val7); val4.localScale = localScale; } } } private static Vector3 DivideScale(Vector3 numerator, Vector3 denominator) { //IL_0000: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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) return new Vector3(DivideScaleComponent(numerator.x, denominator.x), DivideScaleComponent(numerator.y, denominator.y), DivideScaleComponent(numerator.z, denominator.z)); } private static float DivideScaleComponent(float numerator, float denominator) { if (Mathf.Abs(denominator) < 0.0001f || float.IsNaN(denominator) || float.IsInfinity(denominator)) { return 1f; } if (float.IsNaN(numerator) || float.IsInfinity(numerator)) { return 1f; } return Mathf.Clamp(numerator / denominator, 0.05f, 20f); } private static StationPlacementRecord CaptureDefaultThrottlePlacement(Transform throttle) { //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) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0033: 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_003e: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)throttle == (Object)null) { return null; } if (!_defaultThrottlePlacementCaptured) { _defaultThrottleLocalPosition = throttle.localPosition; _defaultThrottleLocalEuler = throttle.localEulerAngles; _defaultThrottleLocalScale = NormalizePlacementScale(throttle.localScale); _defaultThrottleWorldPosition = throttle.position; _defaultThrottleWorldRotation = throttle.rotation; _defaultThrottleWorldScale = throttle.lossyScale; _defaultThrottlePlacementCaptured = true; } return new StationPlacementRecord { target = "throttle", localPosition = ComputeDefaultThrottleRelocatedLocalPosition(throttle), localEuler = _defaultThrottleLocalEuler, localScale = _defaultThrottleLocalScale }; } private static Vector3 ComputeDefaultThrottleRelocatedLocalPosition(Transform throttle) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0026: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)throttle == (Object)null) { return _defaultThrottleLocalPosition; } Vector3 val = (((Object)(object)_root != (Object)null) ? (-_root.transform.right * 0.72f) : (Vector3.left * 0.72f)); Transform parent = throttle.parent; Vector3 val2 = _defaultThrottleWorldPosition + val; if (!((Object)(object)parent != (Object)null)) { return val2; } return parent.InverseTransformPoint(val2); } private static string NormalizePlacementTarget(string targetName) { if (string.IsNullOrWhiteSpace(targetName)) { return "focus"; } string text = targetName.Trim().ToLowerInvariant(); if (text == "seat" || text == "operator" || text == "operatorchair") { return "chair"; } if (text == "stick" || text == "joy" || text == "joystick" || text == "control") { return "throttle"; } if (text == "lever" || text == "startlever" || text == "shiplever" || text == "startmatchlever" || text == "brake" || text == "brakelever" || text == "throttlelever" || text == "gearstick" || text == "gear" || text == "sticklever") { return "throttle"; } if (text == "view" || text == "camera" || text == "focusview" || text == "focusanchor") { return "focus"; } if (text == "radar" || text == "radarview" || text == "radaranchor" || text == "radarfocus" || text == "spaceview" || text == "spacelook") { return "radar"; } if (text == "player" || text == "playerroot" || text == "playerrootanchor" || text == "thirdperson" || text == "thirdpersonplayer" || text == "thirdpersonmodel" || text == "playermodel" || text == "model" || text == "root") { return "player"; } if (text == "operatorpose" || text == "poseanchor" || text == "bodypose") { return "pose"; } if (text == "button" || text == "accessbutton" || text == "access" || text == "entrybutton" || text == "cctvbutton" || text == "redbutton" || text == "bigredbutton" || text == "teleporterbutton") { return "button"; } if (!(text == "note")) { switch (text) { case "stickynote": case "sticky": case "noteanchor": case "cctvnote": break; case "chair": case "throttle": case "focus": case "radar": case "player": case "pose": case "button": case "note": return text; default: { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Unknown CCTV station placement target '" + targetName + "'. Known targets: chair, throttle, focus, radar, player, pose, button, note.")); } return null; } } } return "note"; } private static Vector3 NormalizePlacementScale(Vector3 scale) { //IL_0000: 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_001b: 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_0032: 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_0079: Unknown result type (might be due to invalid IL or missing references) float num = (IsValidScaleComponent(scale.x) ? scale.x : 1f); float num2 = (IsValidScaleComponent(scale.y) ? scale.y : num); float num3 = (IsValidScaleComponent(scale.z) ? scale.z : num); return new Vector3(Mathf.Clamp(num, 0.05f, 5f), Mathf.Clamp(num2, 0.05f, 5f), Mathf.Clamp(num3, 0.05f, 5f)); } private static bool IsValidScaleComponent(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value)) { return value > 0f; } return false; } private static bool TryGetSavedPlacement(string targetName, out StationPlacementRecord record) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) EnsurePlacementProfileLoaded(); string text = NormalizePlacementTarget(targetName); record = null; if (string.IsNullOrWhiteSpace(text) || _placementProfile?.placements == null) { return false; } for (int i = 0; i < _placementProfile.placements.Count; i++) { StationPlacementRecord stationPlacementRecord = _placementProfile.placements[i]; if (stationPlacementRecord != null && string.Equals(NormalizePlacementTarget(stationPlacementRecord.target), text, StringComparison.OrdinalIgnoreCase)) { record = stationPlacementRecord; record.target = text; record.localScale = NormalizePlacementScale(record.localScale); return true; } } return false; } private static void UpsertPlacement(StationPlacementRecord record) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) EnsurePlacementProfileLoaded(); if (_placementProfile.placements == null) { _placementProfile.placements = new List(); } record.target = NormalizePlacementTarget(record.target); if (string.IsNullOrWhiteSpace(record.target)) { return; } record.localScale = NormalizePlacementScale(record.localScale); for (int i = 0; i < _placementProfile.placements.Count; i++) { StationPlacementRecord stationPlacementRecord = _placementProfile.placements[i]; if (stationPlacementRecord != null && string.Equals(NormalizePlacementTarget(stationPlacementRecord.target), record.target, StringComparison.OrdinalIgnoreCase)) { _placementProfile.placements[i] = record; return; } } _placementProfile.placements.Add(record); } private static void EnsurePlacementProfileLoaded() { if (_placementProfileLoaded) { return; } _placementProfileLoaded = true; _placementProfile = new StationPlacementProfile(); string placementProfilePath = PlacementProfilePath; if (string.IsNullOrWhiteSpace(placementProfilePath) || !File.Exists(placementProfilePath)) { return; } try { StationPlacementProfile stationPlacementProfile = ReadPlacementProfile(File.ReadAllText(placementProfilePath)); if (stationPlacementProfile != null && stationPlacementProfile.placements != null) { _placementProfile = stationPlacementProfile; } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Failed reading CCTV station placement profile: " + ex.Message)); } _placementProfile = new StationPlacementProfile(); } } private static StationPlacementProfile ReadPlacementProfile(string json) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) Y4NGZJsonObject val = Y4NGZJson.Parse(json); if (val == null) { return null; } StationPlacementProfile stationPlacementProfile = new StationPlacementProfile(); Y4NGZJsonArray array = val.GetArray("placements"); if (array == null) { return stationPlacementProfile; } for (int i = 0; i < array.Count; i++) { Y4NGZJsonObject val2 = array.GetObject(i); if (val2 != null) { stationPlacementProfile.placements.Add(new StationPlacementRecord { target = val2.GetString("target", ""), localPosition = val2.GetVector3("localPosition"), localEuler = val2.GetVector3("localEuler"), localScale = val2.GetVector3("localScale", Vector3.one) }); } } return stationPlacementProfile; } private static string WritePlacementProfile(StationPlacementProfile profile) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) Y4NGZJsonObject val = new Y4NGZJsonObject(); Y4NGZJsonArray val2 = val.SetArray("placements"); if (profile?.placements != null) { for (int i = 0; i < profile.placements.Count; i++) { StationPlacementRecord stationPlacementRecord = profile.placements[i]; if (stationPlacementRecord != null) { Y4NGZJsonObject obj = val2.AddObject(); obj.SetString("target", stationPlacementRecord.target); obj.SetVector3("localPosition", stationPlacementRecord.localPosition); obj.SetVector3("localEuler", stationPlacementRecord.localEuler); obj.SetVector3("localScale", stationPlacementRecord.localScale); } } } return Y4NGZJson.Write(val, true); } private static bool SavePlacementProfile(string requiredTarget = null) { EnsurePlacementProfileLoaded(); string placementProfilePath = PlacementProfilePath; if (string.IsNullOrWhiteSpace(placementProfilePath)) { return false; } try { string directoryName = Path.GetDirectoryName(placementProfilePath); if (!string.IsNullOrWhiteSpace(directoryName)) { Directory.CreateDirectory(directoryName); } File.WriteAllText(placementProfilePath, WritePlacementProfile(_placementProfile)); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Failed writing CCTV station placement profile: " + ex.Message)); } return false; } return VerifySavedPlacementProfile(placementProfilePath, requiredTarget); } private static bool VerifySavedPlacementProfile(string path, string requiredTarget) { StationPlacementProfile stationPlacementProfile; try { stationPlacementProfile = ReadPlacementProfile(File.ReadAllText(path)); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Wrote the CCTV station placement profile but could not read it back: " + ex.Message)); } return false; } if (stationPlacementProfile?.placements == null) { return false; } int valueOrDefault = (_placementProfile?.placements?.Count).GetValueOrDefault(); if (stationPlacementProfile.placements.Count != valueOrDefault) { return false; } if (string.IsNullOrWhiteSpace(requiredTarget)) { return true; } for (int i = 0; i < stationPlacementProfile.placements.Count; i++) { StationPlacementRecord stationPlacementRecord = stationPlacementProfile.placements[i]; if (stationPlacementRecord != null && string.Equals(NormalizePlacementTarget(stationPlacementRecord.target), requiredTarget, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } private static Transform ResolveThrottleTransform() { if ((Object)(object)_throttleTransform != (Object)null) { return _throttleTransform; } try { _throttleTransform = ResolveThrottleAssemblyTransform(Object.FindObjectOfType()); } catch { _throttleTransform = null; } return _throttleTransform; } private static Transform ResolveThrottleAssemblyTransform(StartMatchLever lever) { if ((Object)(object)lever == (Object)null) { return null; } List list = new List(4); AddTransformIfValid(list, ((Component)lever).transform); AddTransformIfValid(list, ((Object)(object)lever.triggerScript != (Object)null) ? ((Component)lever.triggerScript).transform : null); AddTransformIfValid(list, ((Object)(object)lever.triggerScript != (Object)null) ? lever.triggerScript.playerPositionNode : null); AddTransformIfValid(list, ((Object)(object)lever.leverAnimatorObject != (Object)null) ? ((Component)lever.leverAnimatorObject).transform : null); Transform val = FindDeepestCommonAncestor(list); Transform val2; string reason; if (IsSafeThrottleAssemblyRoot(val)) { val2 = val; reason = "common"; } else { Transform val3 = FindNamedThrottleAncestor(((Object)(object)lever.leverAnimatorObject != (Object)null) ? ((Component)lever.leverAnimatorObject).transform : null); if ((Object)(object)val3 == (Object)null) { val3 = FindNamedThrottleAncestor(((Object)(object)lever.triggerScript != (Object)null) ? ((Component)lever.triggerScript).transform : null); } if ((Object)(object)val3 == (Object)null) { val3 = FindNamedThrottleAncestor(((Component)lever).transform); } if ((Object)(object)val3 != (Object)null) { val2 = val3; reason = "named-ancestor"; } else { val2 = ((Component)lever).transform; reason = "script-fallback"; } } LogThrottleAssemblyResolved(val2, reason); CollectThrottleSecondaryTargets(list, val2); CollectNearbyThrottleSecondaryTargets(lever, val2); DumpThrottleAssemblyHierarchy(lever, val2, reason); return val2; } private static void CollectThrottleSecondaryTargets(List important, Transform primary) { //IL_010a: Unknown result type (might be due to invalid IL or missing references) _throttleSecondaryTargets.Clear(); _throttleSecondaryDefaultWorld.Clear(); _throttleSecondaryDefaultWorldRotations.Clear(); _throttleSecondaryDefaultLocalScales.Clear(); if (important == null || (Object)(object)primary == (Object)null) { return; } for (int i = 0; i < important.Count; i++) { Transform val = important[i]; if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)primary || IsAncestorOf(primary, val) || IsAncestorOf(val, primary)) { continue; } bool flag = false; for (int j = 0; j < _throttleSecondaryTargets.Count; j++) { if ((Object)(object)_throttleSecondaryTargets[j] == (Object)(object)val || IsAncestorOf(_throttleSecondaryTargets[j], val)) { flag = true; break; } } if (!flag) { AddThrottleSecondarySnapshot(val); } } if (_throttleSecondaryTargets.Count <= 0) { return; } for (int k = 0; k < _throttleSecondaryTargets.Count; k++) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV] Start lever secondary move target [{k}]: {GetPath(_throttleSecondaryTargets[k])} " + "world=" + FormatVector(_throttleSecondaryDefaultWorld[k]))); } } } private static void CollectNearbyThrottleSecondaryTargets(StartMatchLever lever, Transform primary) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: 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_008f: 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_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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)lever == (Object)null || (Object)(object)primary == (Object)null) { return; } Vector3 val = (((Object)(object)lever.leverAnimatorObject != (Object)null) ? ((Component)lever.leverAnimatorObject).transform.position : ((Component)lever).transform.position); Transform[] array; try { array = Resources.FindObjectsOfTypeAll(); } catch { return; } int count = _throttleSecondaryTargets.Count; foreach (Transform val2 in array) { if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).gameObject == (Object)null) { continue; } Scene scene = ((Component)val2).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { continue; } string text = ((((Object)val2).name != null) ? ((Object)val2).name.ToLowerInvariant() : string.Empty); if (text.IndexOf("lever", StringComparison.Ordinal) < 0 && text.IndexOf("brake", StringComparison.Ordinal) < 0 && text.IndexOf("startgame", StringComparison.Ordinal) < 0 && text.IndexOf("gearstick", StringComparison.Ordinal) < 0 && text.IndexOf("gear stick", StringComparison.Ordinal) < 0 && text.IndexOf("gear", StringComparison.Ordinal) < 0 && text.IndexOf("throttle", StringComparison.Ordinal) < 0) { continue; } Vector3 val3 = val2.position - val; if (!(((Vector3)(ref val3)).sqrMagnitude > 2.25f)) { string path = GetPath(val2); if (path != null && path.IndexOf("Environment/HangarShip", StringComparison.OrdinalIgnoreCase) >= 0) { AddThrottleSecondaryTarget(val2, primary); } } } if (_throttleSecondaryTargets.Count > count) { for (int j = count; j < _throttleSecondaryTargets.Count; j++) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV] Start lever nearby move target [{j}]: {GetPath(_throttleSecondaryTargets[j])} " + "world=" + FormatVector(_throttleSecondaryDefaultWorld[j]))); } } } CollectNearbyThrottleRendererTargets(primary, val); } private static void CollectNearbyThrottleRendererTargets(Transform primary, Vector3 anchor) { //IL_004f: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)primary == (Object)null) { return; } Renderer[] array; try { array = Resources.FindObjectsOfTypeAll(); } catch { return; } bool flag = !_throttleRendererCandidatesDumped; _throttleRendererCandidatesDumped = true; if (flag) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV] --- start lever renderer candidates within {1.8f:F2}m of " + "anchor=" + FormatVector(anchor) + " (one-shot) ---")); } } int count = _throttleSecondaryTargets.Count; foreach (Renderer val in array) { if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null) { continue; } Scene scene = ((Component)val).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { continue; } Transform transform = ((Component)val).transform; if ((Object)(object)transform == (Object)null) { continue; } Bounds bounds; try { bounds = val.bounds; } catch { continue; } float num = Vector3.Distance(((Bounds)(ref bounds)).center, anchor); float num2 = Vector3.Distance(((Bounds)(ref bounds)).ClosestPoint(anchor), anchor); if (num2 > 1.8f) { continue; } string path = GetPath(transform); Vector3 size = ((Bounds)(ref bounds)).size; float num3 = Mathf.Max(size.x, Mathf.Max(size.y, size.z)); bool flag2 = false; string text; if ((Object)(object)transform == (Object)(object)primary || IsAncestorOf(primary, transform)) { text = "already-in-primary-subtree"; } else if (IsAncestorOf(transform, primary)) { text = "excluded: ancestor-of-primary"; } else if (path == null || path.IndexOf("Environment/HangarShip", StringComparison.OrdinalIgnoreCase) < 0) { text = "excluded: outside-HangarShip"; } else if (IsUnsafeNearbyThrottleRendererPath(path)) { text = "excluded: unsafe-path-token"; } else if (num3 <= 0.01f) { text = "excluded: degenerate-bounds"; } else if (IsLikelyThrottleCasingRenderer(path, bounds, anchor, num3, num2)) { text = "INCLUDED: throttle-casing"; flag2 = true; } else if (num3 > 1.3f) { text = $"excluded: too-large maxAxis={num3:F2}"; } else if (Mathf.Abs(((Bounds)(ref bounds)).center.y - anchor.y) > 0.95f) { text = $"excluded: vertical-delta={Mathf.Abs(((Bounds)(ref bounds)).center.y - anchor.y):F2}"; } else if (num > 1.1f && num2 > 0.65f) { text = $"excluded: too-far center={num:F2} closest={num2:F2}"; } else { text = "INCLUDED"; flag2 = true; } if (flag) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] candidate " + text + ": " + path + " world=" + FormatVector(transform.position) + " boundsCenter=" + FormatVector(((Bounds)(ref bounds)).center) + " boundsSize=" + FormatVector(size) + " " + $"center={num:F2}m closest={num2:F2}m")); } } if (flag2) { AddThrottleSecondaryTarget(transform, primary); } } if (flag) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)"[LethalCCTV] --- end start lever renderer candidates ---"); } } if (_throttleSecondaryTargets.Count <= count) { return; } for (int j = count; j < _throttleSecondaryTargets.Count; j++) { Transform val2 = _throttleSecondaryTargets[j]; if (!((Object)(object)val2 == (Object)null)) { Bounds bounds2; string text2 = (TryGetRendererBounds(val2, out bounds2) ? (" boundsCenter=" + FormatVector(((Bounds)(ref bounds2)).center) + " boundsSize=" + FormatVector(((Bounds)(ref bounds2)).size)) : string.Empty); ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogInfo((object)($"[LethalCCTV] Start lever nearby renderer move target [{j}]: {GetPath(val2)} " + "world=" + FormatVector(_throttleSecondaryDefaultWorld[j]) + text2)); } } } } private static bool IsLikelyThrottleCasingRenderer(string path, Bounds bounds, Vector3 anchor, float maxAxis, float closestDistance) { //IL_0043: 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) if (string.IsNullOrWhiteSpace(path)) { return false; } if (path.IndexOf("Environment/HangarShip", StringComparison.OrdinalIgnoreCase) < 0) { return false; } if (path.IndexOf("ControlPanelWTexture", StringComparison.OrdinalIgnoreCase) < 0) { return false; } if (maxAxis > 1.85f) { return false; } if (closestDistance > 0.1f) { return false; } if (Mathf.Abs(((Bounds)(ref bounds)).center.y - anchor.y) > 0.55f) { return false; } return true; } private static bool IsUnsafeNearbyThrottleRendererPath(string path) { if (string.IsNullOrWhiteSpace(path)) { return true; } string text = path.ToLowerInvariant(); if (text.IndexOf("monitorwall", StringComparison.Ordinal) < 0 && text.IndexOf("monitor wall", StringComparison.Ordinal) < 0 && text.IndexOf("cctv", StringComparison.Ordinal) < 0 && text.IndexOf("terminal", StringComparison.Ordinal) < 0 && text.IndexOf("keyboard", StringComparison.Ordinal) < 0 && text.IndexOf("phone", StringComparison.Ordinal) < 0 && text.IndexOf("clipboard", StringComparison.Ordinal) < 0 && text.IndexOf("battery", StringComparison.Ordinal) < 0 && text.IndexOf("screen", StringComparison.Ordinal) < 0 && text.IndexOf("button", StringComparison.Ordinal) < 0 && text.IndexOf("light", StringComparison.Ordinal) < 0 && text.IndexOf("poster", StringComparison.Ordinal) < 0) { return text.IndexOf("desk/table", StringComparison.Ordinal) >= 0; } return true; } private static void AddThrottleSecondaryTarget(Transform candidate, Transform primary) { if ((Object)(object)candidate == (Object)null || (Object)(object)primary == (Object)null || (Object)(object)candidate == (Object)(object)primary || IsAncestorOf(primary, candidate) || IsAncestorOf(candidate, primary)) { return; } for (int num = _throttleSecondaryTargets.Count - 1; num >= 0; num--) { Transform val = _throttleSecondaryTargets[num]; if ((Object)(object)val == (Object)null) { _throttleSecondaryTargets.RemoveAt(num); _throttleSecondaryDefaultWorld.RemoveAt(num); _throttleSecondaryDefaultWorldRotations.RemoveAt(num); _throttleSecondaryDefaultLocalScales.RemoveAt(num); } else { if ((Object)(object)val == (Object)(object)candidate || IsAncestorOf(val, candidate)) { return; } if (IsAncestorOf(candidate, val)) { _throttleSecondaryTargets.RemoveAt(num); _throttleSecondaryDefaultWorld.RemoveAt(num); _throttleSecondaryDefaultWorldRotations.RemoveAt(num); _throttleSecondaryDefaultLocalScales.RemoveAt(num); } } } AddThrottleSecondarySnapshot(candidate); } private static void AddThrottleSecondarySnapshot(Transform candidate) { //IL_001b: 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_003b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)candidate == (Object)null)) { _throttleSecondaryTargets.Add(candidate); _throttleSecondaryDefaultWorld.Add(candidate.position); _throttleSecondaryDefaultWorldRotations.Add(candidate.rotation); _throttleSecondaryDefaultLocalScales.Add(candidate.localScale); } } private static void DumpThrottleAssemblyHierarchy(StartMatchLever lever, Transform primary, string reason) { if (_throttleHierarchyDumped || (Object)(object)lever == (Object)null || (Object)(object)primary == (Object)null) { return; } _throttleHierarchyDumped = true; try { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] --- start lever assembly dump (one-shot) ---"); } ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] primary (" + reason + "): " + GetPath(primary))); } ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)("[LethalCCTV] lever script: " + GetPath(((Component)lever).transform))); } ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogInfo((object)("[LethalCCTV] trigger: " + (((Object)(object)lever.triggerScript != (Object)null) ? GetPath(((Component)lever.triggerScript).transform) : ""))); } ManualLogSource log5 = SurveillanceBootstrap.Log; if (log5 != null) { log5.LogInfo((object)("[LethalCCTV] playerPositionNode: " + (((Object)(object)lever.triggerScript != (Object)null && (Object)(object)lever.triggerScript.playerPositionNode != (Object)null) ? GetPath(lever.triggerScript.playerPositionNode) : ""))); } ManualLogSource log6 = SurveillanceBootstrap.Log; if (log6 != null) { log6.LogInfo((object)("[LethalCCTV] leverAnimatorObject: " + (((Object)(object)lever.leverAnimatorObject != (Object)null) ? GetPath(((Component)lever.leverAnimatorObject).transform) : ""))); } for (int i = 0; i < primary.childCount; i++) { Transform child = primary.GetChild(i); if (!((Object)(object)child == (Object)null)) { bool flag = (Object)(object)((Component)child).GetComponentInChildren(true) != (Object)null; ManualLogSource log7 = SurveillanceBootstrap.Log; if (log7 != null) { log7.LogInfo((object)$"[LethalCCTV] primary child[{i}]: {((Object)child).name} renderers={flag}"); } } } ManualLogSource log8 = SurveillanceBootstrap.Log; if (log8 != null) { log8.LogInfo((object)$"[LethalCCTV] placement group ({1 + _throttleSecondaryTargets.Count} member(s)):"); } LogThrottleGroupMember("primary", primary); for (int j = 0; j < _throttleSecondaryTargets.Count; j++) { LogThrottleGroupMember($"secondary[{j}]", _throttleSecondaryTargets[j]); } ManualLogSource log9 = SurveillanceBootstrap.Log; if (log9 != null) { log9.LogInfo((object)"[LethalCCTV] --- end start lever assembly dump ---"); } } catch (Exception ex) { ManualLogSource log10 = SurveillanceBootstrap.Log; if (log10 != null) { log10.LogDebug((object)("[LethalCCTV] Lever assembly dump failed: " + ex.Message)); } } } private static void LogThrottleGroupMember(string role, Transform member) { //IL_0041: 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_009a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)member == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] " + role + ": ")); } return; } Bounds bounds; string text = (TryGetRendererBounds(member, out bounds) ? (" boundsCenter=" + FormatVector(((Bounds)(ref bounds)).center) + " boundsSize=" + FormatVector(((Bounds)(ref bounds)).size)) : " (no renderers)"); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] " + role + ": " + GetPath(member) + " world=" + FormatVector(member.position) + text)); } } private static void AddTransformIfValid(List transforms, Transform transform) { if (transforms != null && !((Object)(object)transform == (Object)null) && !transforms.Contains(transform)) { transforms.Add(transform); } } private static Transform FindDeepestCommonAncestor(List transforms) { if (transforms == null || transforms.Count == 0) { return null; } Transform val = transforms[0]; while ((Object)(object)val != (Object)null) { bool flag = true; for (int i = 1; i < transforms.Count; i++) { if (!IsAncestorOf(val, transforms[i])) { flag = false; break; } } if (flag) { return val; } val = val.parent; } return null; } private static bool IsAncestorOf(Transform ancestor, Transform child) { if ((Object)(object)ancestor == (Object)null || (Object)(object)child == (Object)null) { return false; } Transform val = child; while ((Object)(object)val != (Object)null) { if ((Object)(object)val == (Object)(object)ancestor) { return true; } val = val.parent; } return false; } private static bool IsSafeThrottleAssemblyRoot(Transform transform) { //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_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_005b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform == (Object)null) { return false; } if (IsUnsafeThrottleRootName(((Object)transform).name)) { return false; } if (NameLooksLikeThrottleAssembly(((Object)transform).name)) { return true; } Renderer[] componentsInChildren = ((Component)transform).GetComponentsInChildren(true); if (componentsInChildren != null && componentsInChildren.Length > 24) { return false; } if (TryGetRendererBounds(transform, out var bounds)) { Vector3 size = ((Bounds)(ref bounds)).size; if (Mathf.Max(size.x, Mathf.Max(size.y, size.z)) > 4f) { return false; } } return true; } private static Transform FindNamedThrottleAncestor(Transform start) { Transform val = start; while ((Object)(object)val != (Object)null) { if (IsUnsafeThrottleRootName(((Object)val).name)) { return null; } if (NameLooksLikeThrottleAssembly(((Object)val).name)) { return val; } val = val.parent; } return null; } private static bool NameLooksLikeThrottleAssembly(string name) { if (string.IsNullOrWhiteSpace(name)) { return false; } string text = name.ToLowerInvariant(); if ((text.IndexOf("start", StringComparison.Ordinal) < 0 || text.IndexOf("lever", StringComparison.Ordinal) < 0) && (text.IndexOf("brake", StringComparison.Ordinal) < 0 || text.IndexOf("lever", StringComparison.Ordinal) < 0) && text.IndexOf("gearstick", StringComparison.Ordinal) < 0 && text.IndexOf("gear stick", StringComparison.Ordinal) < 0 && text.IndexOf("throttle", StringComparison.Ordinal) < 0 && text.IndexOf("matchlever", StringComparison.Ordinal) < 0) { return text.IndexOf("startmatchlever", StringComparison.Ordinal) >= 0; } return true; } private static bool IsUnsafeThrottleRootName(string name) { if (string.IsNullOrWhiteSpace(name)) { return false; } string text = name.ToLowerInvariant(); switch (text) { default: return text.IndexOf("shipinside", StringComparison.Ordinal) >= 0; case "environment": case "hangarship": case "shipmodels2b": case "monitorswall": case "monitorwall": case "systems": case "gamesystems": return true; } } private static bool TryGetRendererBounds(Transform root, out Bounds bounds) { //IL_0001: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); if ((Object)(object)root == (Object)null) { return false; } Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); bool flag = false; foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } return flag; } private static void LogThrottleAssemblyResolved(Transform transform, string reason) { if (!((Object)(object)transform == (Object)null)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Start lever placement target resolved via " + reason + ": " + GetPath(transform))); } } } } internal static class CctvOutlineManager { private enum OutlineKind { Item, Hostile, Player } private sealed class OutlineCandidate { public GameObject Root; public OutlineKind Kind; public int RendererCount; public float NearestDistanceSq; } private const float UpdateIntervalSeconds = 0.2f; private const float OutlineRequestDurationSeconds = 0.7f; private const float OutlineRadiusMeters = 58f; private static readonly Dictionary _activeRoots = new Dictionary(128); private static readonly Dictionary _candidatesByRoot = new Dictionary(128); private static readonly HashSet _liveRootIds = new HashSet(); private static readonly List _rootsToClear = new List(128); private static float _nextUpdateAt; private static bool _initialized; private static string _lastOutlineSummary; private static string _lastSkipState; private static float _nextSkipLogAt; internal static void Initialize() { if (!_initialized) { _initialized = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] CCTV OutlineEffect manager initialized."); } } } internal static void Shutdown() { ClearAll(); CctvTargetCache.Clear(); _initialized = false; } internal static void ClearAll() { foreach (GameObject value in _activeRoots.Values) { CctvOutlineEffectBridge.Clear(value); } _activeRoots.Clear(); _candidatesByRoot.Clear(); _liveRootIds.Clear(); _rootsToClear.Clear(); _lastOutlineSummary = null; CctvOutlineEffectBridge.DisableActiveEffect(); } internal static void Tick(CCTVCamera activeCamera, bool isActive, bool force = false) { if (!_initialized) { Initialize(); } if (!isActive || (Object)(object)activeCamera == (Object)null || MonitorFocus.IsTurretPageActive) { if (isActive && (Object)(object)activeCamera == (Object)null) { LogOutlineDiagnostic("skip active=true activeCamera=null"); } ClearAll(); return; } Camera cam = activeCamera.Cam; if ((Object)(object)cam == (Object)null) { LogOutlineDiagnostic("skip active=true holder='" + DescribeCamera(activeCamera) + "' camera=null"); ClearAll(); } else if (force || !(Time.unscaledTime < _nextUpdateAt)) { _nextUpdateAt = Time.unscaledTime + 0.2f; CctvTargetCache.RefreshIfDue(force); RefreshOutlineTargets(cam); } } private static void RefreshOutlineTargets(Camera camera) { //IL_001a: 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) //IL_006f: 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_0078: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) _candidatesByRoot.Clear(); _liveRootIds.Clear(); Vector3 position = ((Component)camera).transform.position; IReadOnlyList rendererTargets = CctvTargetCache.RendererTargets; int num = 0; int num2 = 0; for (int i = 0; i < rendererTargets.Count; i++) { CctvTargetCache.RendererTarget rendererTarget = rendererTargets[i]; if (!ShouldUseRealOutline(rendererTarget.Kind)) { continue; } Renderer renderer = rendererTarget.Renderer; if ((Object)(object)renderer == (Object)null || !renderer.enabled) { continue; } num++; Bounds bounds = renderer.bounds; Vector3 val = ((Bounds)(ref bounds)).center - position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (!(sqrMagnitude > 3364f)) { GameObject val2 = ResolveOutlineRoot(renderer, rendererTarget.Kind); if (!((Object)(object)val2 == (Object)null) && val2.activeInHierarchy) { num2++; UpsertCandidate(val2, ToOutlineKind(rendererTarget.Kind), sqrMagnitude); } } } int num3 = 0; foreach (OutlineCandidate value2 in _candidatesByRoot.Values) { if (!((Object)(object)value2.Root == (Object)null)) { int instanceID = ((Object)value2.Root).GetInstanceID(); if (CctvOutlineEffectBridge.Show(camera, value2.Root, ToChannel(value2.Kind), 0.7f)) { num3++; _liveRootIds.Add(instanceID); _activeRoots[instanceID] = value2.Root; } } } _rootsToClear.Clear(); foreach (KeyValuePair activeRoot in _activeRoots) { if (!_liveRootIds.Contains(activeRoot.Key)) { _rootsToClear.Add(activeRoot.Key); } } for (int j = 0; j < _rootsToClear.Count; j++) { int key = _rootsToClear[j]; if (_activeRoots.TryGetValue(key, out var value)) { CctvOutlineEffectBridge.Clear(value); } _activeRoots.Remove(key); } LogOutlineSummary(num, num2, num3); if (_activeRoots.Count == 0) { CctvOutlineEffectBridge.DisableActiveEffect(); } } private static void UpsertCandidate(GameObject root, OutlineKind kind, float distanceSq) { int instanceID = ((Object)root).GetInstanceID(); if (_candidatesByRoot.TryGetValue(instanceID, out var value)) { value.RendererCount++; value.NearestDistanceSq = Mathf.Min(value.NearestDistanceSq, distanceSq); if (Priority(kind) > Priority(value.Kind)) { value.Kind = kind; } } else { _candidatesByRoot[instanceID] = new OutlineCandidate { Root = root, Kind = kind, RendererCount = 1, NearestDistanceSq = distanceSq }; } } private static bool ShouldUseRealOutline(CctvTargetCache.TargetKind kind) { if (kind != CctvTargetCache.TargetKind.Player && kind != CctvTargetCache.TargetKind.Hostile) { return kind == CctvTargetCache.TargetKind.Item; } return true; } private static GameObject ResolveOutlineRoot(Renderer renderer, CctvTargetCache.TargetKind kind) { if ((Object)(object)renderer == (Object)null) { return null; } switch (kind) { case CctvTargetCache.TargetKind.Player: { PlayerControllerB componentInParent3 = ((Component)renderer).GetComponentInParent(); if (componentInParent3 == null) { return null; } return ((Component)componentInParent3).gameObject; } case CctvTargetCache.TargetKind.Hostile: { EnemyAI componentInParent2 = ((Component)renderer).GetComponentInParent(); if (componentInParent2 == null) { return null; } return ((Component)componentInParent2).gameObject; } case CctvTargetCache.TargetKind.Item: { GrabbableObject componentInParent = ((Component)renderer).GetComponentInParent(); if (componentInParent == null) { return null; } return ((Component)componentInParent).gameObject; } default: return null; } } private static OutlineKind ToOutlineKind(CctvTargetCache.TargetKind kind) { return kind switch { CctvTargetCache.TargetKind.Player => OutlineKind.Player, CctvTargetCache.TargetKind.Hostile => OutlineKind.Hostile, _ => OutlineKind.Item, }; } private static CctvOutlineChannel ToChannel(OutlineKind kind) { return kind switch { OutlineKind.Player => CctvOutlineChannel.Player, OutlineKind.Hostile => CctvOutlineChannel.Hostile, _ => CctvOutlineChannel.Item, }; } private static int Priority(OutlineKind kind) { return kind switch { OutlineKind.Hostile => 3, OutlineKind.Player => 2, _ => 1, }; } private static void LogOutlineSummary(int candidateRenderers, int nearRenderers, int shown) { if (!ShouldLogDiagnostics()) { return; } int num = 0; int num2 = 0; int num3 = 0; using (Dictionary.ValueCollection.Enumerator enumerator = _candidatesByRoot.Values.GetEnumerator()) { while (enumerator.MoveNext()) { switch (enumerator.Current.Kind) { case OutlineKind.Player: num++; break; case OutlineKind.Hostile: num2++; break; default: num3++; break; } } } string text = $"candidateRenderers={candidateRenderers} nearRenderers={nearRenderers} roots={_candidatesByRoot.Count} shown={shown} players={num} hostiles={num2} items={num3}"; if (!(text == _lastOutlineSummary)) { _lastOutlineSummary = text; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] CCTV OutlineEffect summary " + text + ".")); } } } private static void LogOutlineDiagnostic(string state) { if (!ShouldLogDiagnostics()) { return; } float unscaledTime = Time.unscaledTime; if (!(_lastSkipState == state) || !(unscaledTime < _nextSkipLogAt)) { _lastSkipState = state; _nextSkipLogAt = unscaledTime + 3f; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] CCTV OutlineEffect diagnostic " + state + ".")); } } } private static bool ShouldLogDiagnostics() { LethalCCTVConfig config = SurveillanceBootstrap.Config; if (config == null) { return false; } return config.ReconLoggingEnabled?.Value == true; } private static string DescribeCamera(CCTVCamera camera) { //IL_005e: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)camera == (Object)null) { return ""; } string text = ((!string.IsNullOrEmpty(camera.DisplayLabel)) ? camera.DisplayLabel : camera.ResolvedLabel); Transform val = (((Object)(object)camera.Cam != (Object)null) ? ((Component)camera.Cam).transform : ((Component)camera).transform); Vector3 val2 = (((Object)(object)val != (Object)null) ? val.position : Vector3.zero); return $"{text}#{camera.CameraIndex}@{val2.x:0.0},{val2.y:0.0},{val2.z:0.0}"; } } internal static class CCTVScanGlowManager { private sealed class GlowRenderer { public Renderer Original; public Material[] OriginalMaterials; public Material[] CopiedMaterials; public Renderer Overlay; public MaterialPropertyBlock OverlayBlock; public float ExpiresAt; public Color Color; } private const int FALLBACK_SCAN_NODE_MASK = 4194304; private const float TARGET_SEARCH_RADIUS = 2.5f; private const float MAX_GLOW_LIFETIME = 15f; private const float MIN_GLOW_LIFETIME = 1f; private static readonly Color ITEM_GREEN = new Color(0.1f, 1f, 0.32f, 1f); private static readonly Color HOSTILE_RED = new Color(1f, 0.08f, 0.06f, 1f); private static readonly Collider[] _overlapHits = (Collider[])(object)new Collider[64]; private static readonly Dictionary _tracked = new Dictionary(64); private static readonly List _expired = new List(32); private static Material _overlayMaterial; private static int _scanNodeMask = -1; private static bool _initialized; internal static bool HasActiveGlows => _tracked.Count > 0; internal static void Initialize() { if (!_initialized) { _initialized = true; _scanNodeMask = ResolveScanNodeMask(); } } internal static void Shutdown() { ClearAll(); if ((Object)(object)_overlayMaterial != (Object)null) { Object.Destroy((Object)(object)_overlayMaterial); _overlayMaterial = null; } _initialized = false; _scanNodeMask = -1; } internal static void ClearAll() { foreach (GlowRenderer value in _tracked.Values) { Restore(value); } _tracked.Clear(); _expired.Clear(); } internal static void MarkScanTarget(Vector3 position, float radius, int colorKind, float lifetime) { //IL_0021: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) Initialize(); float lifetime2 = Mathf.Clamp(lifetime, 1f, 15f); Color color = ((colorKind == 1) ? HOSTILE_RED : ITEM_GREEN); ScanNodeProperties val = FindNearestScanNode(position, Mathf.Max(radius, 2.5f)); GameObject val2 = (((Object)(object)val != (Object)null) ? ResolveTargetRoot(val) : ResolveFallbackRoot(position, radius)); if ((Object)(object)val2 == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)$"[LethalCCTV] CCTV scan glow skipped; no renderer target near {position}."); } } else { MarkRoot(val2, color, lifetime2); } } internal static void Tick() { if (_tracked.Count == 0) { return; } float unscaledTime = Time.unscaledTime; _expired.Clear(); foreach (KeyValuePair item in _tracked) { GlowRenderer value = item.Value; if (value == null || (Object)(object)value.Original == (Object)null || unscaledTime >= value.ExpiresAt) { _expired.Add(item.Key); } else { ApplyPulse(value, unscaledTime); } } for (int i = 0; i < _expired.Count; i++) { Renderer key = _expired[i]; if (_tracked.TryGetValue(key, out var value2)) { Restore(value2); _tracked.Remove(key); } } _expired.Clear(); } private static void MarkRoot(GameObject root, Color color, float lifetime) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return; } Renderer[] componentsInChildren = root.GetComponentsInChildren(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] CCTV scan glow target '" + ((Object)root).name + "' has no renderers.")); } return; } float expiresAt = Time.unscaledTime + lifetime; int num = 0; foreach (Renderer renderer in componentsInChildren) { if (IsEligibleRenderer(renderer) && TrackRenderer(renderer, color, expiresAt)) { num++; } } if (num > 0) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogDebug((object)$"[LethalCCTV] CCTV scan glow applied to '{((Object)root).name}' renderers={num}."); } } } private static bool TrackRenderer(Renderer renderer, Color color, float expiresAt) { //IL_001b: 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_0087: 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_009a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)renderer == (Object)null) { return false; } if (_tracked.TryGetValue(renderer, out var value)) { value.Color = color; value.ExpiresAt = Mathf.Max(value.ExpiresAt, expiresAt); ApplyPulse(value, Time.unscaledTime); return true; } Material[] sharedMaterials = renderer.sharedMaterials; Renderer val = CreateOverlay(renderer); if ((Object)(object)val == (Object)null) { return false; } GlowRenderer glowRenderer = new GlowRenderer { Original = renderer, OriginalMaterials = sharedMaterials, CopiedMaterials = null, Overlay = val, OverlayBlock = ((!((Object)(object)val != (Object)null)) ? ((MaterialPropertyBlock)null) : new MaterialPropertyBlock()), ExpiresAt = expiresAt, Color = color }; _tracked[renderer] = glowRenderer; ApplyPulse(glowRenderer, Time.unscaledTime); return true; } private static Renderer CreateOverlay(Renderer source) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_003f: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } GameObject val = new GameObject("LethalCCTV_ScanGlowOverlay"); val.layer = ((Component)source).gameObject.layer; val.transform.SetParent(((Component)source).transform, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; Renderer val2 = null; SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((source is SkinnedMeshRenderer) ? source : null); if (val3 != null && (Object)(object)val3.sharedMesh != (Object)null) { SkinnedMeshRenderer obj = val.AddComponent(); obj.sharedMesh = val3.sharedMesh; obj.bones = val3.bones; obj.rootBone = val3.rootBone; ((Renderer)obj).localBounds = ((Renderer)val3).localBounds; obj.updateWhenOffscreen = true; obj.quality = val3.quality; val2 = (Renderer)(object)obj; } else { MeshRenderer val4 = (MeshRenderer)(object)((source is MeshRenderer) ? source : null); if (val4 != null) { MeshFilter component = ((Component)val4).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) { val.AddComponent().sharedMesh = component.sharedMesh; val2 = (Renderer)(object)val.AddComponent(); } } } if ((Object)(object)val2 == (Object)null) { Object.Destroy((Object)(object)val); return null; } val2.enabled = source.enabled; val2.sharedMaterial = EnsureOverlayMaterial(); val2.shadowCastingMode = (ShadowCastingMode)0; val2.receiveShadows = false; val2.allowOcclusionWhenDynamic = false; val2.lightProbeUsage = (LightProbeUsage)0; val2.reflectionProbeUsage = (ReflectionProbeUsage)0; return val2; } private static Material EnsureOverlayMaterial() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0153: 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) if ((Object)(object)_overlayMaterial != (Object)null) { return _overlayMaterial; } _overlayMaterial = new Material(Shader.Find("HDRP/Unlit") ?? Shader.Find("HDRP/Lit") ?? Shader.Find("Unlit/Color")) { name = "LethalCCTV_ScanGlowOverlayMat", renderQueue = 5000 }; SetFloatIfExists(_overlayMaterial, "_SurfaceType", 1f); SetFloatIfExists(_overlayMaterial, "_BlendMode", 0f); SetFloatIfExists(_overlayMaterial, "_ZWrite", 0f); SetFloatIfExists(_overlayMaterial, "_TransparentZWrite", 0f); SetFloatIfExists(_overlayMaterial, "_CullMode", 0f); SetFloatIfExists(_overlayMaterial, "_CullModeForward", 0f); SetFloatIfExists(_overlayMaterial, "_ZTest", 8f); SetFloatIfExists(_overlayMaterial, "_ZTestDepthEqualForOpaque", 8f); SetColorIfExists(_overlayMaterial, "_BaseColor", new Color(0f, 0f, 0f, 0f)); SetColorIfExists(_overlayMaterial, "_UnlitColor", new Color(0f, 0f, 0f, 0f)); SetColorIfExists(_overlayMaterial, "_EmissiveColor", Color.black); SetColorIfExists(_overlayMaterial, "_EmissionColor", Color.black); SetFloatIfExists(_overlayMaterial, "_EmissiveIntensity", 1f); _overlayMaterial.EnableKeyword("_EMISSION"); return _overlayMaterial; } private static void ApplyPulse(GlowRenderer glow, float now) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00bc: 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_00f7: 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_0130: 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_014b: 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_0114: Unknown result type (might be due to invalid IL or missing references) if (glow != null) { bool num = IsHostileColor(glow.Color); float num2 = 0.72f + 0.28f * Mathf.Sin(now * 7.25f); float num3 = (num ? Mathf.Lerp(16f, 48f, num2) : Mathf.Lerp(70f, 190f, num2)); Color val = (Color)(num ? new Color(1f, 0.035f, 0.025f, 1f) : glow.Color); Color val2 = (Color)(num ? new Color(val.r * num3, val.g * num3 * 0.42f, val.b * num3 * 0.32f, 1f) : (val * num3)); Color val3 = (num ? new Color(1f, 0.04f, 0.035f, 0.1f + 0.06f * num2) : new Color(val.r, val.g, val.b, 0.18f + 0.1f * num2)); if ((Object)(object)glow.Overlay != (Object)null) { MaterialPropertyBlock val4 = (MaterialPropertyBlock)(((object)glow.OverlayBlock) ?? ((object)new MaterialPropertyBlock())); val4.SetColor("_BaseColor", val3); val4.SetColor("_UnlitColor", val3); val4.SetColor("_EmissiveColor", val2); val4.SetColor("_EmissionColor", val2); val4.SetColor("_EmissiveColorLDR", val2); val4.SetFloat("_EmissiveIntensity", num3); val4.SetTexture("_EmissiveColorMap", (Texture)(object)Texture2D.whiteTexture); glow.Overlay.SetPropertyBlock(val4); glow.OverlayBlock = val4; } } } private static void ApplyMaterialEmission(Material material, Color baseColor, Color emissive, float intensity, bool hostile) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0087: 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_0093: 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) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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) if (!((Object)(object)material == (Object)null)) { material.EnableKeyword("_EMISSION"); SetColorIfExists(material, "_EmissionColor", emissive); SetColorIfExists(material, "_EmissiveColor", emissive); SetColorIfExists(material, "_EmissiveColorLDR", emissive); SetFloatIfExists(material, "_EmissiveIntensity", intensity); SetFloatIfExists(material, "_UseEmissiveIntensity", 1f); SetTextureIfExists(material, "_EmissiveColorMap", (Texture)(object)Texture2D.whiteTexture); Color value = (hostile ? new Color(baseColor.r, baseColor.g, baseColor.b, 0.12f) : new Color(baseColor.r, baseColor.g, baseColor.b, 0.22f)); SetColorIfExists(material, "_BaseColor", value); SetColorIfExists(material, "_UnlitColor", value); } } private static bool IsHostileColor(Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (color.r > 0.75f && color.g < 0.22f) { return color.b < 0.18f; } return false; } private static void Restore(GlowRenderer glow) { if (glow != null) { if ((Object)(object)glow.Original != (Object)null && glow.OriginalMaterials != null) { glow.Original.sharedMaterials = glow.OriginalMaterials; } if ((Object)(object)glow.Overlay != (Object)null) { Object.Destroy((Object)(object)((Component)glow.Overlay).gameObject); } } } private static bool IsEligibleRenderer(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return false; } if (renderer is LineRenderer) { return false; } if (((object)renderer).GetType().Name.IndexOf("VFX", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } if (((Object)((Component)renderer).gameObject).name.IndexOf("LethalCCTV_ScanGlowOverlay", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } if ((Object)(object)((Component)renderer).GetComponentInParent() != (Object)null) { return false; } if (renderer.sharedMaterials != null) { return renderer.sharedMaterials.Length != 0; } return false; } private static ScanNodeProperties FindNearestScanNode(Vector3 position, float radius) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_0094: 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) ScanNodeProperties best = null; float bestDistance = float.PositiveInfinity; int num = Physics.OverlapSphereNonAlloc(position, radius, _overlapHits, _scanNodeMask, (QueryTriggerInteraction)2); for (int i = 0; i < num; i++) { Collider val = _overlapHits[i]; if (!((Object)(object)val == (Object)null)) { TryChooseNearestNode(((Component)val).GetComponent() ?? ((Component)val).GetComponentInParent(), position, ref best, ref bestDistance); } } if ((Object)(object)best != (Object)null) { return best; } ScanNodeProperties[] array = Object.FindObjectsOfType(true); float num2 = radius * radius; foreach (ScanNodeProperties val2 in array) { if (!((Object)(object)val2 == (Object)null)) { Vector3 val3 = ((Component)val2).transform.position - position; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (!(sqrMagnitude > num2) && !(sqrMagnitude >= bestDistance)) { bestDistance = sqrMagnitude; best = val2; } } } return best; } private static void TryChooseNearestNode(ScanNodeProperties node, Vector3 position, ref ScanNodeProperties best, ref float bestDistance) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //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) if (!((Object)(object)node == (Object)null)) { Vector3 val = ((Component)node).transform.position - position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (!(sqrMagnitude >= bestDistance)) { bestDistance = sqrMagnitude; best = node; } } } private static GameObject ResolveTargetRoot(ScanNodeProperties node) { if ((Object)(object)node == (Object)null) { return null; } EnemyAI componentInParent = ((Component)node).GetComponentInParent(true); if ((Object)(object)componentInParent != (Object)null) { return ((Component)componentInParent).gameObject; } GrabbableObject componentInParent2 = ((Component)node).GetComponentInParent(true); if ((Object)(object)componentInParent2 != (Object)null) { return ((Component)componentInParent2).gameObject; } Turret componentInParent3 = ((Component)node).GetComponentInParent(true); if ((Object)(object)componentInParent3 != (Object)null) { return ((Component)componentInParent3).gameObject; } Landmine componentInParent4 = ((Component)node).GetComponentInParent(true); if ((Object)(object)componentInParent4 != (Object)null) { return ((Component)componentInParent4).gameObject; } SpikeRoofTrap componentInParent5 = ((Component)node).GetComponentInParent(true); if ((Object)(object)componentInParent5 != (Object)null) { return ((Component)componentInParent5).gameObject; } PlayerControllerB componentInParent6 = ((Component)node).GetComponentInParent(true); if ((Object)(object)componentInParent6 != (Object)null) { return ((Component)componentInParent6).gameObject; } Transform parent = ((Component)node).transform.parent; if (!((Object)(object)parent != (Object)null)) { return ((Component)node).gameObject; } return ((Component)parent).gameObject; } private static GameObject ResolveFallbackRoot(Vector3 position, float radius) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0066: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(radius, 2.5f); int num2 = Physics.OverlapSphereNonAlloc(position, num, _overlapHits, -1, (QueryTriggerInteraction)2); GameObject result = null; float num3 = float.PositiveInfinity; for (int i = 0; i < num2; i++) { Collider val = _overlapHits[i]; if ((Object)(object)val == (Object)null) { continue; } GameObject val2 = ResolveKnownRoot(((Component)val).transform); if (!((Object)(object)val2 == (Object)null)) { Vector3 val3 = val2.transform.position - position; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (!(sqrMagnitude >= num3)) { num3 = sqrMagnitude; result = val2; } } } return result; } private static GameObject ResolveKnownRoot(Transform transform) { if ((Object)(object)transform == (Object)null) { return null; } EnemyAI componentInParent = ((Component)transform).GetComponentInParent(true); if ((Object)(object)componentInParent != (Object)null) { return ((Component)componentInParent).gameObject; } GrabbableObject componentInParent2 = ((Component)transform).GetComponentInParent(true); if ((Object)(object)componentInParent2 != (Object)null) { return ((Component)componentInParent2).gameObject; } Turret componentInParent3 = ((Component)transform).GetComponentInParent(true); if ((Object)(object)componentInParent3 != (Object)null) { return ((Component)componentInParent3).gameObject; } Landmine componentInParent4 = ((Component)transform).GetComponentInParent(true); if ((Object)(object)componentInParent4 != (Object)null) { return ((Component)componentInParent4).gameObject; } SpikeRoofTrap componentInParent5 = ((Component)transform).GetComponentInParent(true); if (!((Object)(object)componentInParent5 != (Object)null)) { return null; } return ((Component)componentInParent5).gameObject; } private static int ResolveScanNodeMask() { int num = LayerMask.NameToLayer("ScanNode"); if (num >= 0) { return 1 << num; } return 4194304; } private static void SetColorIfExists(Material material, string property, Color value) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material != (Object)null && material.HasProperty(property)) { material.SetColor(property, value); } } private static void SetFloatIfExists(Material material, string property, float value) { if ((Object)(object)material != (Object)null && material.HasProperty(property)) { material.SetFloat(property, value); } } private static void SetTextureIfExists(Material material, string property, Texture value) { if ((Object)(object)material != (Object)null && material.HasProperty(property)) { material.SetTexture(property, value); } } } internal static class CctvScreenClock { internal const string UnavailableText = "--:--"; private static bool _loggedComparison; internal static string GetShipTime24h() { return ShipClock24h.GetShipTime24h(); } internal static void LogComparisonOnce(string ours) { if (_loggedComparison || string.IsNullOrEmpty(ours) || ours == "--:--") { return; } TimeOfDay instance = TimeOfDay.Instance; if ((Object)(object)instance == (Object)null) { return; } HUDManager instance2 = HUDManager.Instance; string text = (((Object)(object)instance2 != (Object)null && (Object)(object)instance2.clockNumber != (Object)null) ? ((TMP_Text)instance2.clockNumber).text : null); if (!string.IsNullOrEmpty(text)) { _loggedComparison = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][Clock] cctv='" + ours + "' vanillaHud='" + text.Replace("\n", " ") + "' " + $"(normalizedTimeOfDay={instance.normalizedTimeOfDay:F4}, numberOfHours={instance.numberOfHours}). " + "Both use HUDManager.SetClock's (int)(t*60*hours)+360 minutes-since-midnight; ours renders 24h HH:MM, vanilla renders 12h + AM/PM.")); } } } internal static void ResetDiagnostics() { _loggedComparison = false; } } internal static class CctvScreenOutlineOverlay { private enum TargetKind { Item, Hostile, Player, Objective } private struct TargetSnapshot { public Bounds Bounds; public Transform Root; public TargetKind Kind; public int SourceId; public string Label; public TargetSnapshot(Bounds bounds, Transform root, TargetKind kind, int sourceId, string label) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) Bounds = bounds; Root = root; Kind = kind; SourceId = sourceId; Label = label; } } private struct VisibilityCacheEntry { public bool Visible; public float ExpiresAt; public VisibilityCacheEntry(bool visible, float expiresAt) { Visible = visible; ExpiresAt = expiresAt; } } private sealed class OutlineBox { private readonly RectTransform _root; private readonly Image _fill; private readonly Image[] _lines; private readonly RectTransform _labelRoot; private readonly Image _labelBackground; private readonly TextMeshProUGUI _labelText; public OutlineBox(RectTransform parent, Sprite lineSprite, int index) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_004c: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00ba: 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_00d0: 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_014e: 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_016c: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0225: 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_0243: 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_027a: 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_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Expected O, but got Unknown //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Expected O, but got Unknown //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"CCTV_TargetOutline_{index:00}"); val.transform.SetParent((Transform)(object)parent, false); InheritLayer(val, (Transform)(object)parent); _root = val.AddComponent(); _root.anchorMin = new Vector2(0.5f, 0.5f); _root.anchorMax = new Vector2(0.5f, 0.5f); _root.pivot = new Vector2(0.5f, 0.5f); GameObject val2 = new GameObject("ScanlineFill"); val2.transform.SetParent(val.transform, false); InheritLayer(val2, val.transform); RectTransform obj = val2.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; _fill = val2.AddComponent(); _fill.sprite = lineSprite; _fill.type = (Type)2; ((Graphic)_fill).raycastTarget = false; ((Component)_fill).gameObject.SetActive(false); _lines = (Image[])(object)new Image[4]; _lines[0] = CreateLine(val.transform, "Top", lineSprite, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, 0f), new Vector2(0f, 4.5f)); _lines[1] = CreateLine(val.transform, "Bottom", lineSprite, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 0f), new Vector2(0f, 4.5f)); _lines[2] = CreateLine(val.transform, "Left", lineSprite, new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 0.5f), new Vector2(0f, 0f), new Vector2(4.5f, 0f)); _lines[3] = CreateLine(val.transform, "Right", lineSprite, new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(1f, 0.5f), new Vector2(0f, 0f), new Vector2(4.5f, 0f)); GameObject val3 = new GameObject("TargetLabel"); val3.transform.SetParent(val.transform, false); InheritLayer(val3, val.transform); _labelRoot = val3.AddComponent(); _labelRoot.anchorMin = new Vector2(0f, 1f); _labelRoot.anchorMax = new Vector2(0f, 1f); _labelRoot.pivot = new Vector2(0f, 1f); _labelRoot.anchoredPosition = new Vector2(5f, -5f); _labelRoot.sizeDelta = new Vector2(148f, 18f); _labelBackground = val3.AddComponent(); ((Graphic)_labelBackground).color = new Color(0f, 0f, 0f, 0.58f); ((Graphic)_labelBackground).raycastTarget = false; GameObject val4 = new GameObject("Text"); val4.transform.SetParent(val3.transform, false); InheritLayer(val4, val3.transform); RectTransform obj2 = val4.AddComponent(); obj2.anchorMin = Vector2.zero; obj2.anchorMax = Vector2.one; obj2.offsetMin = new Vector2(4f, 0f); obj2.offsetMax = new Vector2(-4f, 0f); _labelText = val4.AddComponent(); ((TMP_Text)_labelText).fontSize = 10.5f; ((TMP_Text)_labelText).fontStyle = (FontStyles)1; ((TMP_Text)_labelText).alignment = (TextAlignmentOptions)4097; ((TMP_Text)_labelText).enableWordWrapping = false; ((TMP_Text)_labelText).overflowMode = (TextOverflowModes)0; ((Graphic)_labelText).raycastTarget = false; SetActive(active: false); } public void Set(Vector2 position, Vector2 size, Color color, string label) { //IL_000d: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0096: Unknown result type (might be due to invalid IL or missing references) SetActive(active: true); _root.anchoredPosition = position; _root.sizeDelta = size; if ((Object)(object)_fill != (Object)null) { ((Graphic)_fill).color = Color.clear; } Color color2 = color; color2.a = 1f; for (int i = 0; i < _lines.Length; i++) { ((Graphic)_lines[i]).color = color2; } if ((Object)(object)_labelText != (Object)null) { ((TMP_Text)_labelText).text = label ?? string.Empty; ((Graphic)_labelText).color = color2; } if ((Object)(object)_labelBackground != (Object)null) { ((Behaviour)_labelBackground).enabled = !string.IsNullOrEmpty(label); } if ((Object)(object)_labelRoot != (Object)null) { ((Component)_labelRoot).gameObject.SetActive(!string.IsNullOrEmpty(label)); } } public void SetActive(bool active) { if ((Object)(object)_root != (Object)null && ((Component)_root).gameObject.activeSelf != active) { ((Component)_root).gameObject.SetActive(active); } } private static Image CreateLine(Transform parent, string name, Sprite sprite, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 position, Vector2 size) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //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_0030: 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_003f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); InheritLayer(val, parent); RectTransform obj = val.AddComponent(); obj.anchorMin = anchorMin; obj.anchorMax = anchorMax; obj.pivot = pivot; obj.anchoredPosition = position; obj.sizeDelta = size; Image obj2 = val.AddComponent(); obj2.sprite = sprite; obj2.type = (Type)2; obj2.preserveAspect = false; ((Graphic)obj2).raycastTarget = false; return obj2; } private static void InheritLayer(GameObject go, Transform parent) { if ((Object)(object)go != (Object)null && (Object)(object)parent != (Object)null) { go.layer = ((Component)parent).gameObject.layer; } } } private const float RefreshIntervalSeconds = 0.55f; private const float LayoutIntervalSeconds = 1f / 12f; private const float VisibilityCacheSeconds = 0.18f; private const float MaxTargetDistanceMeters = 60f; private const int MaxBoxes = 28; private const float MinBoxPixels = 18f; private const float BoxPaddingPixels = 8f; private const float LineThicknessPixels = 4.5f; private const float LineAlpha = 1f; private const float LineOfSightOriginOffset = 0.08f; private const float MinSampleExtentMeters = 0.12f; private const float LabelWidthPixels = 148f; private const float LabelHeightPixels = 18f; private const float LabelInsetPixels = 5f; private const int MaxLabelCharacters = 18; private static readonly Color ObjectiveColor = new Color(1f, 0.86f, 0.1f, 1f); private static readonly Color HostileColor = new Color(1f, 0.06f, 0.04f, 1f); private static readonly Color ItemColor = new Color(0.1f, 1f, 0.28f, 1f); private static readonly Color PlayerColor = Color.white; private static readonly List _targets = new List(160); private static readonly Dictionary _targetIndexByRoot = new Dictionary(160); private static readonly Dictionary _visibilityBySourceId = new Dictionary(160); private static readonly List _boxes = new List(28); private static readonly List _scratchRenderers = new List(16); private static RectTransform _root; private static Texture2D _scanlineTexture; private static Sprite _scanlineSprite; private static float _nextRefreshAt; private static float _nextLayoutAt; private static int _lastCameraId; private static int _cachedLineOfSightCameraId = int.MinValue; private static int _cachedLineOfSightMask; private static string _lastTargetSummary; private static string _lastVisibilitySummary; internal static void Initialize(Transform parent) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)parent == (Object)null) { return; } if ((Object)(object)_root != (Object)null) { AttachRoot(parent); return; } _root = new GameObject("CCTV_TargetScreenOutlines").AddComponent(); AttachRoot(parent); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] CCTV screen-space outline overlay initialized."); } } internal static void Shutdown() { HideAll(); _targets.Clear(); _targetIndexByRoot.Clear(); _visibilityBySourceId.Clear(); CctvTargetCache.Clear(); _lastTargetSummary = null; _lastVisibilitySummary = null; _lastCameraId = 0; _cachedLineOfSightCameraId = int.MinValue; _cachedLineOfSightMask = 0; if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)((Component)_root).gameObject); _root = null; } if ((Object)(object)_scanlineTexture != (Object)null) { Object.Destroy((Object)(object)_scanlineTexture); _scanlineTexture = null; _scanlineSprite = null; } } internal static void Tick(bool focused) { //IL_00fe: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0129: 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_0142: 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_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016f: 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) if ((Object)(object)_root == (Object)null || !focused || MonitorFocus.IsTurretPageActive) { HideAll(); _nextLayoutAt = 0f; return; } if (Time.unscaledTime >= _nextRefreshAt) { _nextRefreshAt = Time.unscaledTime + 0.55f; RefreshTargets(); } int num = 0; int num2 = 0; int num3 = 0; CCTVCamera boundCamera = QuadCameraAssignment.GetBoundCamera(0); Camera val = (((Object)(object)boundCamera != (Object)null) ? boundCamera.Cam : null); if ((Object)(object)val == (Object)null) { HideUnused(num); MaybeLogVisibilitySummary(num2, num, num3); return; } int instanceID = ((Object)val).GetInstanceID(); if (instanceID != _lastCameraId) { _lastCameraId = instanceID; _visibilityBySourceId.Clear(); _cachedLineOfSightCameraId = int.MinValue; _cachedLineOfSightMask = 0; _nextLayoutAt = 0f; } if (!TryGetTargetPaneGeometry(0, out var center, out var size)) { HideUnused(num); MaybeLogVisibilitySummary(num2, num, num3); } else { if (Time.unscaledTime < _nextLayoutAt) { return; } _nextLayoutAt = Time.unscaledTime + 1f / 12f; Vector3 position = ((Component)val).transform.position; for (int i = 0; i < _targets.Count; i++) { if (num >= 28) { break; } TargetSnapshot target = _targets[i]; Vector3 val2 = ((Bounds)(ref target.Bounds)).center - position; if (!(((Vector3)(ref val2)).sqrMagnitude > 3600f) && TryProjectBounds(val, target.Bounds, out var viewportRect)) { num2++; if (!IsTargetVisibleToCameraCached(val, target)) { num3++; } else if (ApplyBox(EnsureBox(num), center, size, viewportRect, ColorForKind(target.Kind), target.Label)) { num++; } } } HideUnused(num); MaybeLogVisibilitySummary(num2, num, num3); } } private static void RefreshTargets() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) _targets.Clear(); _targetIndexByRoot.Clear(); CctvTargetCache.RefreshIfDue(); IReadOnlyList screenTargets = CctvTargetCache.ScreenTargets; for (int i = 0; i < screenTargets.Count; i++) { CctvTargetCache.ScreenTarget screenTarget = screenTargets[i]; if (ShouldDrawScreenBox(screenTarget.Kind) && (!screenTarget.TracksRoot || !((Object)(object)screenTarget.Root == (Object)null))) { _targets.Add(new TargetSnapshot(screenTarget.ResolveCurrentBounds(), screenTarget.Root, ToTargetKind(screenTarget.Kind), screenTarget.SourceId, screenTarget.Label)); } } string text = $"targets={_targets.Count}"; if (ShouldLogDiagnostics() && text != _lastTargetSummary) { _lastTargetSummary = text; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] CCTV screen-space outline summary " + text + ".")); } } } private static void AttachRoot(Transform parent) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null) && !((Object)(object)parent == (Object)null)) { ((Transform)_root).SetParent(parent, false); _root.anchorMin = Vector2.zero; _root.anchorMax = Vector2.one; _root.offsetMin = Vector2.zero; _root.offsetMax = Vector2.zero; ((Transform)_root).localRotation = Quaternion.identity; ((Transform)_root).localScale = Vector3.one; SetLayerRecursive(((Component)_root).gameObject, ((Component)parent).gameObject.layer); ((Transform)_root).SetAsLastSibling(); } } private static bool ShouldDrawScreenBox(CctvTargetCache.TargetKind kind) { return kind == CctvTargetCache.TargetKind.Objective; } private static bool TryGetTargetPaneGeometry(int slot, out Vector2 center, out Vector2 size) { if (CCTVVanillaMonitorDisplay.TryGetCctvPaneGeometry(out center, out size)) { return true; } return MonitorFocus.TryGetOverlayPaneGeometry(slot, out center, out size); } private static TargetKind ToTargetKind(CctvTargetCache.TargetKind kind) { return kind switch { CctvTargetCache.TargetKind.Objective => TargetKind.Objective, CctvTargetCache.TargetKind.Player => TargetKind.Player, CctvTargetCache.TargetKind.Hostile => TargetKind.Hostile, _ => TargetKind.Item, }; } private static void CollectSystemTargets() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) List activeTargets = CctvCommandTargetBridge.GetActiveTargets(); for (int i = 0; i < activeTargets.Count; i++) { CctvCommandTargetBridge.TargetInfo targetInfo = activeTargets[i]; if (targetInfo != null && !((Object)(object)targetInfo.Component == (Object)null)) { AddRootTarget(targetInfo.Component.gameObject, TargetKind.Objective, targetInfo.Position, targetInfo.Radius, targetInfo.DisplayName); } } TryAddTypeTargets("MainframeSupport", TargetKind.Objective); TryAddRadarBoosterTargets(); } private static void CollectEntranceTargets() { //IL_0039: 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) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) EntranceTeleport[] array = Object.FindObjectsOfType(false); foreach (EntranceTeleport val in array) { if (!((Object)(object)val == (Object)null)) { Vector3 fallbackPosition = (((Object)(object)val.entrancePoint != (Object)null) ? val.entrancePoint.position : ((Component)val).transform.position); AddRootTarget(((Component)val).gameObject, TargetKind.Objective, fallbackPosition, (val.entranceId == 0) ? 1.25f : 0.95f, (val.entranceId == 0) ? "MAIN ENTRANCE" : "FIRE EXIT"); } } } private static void CollectContractObjectiveTargets() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) IReadOnlyList markers = ContractObjectiveProvider.GetMarkers(); for (int i = 0; i < markers.Count; i++) { ContractObjectiveProvider.MarkerSnapshot markerSnapshot = markers[i]; if (!markerSnapshot.IsComplete) { AddBoundsTarget(new Bounds(markerSnapshot.Position, Vector3.one * Mathf.Max(0.7f, markerSnapshot.Radius * 2f)), TargetKind.Objective, markerSnapshot.Label); } } } private static void CollectPlayerTargets() { //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) //IL_007b: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null || array.Length == 0) { array = Object.FindObjectsOfType(false); } foreach (PlayerControllerB val in array) { if (!((Object)(object)val == (Object)null) && !val.isPlayerDead && (val.isPlayerControlled || val.isHostPlayerObject)) { string label = ((!string.IsNullOrWhiteSpace(val.playerUsername)) ? val.playerUsername : "PLAYER"); AddRootTarget(((Component)val).gameObject, TargetKind.Player, ((Component)val).transform.position + Vector3.up, 0.85f, label); } } } private static void CollectHostileTargets() { //IL_0079: 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_0083: Unknown result type (might be due to invalid IL or missing references) EnemyAI[] array = Object.FindObjectsOfType(false); foreach (EnemyAI val in array) { if (!((Object)(object)val == (Object)null) && !val.isEnemyDead && !val.isInsidePlayerShip && !val.isOutside) { string label = (((Object)(object)val.enemyType != (Object)null && !string.IsNullOrWhiteSpace(val.enemyType.enemyName)) ? val.enemyType.enemyName : ((object)val).GetType().Name); AddRootTarget(((Component)val).gameObject, TargetKind.Hostile, ((Component)val).transform.position + Vector3.up, 1f, label); } } } private static void CollectItemTargets() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) GrabbableObject[] array = Object.FindObjectsOfType(false); foreach (GrabbableObject val in array) { if (!((Object)(object)val == (Object)null) && !val.isHeldByEnemy && !((Object)(object)val.itemProperties == (Object)null) && !val.isInShipRoom && !val.isInElevator) { TargetKind targetKind = (IsRadarSystem(((Component)val).gameObject, ((object)val).GetType()) ? TargetKind.Objective : TargetKind.Item); string text = (((Object)(object)val.itemProperties != (Object)null && !string.IsNullOrWhiteSpace(val.itemProperties.itemName)) ? val.itemProperties.itemName : ((Object)((Component)val).gameObject).name); AddRootTarget(((Component)val).gameObject, targetKind, ((Component)val).transform.position, 0.45f, (targetKind == TargetKind.Objective) ? "RADAR" : text); } } } private static void TryAddTypeTargets(string typeName, TargetKind kind) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) Type type = Type.GetType("Y4NGZCompany.Facility.Mainframe." + typeName + ", LethalCCTV", throwOnError: false); if (type == null) { return; } Object[] array = Object.FindObjectsOfType(type); foreach (Object obj in array) { Component val = (Component)(object)((obj is Component) ? obj : null); if (!((Object)(object)val == (Object)null)) { AddRootTarget(val.gameObject, kind, val.transform.position, 1f, CleanTypeLabel(typeName)); } } } private static void TryAddRadarBoosterTargets() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) Type type = Type.GetType("RadarBoosterItem, Assembly-CSharp", throwOnError: false); if (type == null) { return; } Object[] array = Object.FindObjectsOfType(type); foreach (Object obj in array) { Component val = (Component)(object)((obj is Component) ? obj : null); if (!((Object)(object)val == (Object)null)) { AddRootTarget(val.gameObject, TargetKind.Objective, val.transform.position, 0.9f, "RADAR"); } } } private static void AddRootTarget(GameObject root, TargetKind kind, Vector3 fallbackPosition, float fallbackRadius, string label = null) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_0040: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { AddBoundsTarget(new Bounds(fallbackPosition, Vector3.one * Mathf.Max(0.4f, fallbackRadius * 2f)), kind, label); return; } if (!TryResolveRendererBounds(root, out var bounds)) { ((Bounds)(ref bounds))..ctor(fallbackPosition, Vector3.one * Mathf.Max(0.4f, fallbackRadius * 2f)); } int instanceID = ((Object)root).GetInstanceID(); if (_targetIndexByRoot.TryGetValue(instanceID, out var value)) { TargetSnapshot value2 = _targets[value]; ((Bounds)(ref value2.Bounds)).Encapsulate(bounds); if (Priority(kind) > Priority(value2.Kind)) { value2.Kind = kind; } if (string.IsNullOrEmpty(value2.Label)) { value2.Label = NormalizeLabel(label, ((Object)root).name, kind); } _targets[value] = value2; } else { _targetIndexByRoot[instanceID] = _targets.Count; _targets.Add(new TargetSnapshot(bounds, root.transform, kind, instanceID, NormalizeLabel(label, ((Object)root).name, kind))); } } private static void AddBoundsTarget(Bounds bounds, TargetKind kind, string label = null) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) _targets.Add(new TargetSnapshot(bounds, null, kind, -_targets.Count - 1, NormalizeLabel(label, null, kind))); } private static bool TryResolveRendererBounds(GameObject root, out Bounds bounds) { //IL_0001: 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_003c: 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) bounds = default(Bounds); bool flag = false; _scratchRenderers.Clear(); root.GetComponentsInChildren(true, _scratchRenderers); for (int i = 0; i < _scratchRenderers.Count; i++) { Renderer val = _scratchRenderers[i]; if (IsEligibleRenderer(val)) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } return flag; } private static bool TryProjectBounds(Camera camera, Bounds bounds, out Rect viewportRect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0079: 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_008b: 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_0197: 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_009d: 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_00b3: 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_00ba: 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_00d8: 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_00f7: Unknown result type (might be due to invalid IL or missing references) viewportRect = default(Rect); if ((Object)(object)camera == (Object)null) { return false; } if (camera.WorldToViewportPoint(((Bounds)(ref bounds)).center).z <= camera.nearClipPlane) { return false; } Vector3 min = ((Bounds)(ref bounds)).min; Vector3 max = ((Bounds)(ref bounds)).max; float num = float.PositiveInfinity; float num2 = float.NegativeInfinity; float num3 = float.PositiveInfinity; float num4 = float.NegativeInfinity; int num5 = 0; Vector3 val = default(Vector3); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { ((Vector3)(ref val))..ctor((i == 0) ? min.x : max.x, (j == 0) ? min.y : max.y, (k == 0) ? min.z : max.z); Vector3 val2 = camera.WorldToViewportPoint(val); if (!(val2.z <= camera.nearClipPlane)) { num = Mathf.Min(num, val2.x); num2 = Mathf.Max(num2, val2.x); num3 = Mathf.Min(num3, val2.y); num4 = Mathf.Max(num4, val2.y); num5++; } } } } if (num5 == 0) { return false; } if (num2 < 0f || num > 1f || num4 < 0f || num3 > 1f) { return false; } num = Mathf.Clamp01(num); num2 = Mathf.Clamp01(num2); num3 = Mathf.Clamp01(num3); num4 = Mathf.Clamp01(num4); if (num2 <= num || num4 <= num3) { return false; } viewportRect = Rect.MinMaxRect(num, num3, num2, num4); return true; } private static bool IsTargetVisibleToCamera(Camera camera, TargetSnapshot target) { //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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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) //IL_0052: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00e3: 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_00e5: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0134: 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_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_015c: 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_016e: 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_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)camera == (Object)null) { return false; } Vector3 size = ((Bounds)(ref target.Bounds)).size; if (((Vector3)(ref size)).sqrMagnitude <= 1E-06f) { return false; } Transform transform = ((Component)camera).transform; Vector3 origin = transform.position + transform.forward * 0.08f; Bounds bounds = target.Bounds; Vector3 center = ((Bounds)(ref bounds)).center; Vector3 extents = ((Bounds)(ref bounds)).extents; extents.x = Mathf.Max(extents.x, 0.12f); extents.y = Mathf.Max(extents.y, 0.12f); extents.z = Mathf.Max(extents.z, 0.12f); if (HasClearCameraLine(camera, target, origin, center)) { return true; } if (HasClearCameraLine(camera, target, origin, center + new Vector3(extents.x, 0f, 0f))) { return true; } if (HasClearCameraLine(camera, target, origin, center - new Vector3(extents.x, 0f, 0f))) { return true; } if (HasClearCameraLine(camera, target, origin, center + new Vector3(0f, extents.y, 0f))) { return true; } if (HasClearCameraLine(camera, target, origin, center - new Vector3(0f, extents.y, 0f))) { return true; } if (HasClearCameraLine(camera, target, origin, center + new Vector3(0f, 0f, extents.z))) { return true; } if (HasClearCameraLine(camera, target, origin, center - new Vector3(0f, 0f, extents.z))) { return true; } return false; } private static bool IsTargetVisibleToCameraCached(Camera camera, TargetSnapshot target) { float unscaledTime = Time.unscaledTime; if (_visibilityBySourceId.TryGetValue(target.SourceId, out var value) && unscaledTime < value.ExpiresAt) { return value.Visible; } bool flag = IsTargetVisibleToCamera(camera, target); _visibilityBySourceId[target.SourceId] = new VisibilityCacheEntry(flag, unscaledTime + 0.18f); return flag; } private static bool HasClearCameraLine(Camera camera, TargetSnapshot target, Vector3 origin, Vector3 point) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_0008: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_004d: 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_006d: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) Vector3 val = camera.WorldToViewportPoint(point); if (val.z <= camera.nearClipPlane || val.x < 0f || val.x > 1f || val.y < 0f || val.y > 1f) { return false; } Vector3 val2 = point - origin; float magnitude = ((Vector3)(ref val2)).magnitude; if (magnitude <= 0.05f) { return true; } int num = ResolveLineOfSightMask(camera); RaycastHit hit = default(RaycastHit); if (!Physics.Raycast(origin, val2 / magnitude, ref hit, magnitude, num, (QueryTriggerInteraction)1)) { return true; } return IsHitPartOfTarget(hit, target); } private static int ResolveLineOfSightMask(Camera camera) { int num = (((Object)(object)camera != (Object)null) ? ((Object)camera).GetInstanceID() : 0); if (_cachedLineOfSightCameraId == num && _cachedLineOfSightMask != 0) { return _cachedLineOfSightMask; } int num2 = (((Object)(object)camera != (Object)null && camera.cullingMask != 0) ? camera.cullingMask : (-5)); int num3 = LayerMask.NameToLayer("UI"); if (num3 >= 0) { num2 &= ~(1 << num3); } int num4 = LayerMask.NameToLayer("HelmetVisor"); if (num4 >= 0) { num2 &= ~(1 << num4); } _cachedLineOfSightCameraId = num; _cachedLineOfSightMask = num2; return num2; } private static bool IsHitPartOfTarget(RaycastHit hit, TargetSnapshot target) { Collider collider = ((RaycastHit)(ref hit)).collider; Transform root = target.Root; if ((Object)(object)collider == (Object)null || (Object)(object)root == (Object)null) { return false; } Transform transform = ((Component)collider).transform; if ((Object)(object)transform == (Object)null) { return false; } if (!((Object)(object)transform == (Object)(object)root) && !transform.IsChildOf(root)) { return root.IsChildOf(transform); } return true; } private static void MaybeLogVisibilitySummary(int projected, int visible, int occluded) { if (!ShouldLogDiagnostics()) { return; } string text = $"projected={projected} visible={visible} occluded={occluded}"; if (!(text == _lastVisibilitySummary)) { _lastVisibilitySummary = text; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] CCTV screen-space outline visibility " + text + ".")); } } } private static bool ShouldLogDiagnostics() { LethalCCTVConfig config = SurveillanceBootstrap.Config; if (config == null) { return false; } return config.ReconLoggingEnabled?.Value == true; } private static OutlineBox EnsureBox(int index) { while (_boxes.Count <= index && _boxes.Count < 28) { _boxes.Add(new OutlineBox(_root, EnsureScanlineSprite(), _boxes.Count)); } return _boxes[index]; } private static bool ApplyBox(OutlineBox box, Vector2 paneCenter, Vector2 paneSize, Rect viewportRect, Color color, string label) { //IL_000c: 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_003f: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(18f, ((Rect)(ref viewportRect)).width * paneSize.x + 16f); float num2 = Mathf.Max(18f, ((Rect)(ref viewportRect)).height * paneSize.y + 16f); if (num > paneSize.x * 0.78f || num2 > paneSize.y * 0.78f) { box.SetActive(active: false); return false; } Vector2 position = default(Vector2); ((Vector2)(ref position))..ctor(paneCenter.x + (((Rect)(ref viewportRect)).center.x - 0.5f) * paneSize.x, paneCenter.y + (((Rect)(ref viewportRect)).center.y - 0.5f) * paneSize.y); box.Set(position, new Vector2(num, num2), color, label); return true; } private static void HideUnused(int used) { for (int i = used; i < _boxes.Count; i++) { _boxes[i].SetActive(active: false); } } private static void HideAll() { for (int i = 0; i < _boxes.Count; i++) { _boxes[i].SetActive(active: false); } } private static bool IsEligibleRenderer(Renderer renderer) { if ((Object)(object)renderer == (Object)null || !renderer.enabled) { return false; } if (renderer is ParticleSystemRenderer) { return false; } if (renderer is LineRenderer) { return false; } if ((Object)(object)((Component)renderer).gameObject == (Object)null) { return false; } if ((Object)(object)((Component)renderer).GetComponentInParent() != (Object)null) { return false; } if ((((Object)((Component)renderer).gameObject).name ?? string.Empty).StartsWith("LethalCCTV_", StringComparison.OrdinalIgnoreCase)) { return false; } return true; } private static bool IsRadarSystem(GameObject root, Type type) { string text = ((type != null) ? type.Name : string.Empty); string text2 = (((Object)(object)root != (Object)null) ? ((Object)root).name : string.Empty); if (!Contains(text, "Radar")) { return Contains(text2, "Radar"); } return true; } private static bool Contains(string text, string needle) { if (!string.IsNullOrEmpty(text)) { return text.IndexOf(needle, StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static string NormalizeLabel(string label, string fallbackName, TargetKind kind) { string text = ((!string.IsNullOrWhiteSpace(label)) ? label : fallbackName); if (string.IsNullOrWhiteSpace(text)) { text = kind switch { TargetKind.Objective => "OBJECTIVE", TargetKind.Player => "PLAYER", TargetKind.Hostile => "HOSTILE", _ => "ITEM", }; } text = text.Replace("(Clone)", string.Empty).Replace("_", " ").Replace("-", " ") .Trim(); text = CollapseSpaces(text).ToUpperInvariant(); if (text.Length > 18) { text = text.Substring(0, 18); } return text; } private static string CleanTypeLabel(string typeName) { if (string.IsNullOrWhiteSpace(typeName)) { return null; } return typeName.Replace("Support", string.Empty).Replace("System", string.Empty); } private static string CollapseSpaces(string text) { if (string.IsNullOrEmpty(text)) { return string.Empty; } StringBuilder stringBuilder = null; bool flag = false; for (int i = 0; i < text.Length; i++) { char c = text[i]; bool flag2 = char.IsWhiteSpace(c); if (!(flag2 && flag)) { flag = flag2; if (stringBuilder != null) { stringBuilder.Append(flag2 ? ' ' : c); } else if (flag2 && c != ' ') { stringBuilder = new StringBuilder(text.Length); stringBuilder.Append(text, 0, i); stringBuilder.Append(' '); } } } if (stringBuilder == null) { return text; } return stringBuilder.ToString(); } private static int Priority(TargetKind kind) { return kind switch { TargetKind.Objective => 4, TargetKind.Player => 3, TargetKind.Hostile => 2, _ => 1, }; } private static Color ColorForKind(TargetKind kind) { //IL_001c: 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_0016: 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) return (Color)(kind switch { TargetKind.Objective => ObjectiveColor, TargetKind.Hostile => HostileColor, TargetKind.Player => PlayerColor, _ => ItemColor, }); } private static Sprite EnsureScanlineSprite() { //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_0027: 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_003a: Expected O, but got Unknown //IL_00b0: 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_0079: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_scanlineSprite != (Object)null) { return _scanlineSprite; } _scanlineTexture = new Texture2D(1, 8, (TextureFormat)4, false) { name = "LethalCCTV_ScreenOutlineScanlines", filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)0 }; for (int i = 0; i < 8; i++) { float num; switch (i) { default: num = 0.26f; break; case 2: case 6: num = 0.58f; break; case 1: case 5: num = 1f; break; } float num2 = num; _scanlineTexture.SetPixel(0, i, new Color(1f, 1f, 1f, num2)); } _scanlineTexture.Apply(false, true); _scanlineSprite = Sprite.Create(_scanlineTexture, new Rect(0f, 0f, 1f, 8f), new Vector2(0.5f, 0.5f), 1f); return _scanlineSprite; } private static void SetLayerRecursive(GameObject root, int layer) { if (!((Object)(object)root == (Object)null)) { root.layer = layer; Transform transform = root.transform; for (int i = 0; i < transform.childCount; i++) { SetLayerRecursive(((Component)transform.GetChild(i)).gameObject, layer); } } } } internal static class CCTVShipSystemsBridge { private const string ApiTypeName = "Y4NGZCompany.ShipSystems.Layout.ShipSystemsApi"; private const float UpgradeCacheSeconds = 0.5f; private const float PowerStateCacheSeconds = 0.15f; private static Type _apiType; private static bool _resolved; private static readonly Dictionary _methodCache = new Dictionary(); private static bool _cachedHasBodycamsUpgrade; private static float _bodycamsCacheValidUntil; private static bool _cachedHasTurretUpgrade; private static float _turretCacheValidUntil; private static bool _cachedShipPowerOnline = true; private static float _shipPowerCacheValidUntil; private static bool _cachedQuotaPresentationActive; private static float _quotaPresentationCacheValidUntil; internal static bool IsAvailable { get { Resolve(); return _apiType != null; } } internal static bool CanUseRemoteOperations(out string reason) { reason = string.Empty; if (!IsAvailable) { return true; } if (InvokeBool("CanUseRemoteOperations", false)) { return true; } reason = InvokeString("GetRemoteOperationsBlockReason", "REMOTE OPS LOCKED"); return false; } internal static bool TrySpendRemoteOperationPower() { if (!IsAvailable) { return true; } return InvokeBool("TrySpendCctvRemotePower", false); } internal static bool HasBodycamsUpgrade() { float unscaledTime = Time.unscaledTime; if (unscaledTime < _bodycamsCacheValidUntil) { return _cachedHasBodycamsUpgrade; } _bodycamsCacheValidUntil = unscaledTime + 0.5f; _cachedHasBodycamsUpgrade = IsAvailable && (InvokeBool("HasBodycamsUpgrade", false) || InvokeBool("HasUpgrade", false, "Bodycams")); return _cachedHasBodycamsUpgrade; } internal static bool HasTurretUpgrade() { float unscaledTime = Time.unscaledTime; if (unscaledTime < _turretCacheValidUntil) { return _cachedHasTurretUpgrade; } _turretCacheValidUntil = unscaledTime + 0.5f; _cachedHasTurretUpgrade = IsAvailable && (InvokeBool("HasTurretUpgrade", false) || InvokeBool("HasUpgrade", false, "Turret")); return _cachedHasTurretUpgrade; } internal static bool TrySpendTurretShotPower() { if (!IsAvailable) { return false; } return InvokeBool("TrySpendTurretShotPower", false); } internal static float GetPowerFraction() { if (!IsAvailable) { return 1f; } return InvokeFloat("GetPowerFraction", 1f); } internal static bool IsShipPowerOnline() { float unscaledTime = Time.unscaledTime; if (unscaledTime < _shipPowerCacheValidUntil) { return _cachedShipPowerOnline; } _shipPowerCacheValidUntil = unscaledTime + 0.15f; _cachedShipPowerOnline = !IsAvailable || InvokeBool("IsShipPowerOnline", true); return _cachedShipPowerOnline; } internal static bool IsBatteryBroken() { if (!IsAvailable) { return false; } return InvokeBool("IsBatteryBroken", false); } internal static bool IsPrimaryMonitorTakeoverActive() { if (!IsAvailable) { return false; } return InvokeBool("IsPrimaryMonitorTakeoverActive", false); } internal static bool IsQuotaPresentationActive() { float unscaledTime = Time.unscaledTime; if (unscaledTime < _quotaPresentationCacheValidUntil) { return _cachedQuotaPresentationActive; } _quotaPresentationCacheValidUntil = unscaledTime + 0.15f; _cachedQuotaPresentationActive = IsAvailable && InvokeBool("IsQuotaPresentationActive", false); return _cachedQuotaPresentationActive; } internal static void NoteTurretShotAccepted() { if (IsAvailable) { InvokeVoid("NoteTurretShotAccepted"); } } internal static string GetCurrentLayoutName() { if (!IsAvailable) { return "Vanilla"; } return InvokeString("GetCurrentLayoutName", "Vanilla"); } internal static bool IsPowerMonitorDisplayEnabled() { if (!IsAvailable) { return false; } return InvokeBool("IsPowerMonitorDisplayEnabled", false); } internal static bool TryUseSignalBeacon() { if (!IsAvailable) { return false; } return InvokeBool("TryUseSignalBeacon", false); } internal static bool TryUseSpeakerHijack() { if (!IsAvailable) { return false; } return InvokeBool("TryUseSpeakerHijack", false); } internal static void BeginExternalMonitorTakeover() { if (IsAvailable) { if (GetApiMethod("BeginPrimaryMonitorTakeover") != null) { InvokeVoid("BeginPrimaryMonitorTakeover"); } else { InvokeVoid("BeginExternalMonitorTakeover"); } } } internal static void EndExternalMonitorTakeover() { if (IsAvailable) { if (GetApiMethod("EndPrimaryMonitorTakeover") != null) { InvokeVoid("EndPrimaryMonitorTakeover"); } else { InvokeVoid("EndExternalMonitorTakeover"); } } } internal static void ForceRebindPowerDisplay() { if (IsAvailable) { InvokeVoid("ForceRebindPowerDisplay"); } } private static void Resolve() { if (!_resolved) { _resolved = true; _apiType = CompanyAssemblyBridge.ResolveType("Y4NGZCompany.ShipSystems.Layout.ShipSystemsApi"); if (_apiType != null) { _methodCache.Clear(); } } } private static MethodInfo GetApiMethod(string methodName) { if (_apiType == null || string.IsNullOrEmpty(methodName)) { return null; } if (_methodCache.TryGetValue(methodName, out var value)) { return value; } MethodInfo method = _apiType.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public); _methodCache[methodName] = method; return method; } private static bool InvokeBool(string methodName, bool defaultValue, params object[] args) { try { MethodInfo apiMethod = GetApiMethod(methodName); if (apiMethod == null) { return defaultValue; } return (apiMethod.Invoke(null, args ?? Array.Empty()) is bool flag) ? flag : defaultValue; } catch { return defaultValue; } } private static string InvokeString(string methodName, string defaultValue) { try { MethodInfo apiMethod = GetApiMethod(methodName); if (apiMethod == null) { return defaultValue; } return (apiMethod.Invoke(null, Array.Empty()) as string) ?? defaultValue; } catch { return defaultValue; } } private static float InvokeFloat(string methodName, float defaultValue) { try { MethodInfo apiMethod = GetApiMethod(methodName); if (apiMethod == null) { return defaultValue; } object obj = apiMethod.Invoke(null, Array.Empty()); if (obj is float result) { return result; } if (obj is double num) { return (float)num; } return defaultValue; } catch { return defaultValue; } } private static void InvokeVoid(string methodName) { try { GetApiMethod(methodName)?.Invoke(null, Array.Empty()); } catch { } } } public static class CCTVStationEvents { public static event Action ChairEntered; public static event Action ChairExited; public static event Action CameraSelected; public static event Action CameraControlChanged; public static event Action JoystickMoved; public static event Action ActionButtonPressed; public static event Action RadarViewChanged; internal static void RaiseChairEntered(PlayerControllerB player) { SafeRaise(delegate { CCTVStationEvents.ChairEntered?.Invoke(player); }, "ChairEntered"); } internal static void RaiseChairExited(PlayerControllerB player) { SafeRaise(delegate { CCTVStationEvents.ChairExited?.Invoke(player); }, "ChairExited"); } internal static void RaiseCameraSelected(int slot) { SafeRaise(delegate { CCTVStationEvents.CameraSelected?.Invoke(slot); }, "CameraSelected"); } internal static void RaiseCameraControlChanged(bool controllingCamera) { SafeRaise(delegate { CCTVStationEvents.CameraControlChanged?.Invoke(controllingCamera); }, "CameraControlChanged"); } internal static void RaiseJoystickMoved(Vector2 appliedDeltaDeg) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) Vector2 direction = CCTVJoystickPhaseDriver.QuantizeCardinal(appliedDeltaDeg); SafeRaise(delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) CCTVStationEvents.JoystickMoved?.Invoke(direction); }, "JoystickMoved"); } internal static void RaiseActionButtonPressed(string actionId) { SafeRaise(delegate { CCTVStationEvents.ActionButtonPressed?.Invoke(actionId); }, "ActionButtonPressed"); } internal static void RaiseRadarViewChanged(bool lookingAtRadar) { SafeRaise(delegate { CCTVStationEvents.RadarViewChanged?.Invoke(lookingAtRadar); }, "RadarViewChanged"); } private static void SafeRaise(Action raise, string eventName) { try { raise(); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] CCTVStationEvents." + eventName + " subscriber threw: " + ex.Message)); } } } } internal sealed class CCTVJoystickPhaseDriver { internal const float DefaultTransitionSeconds = 0.16f; private readonly float _transitionSeconds; private Vector2 _value; private Vector2 _requested; private Vector2 _from; private Vector2 _to; private Vector2 _queued; private float _elapsed; private bool _transitioning; internal Vector2 Requested => _requested; internal CCTVJoystickPhaseDriver(float transitionSeconds = 0.16f) { _transitionSeconds = Mathf.Max(0.01f, transitionSeconds); } internal void Reset() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //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) _value = Vector2.zero; _requested = Vector2.zero; _from = Vector2.zero; _to = Vector2.zero; _queued = Vector2.zero; _elapsed = 0f; _transitioning = false; } internal void SetRequested(Vector2 direction) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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) //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_0019: Unknown result type (might be due to invalid IL or missing references) direction = QuantizeCardinal(direction); if (!SameDirection(_requested, direction)) { _requested = direction; ReplanForRequest(); } } internal void SetImmediate(Vector2 direction) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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) //IL_000a: 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_0011: 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_0018: 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_001f: 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_002a: Unknown result type (might be due to invalid IL or missing references) direction = QuantizeCardinal(direction); _value = direction; _requested = direction; _from = direction; _to = direction; _queued = Vector2.zero; _elapsed = 0f; _transitioning = false; } internal Vector2 Tick(float dt) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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) //IL_0022: 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_00de: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00be: 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_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_00d0: Unknown result type (might be due to invalid IL or missing references) if (!_transitioning) { if (!SameDirection(_value, _requested)) { StartTransitionForRequest(); } return _value; } _elapsed += Mathf.Max(0f, dt); float num = Mathf.Clamp01(_elapsed / _transitionSeconds); float num2 = num * num * (3f - 2f * num); _value = Vector2.Lerp(_from, _to, num2); if (num >= 1f) { _value = _to; _transitioning = false; if (!SameDirection(_queued, Vector2.zero) && SameDirection(_queued, _requested)) { Vector2 queued = _queued; _queued = Vector2.zero; StartTransition(queued); } else { _queued = Vector2.zero; if (!SameDirection(_value, _requested)) { StartTransitionForRequest(); } } } return _value; } private void ReplanForRequest() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if (!_transitioning) { StartTransitionForRequest(); } else if (SameDirection(_requested, Vector2.zero)) { _queued = Vector2.zero; if (!SameDirection(_to, Vector2.zero)) { StartTransition(Vector2.zero); } } else if (SameDirection(_requested, _to)) { _queued = Vector2.zero; } else if (SameDirection(_to, Vector2.zero)) { _queued = _requested; } else { _queued = _requested; StartTransition(Vector2.zero); } } private void StartTransitionForRequest() { //IL_0001: 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_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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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) //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_0045: Unknown result type (might be due to invalid IL or missing references) if (!SameDirection(_value, _requested)) { if (!SameDirection(_value, Vector2.zero) && !SameDirection(_requested, Vector2.zero)) { _queued = _requested; StartTransition(Vector2.zero); } else { _queued = Vector2.zero; StartTransition(_requested); } } } private void StartTransition(Vector2 target) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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) //IL_000e: 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_0045: 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_004c: 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_0018: 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_001f: 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_0026: Unknown result type (might be due to invalid IL or missing references) target = QuantizeCardinal(target); if (SameDirection(_value, target)) { _value = target; _from = target; _to = target; _elapsed = 0f; _transitioning = false; } else { _from = _value; _to = target; _elapsed = 0f; _transitioning = true; } } internal static Vector2 QuantizeCardinal(Vector2 input) { //IL_0014: 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) //IL_000e: 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_0052: 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) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (((Vector2)(ref input)).sqrMagnitude < 1E-08f) { return Vector2.zero; } if (Mathf.Abs(input.x) >= Mathf.Abs(input.y)) { return new Vector2(Mathf.Sign(input.x), 0f); } return new Vector2(0f, Mathf.Sign(input.y)); } private static bool SameDirection(Vector2 a, Vector2 b) { //IL_0000: 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_0019: 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) if (Mathf.Abs(a.x - b.x) < 0.001f) { return Mathf.Abs(a.y - b.y) < 0.001f; } return false; } } internal sealed class CCTVStationPlacementEditor { private const float ViewOrbitSensitivity = 0.18f; private const float ViewMinPitch = -35f; private const float ViewMaxPitch = 55f; private Transform _target; private string _targetName; private Vector3 _startLocalPosition; private Quaternion _startLocalRotation; private Vector3 _startLocalScale; private bool _active; private string _status = "ready"; private float _statusVisibleUntil; private float _viewYaw; private float _viewPitch; private bool _rotationInputLogged; private float _nextRotationInputLogAt; private PlayerControllerB _player; private Camera _camera; private bool _capturedInputState; private CursorLockMode _savedCursorLock; private bool _savedCursorVisible; private bool _savedDisableLook; private bool _savedDisableMove; private bool _capturedCameraTransform; private Vector3 _savedCameraLocalPosition; private Quaternion _savedCameraLocalRotation; private bool _liveFocusCameraMode; internal bool IsActive => _active; internal void Start(string targetName) { //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) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) if (!CCTVOperatorStation.TryGetDebugPlacementTarget(targetName, out var target, out var normalizedTarget)) { ShowStatus("CCTV placement target '" + (targetName ?? "chair") + "' unavailable", 3f, hudTip: true); return; } Cancel(); _target = target; _targetName = normalizedTarget; _startLocalPosition = target.localPosition; _startLocalRotation = target.localRotation; _startLocalScale = target.localScale; _liveFocusCameraMode = MonitorFocus.IsFocused && (normalizedTarget == "focus" || normalizedTarget == "radar" || normalizedTarget == "player"); _viewYaw = 0f; _viewPitch = 0f; _rotationInputLogged = false; _nextRotationInputLogAt = 0f; _active = true; BeginInputCapture(); if (!_liveFocusCameraMode) { EnsurePlacementCamera(); UpdatePlacementCameraPose(); } ShowStatus("editing CCTV " + _targetName, 2f, hudTip: true); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogMessage((object)$"[LethalCCTV][ViewEdit] started target={_targetName} pos={target.localPosition} euler={target.localEulerAngles} scale={target.localScale}."); } } internal void Tick() { //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0232: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) if (!_active || (Object)(object)_target == (Object)null) { return; } Keyboard current = Keyboard.current; if (current == null) { return; } if (((ButtonControl)current.enterKey).wasPressedThisFrame || ((ButtonControl)current.numpadEnterKey).wasPressedThisFrame) { Save(); return; } if (((ButtonControl)current.escapeKey).wasPressedThisFrame || ((ButtonControl)current.backspaceKey).wasPressedThisFrame || ((ButtonControl)current.deleteKey).wasPressedThisFrame) { Cancel(); return; } if (!_liveFocusCameraMode) { UpdateOrbitInput(); EnsurePlacementCamera(); UpdatePlacementCameraPose(); } float num = Mathf.Max(Time.unscaledDeltaTime, 0.001f); int num2; float num3; if (!((ButtonControl)current.leftShiftKey).isPressed) { num2 = (((ButtonControl)current.rightShiftKey).isPressed ? 1 : 0); if (num2 == 0) { num3 = 0.85f; goto IL_00c4; } } else { num2 = 1; } num3 = 4f; goto IL_00c4; IL_00c4: float num4 = num3; float num5 = ((num2 != 0) ? 1.4f : 0.35f); float num6 = ((num2 != 0) ? 120f : 42f); float num7 = ((num2 != 0) ? 1.2f : 0.35f); bool num8 = string.Equals(_targetName, "radar", StringComparison.OrdinalIgnoreCase); Vector3 val = Vector3.zero; if (!num8) { if (((ButtonControl)current.wKey).isPressed || ((ButtonControl)current.upArrowKey).isPressed) { val += GetEditForward(); } if (((ButtonControl)current.sKey).isPressed || ((ButtonControl)current.downArrowKey).isPressed) { val -= GetEditForward(); } if (((ButtonControl)current.dKey).isPressed || ((ButtonControl)current.rightArrowKey).isPressed) { val += GetEditRight(); } if (((ButtonControl)current.aKey).isPressed || ((ButtonControl)current.leftArrowKey).isPressed) { val -= GetEditRight(); } } float num9 = 0f; if (!num8) { if (((ButtonControl)current.spaceKey).isPressed || ((ButtonControl)current.eKey).isPressed || ((ButtonControl)current.pageUpKey).isPressed) { num9 += num5 * num; } if (((ButtonControl)current.leftCtrlKey).isPressed || ((ButtonControl)current.rightCtrlKey).isPressed || ((ButtonControl)current.qKey).isPressed || ((ButtonControl)current.pageDownKey).isPressed) { num9 -= num5 * num; } } Vector3 zero = Vector3.zero; if (((ButtonControl)current.iKey).isPressed || ((ButtonControl)current.fKey).isPressed) { zero.x -= num6 * num; } if (((ButtonControl)current.kKey).isPressed || ((ButtonControl)current.gKey).isPressed) { zero.x += num6 * num; } if (((ButtonControl)current.jKey).isPressed || ((ButtonControl)current.rKey).isPressed) { zero.y -= num6 * num; } if (((ButtonControl)current.lKey).isPressed || ((ButtonControl)current.tKey).isPressed) { zero.y += num6 * num; } if (((ButtonControl)current.uKey).isPressed || ((ButtonControl)current.zKey).isPressed) { zero.z -= num6 * num; } if (((ButtonControl)current.oKey).isPressed || ((ButtonControl)current.xKey).isPressed) { zero.z += num6 * num; } if (num8) { if (((ButtonControl)current.aKey).isPressed || ((ButtonControl)current.leftArrowKey).isPressed) { zero.y -= num6 * num; } if (((ButtonControl)current.dKey).isPressed || ((ButtonControl)current.rightArrowKey).isPressed) { zero.y += num6 * num; } } float num10 = 0f; if (!num8) { if (((ButtonControl)current.cKey).isPressed) { num10 -= num7 * num; } if (((ButtonControl)current.vKey).isPressed) { num10 += num7 * num; } } Vector3 val2 = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? (((Vector3)(ref val)).normalized * num4 * num) : Vector3.zero); if (Mathf.Abs(num9) > 0.0001f) { val2 += Vector3.up * num9; } if (((Vector3)(ref val2)).sqrMagnitude > 0f || ((Vector3)(ref zero)).sqrMagnitude > 1E-06f || Mathf.Abs(num10) > 0.0001f) { Nudge(val2, zero, num10); } } internal bool IsEditingTarget(string targetName) { if (_active) { return string.Equals(_targetName, NormalizeTargetForCompare(targetName), StringComparison.OrdinalIgnoreCase); } return false; } internal string GetStatus() { string text = (_active ? ("editing " + _targetName + " " + FormatSummary()) : ((Time.unscaledTime <= _statusVisibleUntil) ? _status : "ready")); string text2 = "CCTV station placement: " + text; if (_active) { bool flag = string.Equals(_targetName, "radar", StringComparison.OrdinalIgnoreCase); bool flag2 = string.Equals(_targetName, "focus", StringComparison.OrdinalIgnoreCase); text2 += (flag ? "\nControls ROTATION ONLY: A/D or arrows pivot, F/G pitch, R/T yaw, Z/X roll (I/K, J/L, U/O aliases), Enter save, Esc cancel" : (flag2 ? "\nControls WASD move, SPACE/CTRL height, F/G pitch, R/T yaw, Z/X roll (I/K, J/L, U/O aliases), Enter save, Esc cancel" : "\nControls WASD move, SPACE/CTRL height, F/G pitch, R/T yaw, Z/X roll (I/K, J/L, U/O aliases), C/V scale, MIDDLE-MOUSE orbit view, Enter save, Esc cancel")); } return text2; } internal void Cancel() { //IL_001e: 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_0040: Unknown result type (might be due to invalid IL or missing references) if (!_active) { return; } if ((Object)(object)_target != (Object)null) { _target.localPosition = _startLocalPosition; _target.localRotation = _startLocalRotation; _target.localScale = _startLocalScale; if (string.Equals(_targetName, "throttle", StringComparison.OrdinalIgnoreCase)) { CCTVOperatorStation.SyncThrottleSecondaryTargetsToPrimary(_target); } } _active = false; _liveFocusCameraMode = false; RestoreInputCapture(); ShowStatus("CCTV placement cancelled", 1.5f, hudTip: true); } internal void ShowStatus(string message, float seconds, bool hudTip = false) { _status = message ?? string.Empty; _statusVisibleUntil = Time.unscaledTime + Mathf.Max(0.1f, seconds); if (hudTip) { HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip("CCTV PLACEMENT", _status, false, false, "LC_Tip1"); } } } private void Save() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_target == (Object)null)) { if (string.Equals(_targetName, "radar", StringComparison.OrdinalIgnoreCase) && (Object)(object)CCTVOperatorStation.FocusViewAnchor != (Object)null) { _target.position = CCTVOperatorStation.FocusViewAnchor.position; } CCTVOperatorStation.SaveDebugPlacement(_targetName, _target); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogMessage((object)("[LethalCCTV][ViewEdit] saved target=" + _targetName + " " + FormatSummary() + ".")); } _active = false; _liveFocusCameraMode = false; RestoreInputCapture(); ShowStatus("CCTV placement saved", 2f, hudTip: true); } } private void Nudge(Vector3 worldDelta, Vector3 localEulerDelta, float scaleDelta) { //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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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) //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_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0182: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019a: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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_00ed: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_target == (Object)null) { return; } Transform target = _target; target.position += worldDelta; if (((Vector3)(ref localEulerDelta)).sqrMagnitude > 1E-06f) { if (string.Equals(_targetName, "focus", StringComparison.OrdinalIgnoreCase) || string.Equals(_targetName, "radar", StringComparison.OrdinalIgnoreCase)) { Quaternion val = _target.rotation; if (Mathf.Abs(localEulerDelta.y) > 1E-06f) { val = Quaternion.AngleAxis(localEulerDelta.y, Vector3.up) * val; } if (Mathf.Abs(localEulerDelta.x) > 1E-06f) { Vector3 val2 = val * Vector3.right; val = Quaternion.AngleAxis(localEulerDelta.x, val2) * val; } if (Mathf.Abs(localEulerDelta.z) > 1E-06f) { Vector3 val3 = val * Vector3.forward; val = Quaternion.AngleAxis(localEulerDelta.z, val3) * val; } _target.rotation = val; } else { _target.localRotation = Quaternion.Euler(_target.localEulerAngles + localEulerDelta); } if (!_rotationInputLogged || Time.unscaledTime >= _nextRotationInputLogAt) { _rotationInputLogged = true; _nextRotationInputLogAt = Time.unscaledTime + 0.5f; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { string text = $"[LethalCCTV][ViewEdit] rotation input target={_targetName} delta={localEulerDelta} "; object arg = _target.localEulerAngles; Quaternion rotation = _target.rotation; log.LogMessage((object)(text + $"localEuler={arg} worldEuler={((Quaternion)(ref rotation)).eulerAngles}.")); } } } if (Mathf.Abs(scaleDelta) > 0.0001f) { float num = Mathf.Max(0.01f, 1f + scaleDelta); _target.localScale = NormalizeScale(_target.localScale * num); } if (string.Equals(_targetName, "throttle", StringComparison.OrdinalIgnoreCase)) { CCTVOperatorStation.SyncThrottleSecondaryTargetsToPrimary(_target); } if (!_liveFocusCameraMode) { UpdatePlacementCameraPose(); } ShowStatus("editing CCTV " + _targetName + " " + FormatSummary(), 0.35f); } private Vector3 GetEditForward() { //IL_0033: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) Transform val = (((Object)(object)_camera != (Object)null) ? ((Component)_camera).transform : _target); Vector3 val2 = (((Object)(object)val != (Object)null) ? val.forward : Vector3.forward); val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.forward; } return ((Vector3)(ref val2)).normalized; } private Vector3 GetEditRight() { //IL_0033: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) Transform val = (((Object)(object)_camera != (Object)null) ? ((Component)_camera).transform : _target); Vector3 val2 = (((Object)(object)val != (Object)null) ? val.right : Vector3.right); val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.right; } return ((Vector3)(ref val2)).normalized; } private void BeginInputCapture() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = ResolvePlayer(); if (!((Object)(object)val == (Object)null)) { RestoreInputCapture(); _player = val; _savedCursorLock = Cursor.lockState; _savedCursorVisible = Cursor.visible; _savedDisableLook = val.disableLookInput; _savedDisableMove = val.disableMoveInput; val.disableLookInput = true; val.disableMoveInput = true; Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; _capturedInputState = true; } } private void RestoreInputCapture() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) RestoreCameraTransform(); if (_capturedInputState) { if ((Object)(object)_player != (Object)null) { _player.disableLookInput = _savedDisableLook; _player.disableMoveInput = _savedDisableMove; } Cursor.lockState = _savedCursorLock; Cursor.visible = _savedCursorVisible; } _capturedInputState = false; _player = null; _camera = null; } private void EnsurePlacementCamera() { //IL_0020: 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_0031: 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) Camera val = ResolveCamera(); if (!((Object)(object)val == (Object)null)) { if (!_capturedCameraTransform) { _savedCameraLocalPosition = ((Component)val).transform.localPosition; _savedCameraLocalRotation = ((Component)val).transform.localRotation; _capturedCameraTransform = true; } _camera = val; ((Behaviour)_camera).enabled = true; Camera camera = _camera; camera.cullingMask |= 1; } } private Camera ResolveCamera() { PlayerControllerB val = _player ?? ResolvePlayer(); if ((Object)(object)val?.gameplayCamera != (Object)null) { return val.gameplayCamera; } if ((Object)(object)Camera.main != (Object)null) { return Camera.main; } Camera[] array = Object.FindObjectsOfType(); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null && ((Behaviour)array[i]).enabled) { return array[i]; } } return null; } private static PlayerControllerB ResolvePlayer() { if ((Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null) { return GameNetworkManager.Instance.localPlayerController; } if (!((Object)(object)StartOfRound.Instance != (Object)null)) { return null; } return StartOfRound.Instance.localPlayerController; } private void UpdateOrbitInput() { //IL_001d: 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_0039: 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) Mouse current = Mouse.current; if (current != null && current.middleButton.isPressed) { Vector2 val = ((InputControl)(object)((Pointer)current).delta).ReadValue(); if (!(((Vector2)(ref val)).sqrMagnitude <= 0.0001f)) { _viewYaw += val.x * 0.18f; _viewPitch = Mathf.Clamp(_viewPitch - val.y * 0.18f, -35f, 55f); } } } private void UpdatePlacementCameraPose() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //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_0043: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_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_017b: 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_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_019f: 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_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) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_camera == (Object)null) && !((Object)(object)_target == (Object)null)) { if (!TryGetRendererBounds(_target, out var bounds)) { ((Bounds)(ref bounds))..ctor(_target.position + Vector3.up * 0.5f, new Vector3(1.2f, 1.2f, 1.2f)); } Vector3 center = ((Bounds)(ref bounds)).center; Vector3 forward = _target.forward; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 0.0001f) { forward = Vector3.forward; } ((Vector3)(ref forward)).Normalize(); float num = Mathf.Max(0.4f, Mathf.Max(((Bounds)(ref bounds)).size.x, ((Bounds)(ref bounds)).size.z)); float num2 = Mathf.Max(0.25f, ((Bounds)(ref bounds)).size.y); float num3 = Mathf.Clamp(num * 0.95f + num2 * 0.35f + 0.9f, 1.1f, 8f); float num4 = Mathf.Clamp(num2 * 0.45f + num * 0.08f, 0.25f, 3f); Vector3 val = Quaternion.AngleAxis(_viewYaw, Vector3.up) * forward; float num5 = Mathf.Clamp(_viewPitch, -35f, 55f) * (MathF.PI / 180f); float num6 = Mathf.Max(0.2f, num3 * Mathf.Cos(num5)); float num7 = num4 + num3 * Mathf.Sin(num5); Vector3 val2 = center + val * num6 + Vector3.up * num7; Vector3 val3 = center - val2; if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { val3 = -forward; } ((Component)_camera).transform.SetPositionAndRotation(val2, Quaternion.LookRotation(((Vector3)(ref val3)).normalized, Vector3.up)); } } private void RestoreCameraTransform() { //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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) if (_capturedCameraTransform) { if ((Object)(object)_camera != (Object)null) { ((Component)_camera).transform.localPosition = _savedCameraLocalPosition; ((Component)_camera).transform.localRotation = _savedCameraLocalRotation; } _capturedCameraTransform = false; _savedCameraLocalPosition = Vector3.zero; _savedCameraLocalRotation = Quaternion.identity; } } private static bool TryGetRendererBounds(Transform root, out Bounds bounds) { //IL_0001: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); if ((Object)(object)root == (Object)null) { return false; } Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); bool flag = false; foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } return flag; } private string FormatSummary() { //IL_001a: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_008c: 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_00a8: 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) if ((Object)(object)_target == (Object)null) { return string.Empty; } Vector3 localPosition = _target.localPosition; Vector3 localEulerAngles = _target.localEulerAngles; Vector3 localScale = _target.localScale; return $"pos=({localPosition.x:0.00},{localPosition.y:0.00},{localPosition.z:0.00}) rot=({localEulerAngles.x:0},{localEulerAngles.y:0},{localEulerAngles.z:0}) scale=({localScale.x:0.00},{localScale.y:0.00},{localScale.z:0.00})"; } private static Vector3 NormalizeScale(Vector3 scale) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) return new Vector3(Mathf.Clamp(scale.x, 0.05f, 5f), Mathf.Clamp(scale.y, 0.05f, 5f), Mathf.Clamp(scale.z, 0.05f, 5f)); } private static string NormalizeTargetForCompare(string targetName) { if (string.IsNullOrWhiteSpace(targetName)) { return "focus"; } string text = targetName.Trim().ToLowerInvariant(); switch (text) { case "seat": case "operator": case "operatorchair": return "chair"; case "stick": case "joy": case "joystick": case "control": return "throttle"; case "lever": case "startlever": case "shiplever": case "startmatchlever": case "brake": case "brakelever": case "throttlelever": case "gearstick": case "gear": case "sticklever": return "throttle"; case "view": case "camera": case "focusview": case "focusanchor": return "focus"; case "radar": case "radarview": case "radaranchor": case "radarfocus": case "spaceview": case "spacelook": return "radar"; case "player": case "playerroot": case "playerrootanchor": case "thirdperson": case "thirdpersonplayer": case "thirdpersonmodel": case "playermodel": case "model": case "root": return "player"; case "operatorpose": case "poseanchor": case "bodypose": return "pose"; case "button": case "accessbutton": case "cctvbutton": case "cctvaccessbutton": case "interactbutton": case "entrybutton": return "button"; default: return text; } } } internal static class CCTVStickyNoteItem { internal const string PrefabName = "Y4NGZ_CCTV_StickyNote"; private const string TextureResourceName = "Y4NGZ_CCTV_StickyNote.png"; private const string ItemDisplayName = "CCTV controls"; private const string VanillaItemName = "Sticky note"; private const string VanillaObjectName = "StickyNoteItem"; private const string SourceScene = "the in-scene vanilla note (a GrabbableObject whose itemName is 'Sticky note')"; private const string SourceCatalogue = "StartOfRound.allItemsList"; private const string SourceShipHierarchy = "a ship-hierarchy object named 'StickyNoteItem'"; private const float ExistingScanIntervalSeconds = 0.25f; private const float ResolveRetryIntervalSeconds = 2f; internal const float VanillaNoteScale = 0.104262345f; private static readonly Vector3 VanillaFlatRestingEuler = new Vector3(-90f, 0f, 0f); private const float RestoredIdentityRotationToleranceDeg = 1f; private const float RestoredAnchorAdoptionRadius = 0.5f; private static readonly Vector3 VanillaColliderSize = new Vector3(2.0155149f, 2.282906f, 0.3427938f); private static readonly Vector3 VanillaColliderCentre = new Vector3(-0.007757432f, 0.14145488f, 0.15767327f); private static bool _registrationAttempted; private static bool _lateBound; private static bool _spawnLogged; private static float _settleAt = -1f; private static float _nextExistingScanAt = -1f; private static float _nextResolveAttemptAt = -1f; private static bool _spawnPointWarned; private static GameObject _vanillaSource; private static string _resolvedFrom = "the in-scene vanilla note (a GrabbableObject whose itemName is 'Sticky note')"; private static CCTVStickyNoteProp _trackedNote; private static StartOfRound _spawnStateRound; private static Texture2D _texture; private static Material _material; private static Mesh _mesh; internal static GameObject Prefab { get; private set; } internal static Item ItemProperties { get; private set; } internal static bool Registered { get; private set; } internal static bool RegistrationFailed { get; private set; } internal static int VisualBindGeneration { get; private set; } internal static string DescribeResolutionSources() { return "the in-scene vanilla note (a GrabbableObject whose itemName is 'Sticky note'), StartOfRound.allItemsList, and a ship-hierarchy object named 'StickyNoteItem'"; } internal static void Register() { if (_registrationAttempted) { return; } _registrationAttempted = true; try { Prefab = BuildPrefab(); ItemProperties = BuildItemProperties(Prefab); ((GrabbableObject)Prefab.GetComponent()).itemProperties = ItemProperties; ItemProperties.spawnPrefab = Prefab; NetworkPrefabs.RegisterNetworkPrefab(Prefab); Items.RegisterItem(ItemProperties); Registered = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Registered the CCTV controls sticky note as a grabbable item."); } } catch (Exception ex) { RegistrationFailed = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] CCTV sticky note registration failed; forcing the operator controls overlay on as the fallback: " + ex.Message)); } if ((Object)(object)Prefab != (Object)null) { Object.DestroyImmediate((Object)(object)Prefab); } Prefab = null; ItemProperties = null; } } private static GameObject BuildPrefab() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0112: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Y4NGZ_CCTV_StickyNote"); val.SetActive(false); ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val); val.transform.localScale = Vector3.one * 0.104262345f; SetTagSafe(val, "PhysicsProp"); val.layer = ResolveLayer("Props", ResolveLayer("InteractableObject", 6)); NetworkObject obj = val.AddComponent(); obj.SynchronizeTransform = true; obj.SceneMigrationSynchronization = true; obj.SpawnWithObservers = true; obj.DontDestroyWithOwner = true; obj.AutoObjectParentSync = true; CctvFixtureAssets.AssignStableNetworkHash(obj, "StickyNote", "Y4NGZ_CCTV_StickyNote"); val.AddComponent(); MeshRenderer val2 = val.AddComponent(); ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)1; ((Renderer)val2).receiveShadows = true; Rigidbody val3 = val.AddComponent(); val3.isKinematic = true; val3.useGravity = false; val3.mass = 0.35f; val3.drag = 0.2f; val3.angularDrag = 5f; val3.interpolation = (RigidbodyInterpolation)1; val3.collisionDetectionMode = (CollisionDetectionMode)3; BoxCollider val4 = val.AddComponent(); ((Collider)val4).isTrigger = false; val4.size = VanillaColliderSize; val4.center = VanillaColliderCentre; AudioSource obj2 = val.AddComponent(); obj2.playOnAwake = false; obj2.spatialBlend = 1f; obj2.dopplerLevel = 0.3f; obj2.minDistance = 4f; obj2.maxDistance = 18f; CCTVStickyNoteProp cCTVStickyNoteProp = val.AddComponent(); ((GrabbableObject)cCTVStickyNoteProp).grabbable = true; ((GrabbableObject)cCTVStickyNoteProp).grabbableToEnemies = true; ((GrabbableObject)cCTVStickyNoteProp).isInFactory = false; ((GrabbableObject)cCTVStickyNoteProp).scrapValue = 0; ((GrabbableObject)cCTVStickyNoteProp).rotateObject = false; ((GrabbableObject)cCTVStickyNoteProp).propBody = val3; ((GrabbableObject)cCTVStickyNoteProp).propColliders = (Collider[])(object)new Collider[1] { (Collider)val4 }; ((GrabbableObject)cCTVStickyNoteProp).mainObjectRenderer = val2; BuildScanNode(val, val4); return val; } private static void BuildScanNode(GameObject root, BoxCollider pickupCollider) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_002e: 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_003f: 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) GameObject val = new GameObject("ScanNode"); val.transform.SetParent(root.transform, false); val.layer = ResolveLayer("ScanNode", 22); val.transform.localPosition = pickupCollider.center; BoxCollider obj = val.AddComponent(); ((Collider)obj).isTrigger = true; obj.size = pickupCollider.size; ScanNodeProperties obj2 = val.AddComponent(); obj2.headerText = "CCTV controls"; obj2.subText = "operator reference"; obj2.maxRange = 12; obj2.minRange = 1; obj2.requiresLineOfSight = true; obj2.nodeType = 0; obj2.creatureScanID = -1; obj2.scrapValue = 0; } private static Item BuildItemProperties(GameObject prefab) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) Item val = ScriptableObject.CreateInstance(); ((Object)val).name = "Y4NGZ CCTV Sticky Note Item"; val.itemName = "CCTV controls"; val.spawnPositionTypes = new List(); val.twoHanded = false; val.twoHandedAnimation = false; val.canBeGrabbedBeforeGameStart = true; val.disallowUtilitySlot = true; val.weight = 1f; val.itemSpawnsOnGround = false; val.isConductiveMetal = false; val.isScrap = false; val.creditsWorth = 0; val.minValue = 0; val.maxValue = 0; val.spawnPrefab = prefab; val.requiresBattery = false; val.grabAnimationTime = 0f; val.syncGrabFunction = false; val.syncUseFunction = false; val.syncDiscardFunction = false; val.toolTips = new string[1] { "Inspect: [Z]" }; val.verticalOffset = 0.05f; val.floorYOffset = 0; val.allowDroppingAheadOfPlayer = true; val.restingRotation = new Vector3(-90f, 0f, 0f); val.rotationOffset = new Vector3(96.65f, 15.8f, -90f); val.positionOffset = new Vector3(0.03f, 0.1f, -0.1f); val.meshOffset = false; val.canBeInspected = true; return val; } internal static bool TryResolveVisual(out Mesh mesh, out Material material) { if (_lateBound && ((Object)(object)_mesh == (Object)null || (Object)(object)_material == (Object)null)) { _lateBound = false; _vanillaSource = null; _nextResolveAttemptAt = -1f; } if (!_lateBound) { LateBind(); } mesh = _mesh; material = _material; if ((Object)(object)mesh != (Object)null) { return (Object)(object)material != (Object)null; } return false; } internal static bool TryResolveColliderShape(out Vector3 size, out Vector3 centre, out float scale) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_0062: Unknown result type (might be due to invalid IL or missing references) size = VanillaColliderSize; centre = VanillaColliderCentre; scale = 0.104262345f; MeshFilter filter; MeshRenderer renderer; GameObject val = FindVanillaPrefab(out filter, out renderer); if ((Object)(object)val == (Object)null) { return false; } BoxCollider component = val.GetComponent(); if ((Object)(object)component == (Object)null) { return true; } size = component.size; centre = component.center; float x = val.transform.localScale.x; if (x > 0.0001f) { scale = x; } return true; } private static GameObject FindVanillaPrefab(out MeshFilter filter, out MeshRenderer renderer) { if ((Object)(object)_vanillaSource != (Object)null && TryGetBorrowableVisual(_vanillaSource, out filter, out renderer)) { return _vanillaSource; } _vanillaSource = null; filter = null; renderer = null; if (Time.realtimeSinceStartup < _nextResolveAttemptAt) { return null; } _nextResolveAttemptAt = Time.realtimeSinceStartup + 2f; GameObject val = FindShipNoteByObjectName(); string resolvedFrom = "a ship-hierarchy object named 'StickyNoteItem'"; if (!TryGetBorrowableVisual(val, out filter, out renderer)) { val = FindCatalogueNotePrefab(); resolvedFrom = "StartOfRound.allItemsList"; } if (!TryGetBorrowableVisual(val, out filter, out renderer)) { val = FindSceneNoteByItemName(); resolvedFrom = "the in-scene vanilla note (a GrabbableObject whose itemName is 'Sticky note')"; } if (!TryGetBorrowableVisual(val, out filter, out renderer)) { return null; } _vanillaSource = val; _resolvedFrom = resolvedFrom; return val; } private static bool TryGetBorrowableVisual(GameObject candidate, out MeshFilter filter, out MeshRenderer renderer) { filter = null; renderer = null; if ((Object)(object)candidate == (Object)null) { return false; } filter = candidate.GetComponentInChildren(true); if ((Object)(object)filter == (Object)null || (Object)(object)filter.sharedMesh == (Object)null) { return false; } renderer = candidate.GetComponentInChildren(true); if ((Object)(object)renderer != (Object)null) { return (Object)(object)((Renderer)renderer).sharedMaterial != (Object)null; } return false; } private static GameObject FindShipNoteByObjectName() { Transform val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.elevatorTransform : null); if ((Object)(object)val != (Object)null) { Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Transform val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && IsVanillaNoteName(((Object)((Component)val2).gameObject).name)) { return ((Component)val2).gameObject; } } } return GameObject.Find("Environment/HangarShip/StickyNoteItem"); } private static bool IsVanillaNoteName(string name) { if (string.IsNullOrEmpty(name)) { return false; } if (name.Equals("StickyNoteItem", StringComparison.OrdinalIgnoreCase)) { return true; } if (!name.StartsWith("StickyNoteItem ", StringComparison.OrdinalIgnoreCase)) { return name.StartsWith("StickyNoteItem(", StringComparison.OrdinalIgnoreCase); } return true; } private static GameObject FindCatalogueNotePrefab() { List list = StartOfRound.Instance?.allItemsList?.itemsList; if (list == null) { return null; } for (int i = 0; i < list.Count; i++) { Item val = list[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val.spawnPrefab == (Object)null) && string.Equals(val.itemName, "Sticky note", StringComparison.OrdinalIgnoreCase)) { return val.spawnPrefab; } } return null; } private static GameObject FindSceneNoteByItemName() { GrabbableObject[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); if (array == null) { return null; } GameObject val = null; foreach (GrabbableObject val2 in array) { if ((Object)(object)val2 == (Object)null || val2 is CCTVStickyNoteProp) { continue; } Item itemProperties = val2.itemProperties; if (!((Object)(object)itemProperties == (Object)null) && string.Equals(itemProperties.itemName, "Sticky note", StringComparison.OrdinalIgnoreCase)) { if (!val2.isHeld && !val2.isPocketed) { return ((Component)val2).gameObject; } if ((Object)(object)val == (Object)null) { val = ((Component)val2).gameObject; } } } return val; } private static void LateBind() { if (_lateBound) { return; } MeshFilter filter; MeshRenderer renderer; GameObject val = FindVanillaPrefab(out filter, out renderer); if ((Object)(object)val == (Object)null) { return; } Material val2 = BuildMaterial(((Renderer)renderer).sharedMaterial); if (!((Object)(object)val2 == (Object)null)) { if ((Object)(object)_material != (Object)null && _material != val2) { Object.Destroy((Object)(object)_material); } _mesh = filter.sharedMesh; _material = val2; CopyVanillaItemPresentation(val); _lateBound = true; VisualBindGeneration++; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] CCTV sticky note bound to the vanilla note mesh '" + ((Object)_mesh).name + "' and a clone of '" + ((Object)((Renderer)renderer).sharedMaterial).name + "', resolved from " + _resolvedFrom + ".")); } } } private static void CopyVanillaItemPresentation(GameObject vanillaPrefab) { if ((Object)(object)ItemProperties == (Object)null) { return; } GrabbableObject component = vanillaPrefab.GetComponent(); Item val = (((Object)(object)component != (Object)null) ? component.itemProperties : null); if (!((Object)(object)val == (Object)null)) { if ((Object)(object)ItemProperties.itemIcon == (Object)null) { ItemProperties.itemIcon = val.itemIcon; } ItemProperties.grabSFX = (((Object)(object)ItemProperties.grabSFX != (Object)null) ? ItemProperties.grabSFX : val.grabSFX); ItemProperties.dropSFX = (((Object)(object)ItemProperties.dropSFX != (Object)null) ? ItemProperties.dropSFX : val.dropSFX); ItemProperties.pocketSFX = (((Object)(object)ItemProperties.pocketSFX != (Object)null) ? ItemProperties.pocketSFX : val.pocketSFX); ItemProperties.throwSFX = (((Object)(object)ItemProperties.throwSFX != (Object)null) ? ItemProperties.throwSFX : val.throwSFX); } } private static Material BuildMaterial(Material vanillaMaterial) { //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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0041: Expected O, but got Unknown Texture2D val = LoadEmbeddedTexture(); if ((Object)(object)val == (Object)null) { return null; } Material val2 = new Material(vanillaMaterial) { name = "Y4NGZ_CCTV_StickyNoteMaterial" }; AssignTexture(val2, "_BaseColorMap", val); AssignTexture(val2, "_MainTex", val); Object.DontDestroyOnLoad((Object)val2); return val2; } private static void AssignTexture(Material material, string property, Texture2D texture) { if ((Object)(object)material != (Object)null && material.HasProperty(property)) { material.SetTexture(property, (Texture)(object)texture); } } private static Texture2D LoadEmbeddedTexture() { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown if ((Object)(object)_texture != (Object)null) { return _texture; } try { Assembly assembly = typeof(CCTVStickyNoteItem).Assembly; string text = assembly.GetManifestResourceNames().FirstOrDefault((string name) => name.EndsWith(".Y4NGZ_CCTV_StickyNote.png", StringComparison.OrdinalIgnoreCase)); if (string.IsNullOrWhiteSpace(text)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Embedded sticky note texture 'Y4NGZ_CCTV_StickyNote.png' was not found in the assembly."); } return null; } byte[] array; using (Stream stream = assembly.GetManifestResourceStream(text)) { if (stream == null) { return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); array = memoryStream.ToArray(); } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, false); if (!ImageConversion.LoadImage(val, array, true)) { Object.Destroy((Object)(object)val); return null; } ((Object)val).name = "Y4NGZ_CCTV_StickyNoteTex"; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)2; ((Texture)val).anisoLevel = 4; Object.DontDestroyOnLoad((Object)(object)val); _texture = val; return _texture; } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Failed to load the embedded sticky note texture: " + ex.Message)); } return null; } } internal static void EnsureSpawnedInShip() { //IL_0133: 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_0161: 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_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) if (!Registered) { return; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return; } if (_spawnStateRound != instance) { _spawnStateRound = instance; _settleAt = -1f; _nextExistingScanAt = -1f; _nextResolveAttemptAt = -1f; _spawnLogged = false; _spawnPointWarned = false; _trackedNote = null; _vanillaSource = null; } LateBind(); if ((Object)(object)_trackedNote == (Object)null && Time.realtimeSinceStartup >= _nextExistingScanAt) { _nextExistingScanAt = Time.realtimeSinceStartup + 0.25f; _trackedNote = FindExistingNote(); } NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsServer || !singleton.IsListening) { return; } if (_settleAt < 0f) { _settleAt = Time.realtimeSinceStartup + 3f; } if (Time.realtimeSinceStartup < _settleAt || (Object)(object)_trackedNote != (Object)null) { return; } Transform val = CCTVOperatorStation.EnsureNoteAnchor(); Transform elevatorTransform = instance.elevatorTransform; if ((Object)(object)val == (Object)null || (Object)(object)elevatorTransform == (Object)null) { if (!_spawnPointWarned) { _spawnPointWarned = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] CCTV sticky note anchor unavailable (operator station root not spawned yet); the note will spawn as soon as the station resolves."); } } return; } try { GameObject obj = Object.Instantiate(Prefab, val.position, val.rotation, elevatorTransform); ((Object)obj).hideFlags = (HideFlags)0; obj.SetActive(true); CCTVStickyNoteProp component = obj.GetComponent(); component?.AdoptAuthoredScale(val.localScale); obj.GetComponent().Spawn(false); PlaceAtAnchor(obj, val); _trackedNote = component; if (!_spawnLogged) { _spawnLogged = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] Spawned the CCTV controls sticky note at the station note anchor: " + $"world={val.position} anchorLocal={val.localPosition} euler={val.eulerAngles}.")); } } } catch (Exception ex) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV] Failed to spawn the CCTV sticky note: " + ex.Message)); } } } private static CCTVStickyNoteProp FindExistingNote() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) CCTVStickyNoteProp[] array = Resources.FindObjectsOfTypeAll(); if (array == null) { return null; } foreach (CCTVStickyNoteProp cCTVStickyNoteProp in array) { if (!((Object)(object)cCTVStickyNoteProp == (Object)null) && (!((Object)(object)Prefab != (Object)null) || !((Object)(object)((Component)cCTVStickyNoteProp).gameObject == (Object)(object)Prefab))) { Scene scene = ((Component)cCTVStickyNoteProp).gameObject.scene; if (((Scene)(ref scene)).IsValid() && ((Scene)(ref scene)).isLoaded) { NormalizeRestoredNote(((Component)cCTVStickyNoteProp).gameObject); RepairRestoredNoteRotation(cCTVStickyNoteProp); return cCTVStickyNoteProp; } } } return null; } private static void NormalizeRestoredNote(GameObject note) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)note == (Object)null) && (int)((Object)note).hideFlags != 0) { ((Object)note).hideFlags = (HideFlags)0; if (!note.activeSelf) { note.SetActive(true); } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Re-activated a save-restored CCTV sticky note that vanilla cloned from the inactive prefab template."); } } } private static void RepairRestoredNoteRotation(CCTVStickyNoteProp note) { //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_0055: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00d4: 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_00db: 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_00e8: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsServer || !singleton.IsListening || !CanRepositionNote(note)) { return; } Transform val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.elevatorTransform : null); if (!(Quaternion.Angle(ToShipLocalRotation(val, ((Component)note).transform.rotation), Quaternion.identity) > 1f)) { Transform noteAnchor = CCTVOperatorStation.NoteAnchor; int num; if ((Object)(object)noteAnchor != (Object)null) { Vector3 val2 = noteAnchor.position - ((Component)note).transform.position; num = ((((Vector3)(ref val2)).sqrMagnitude <= 0.25f) ? 1 : 0); } else { num = 0; } bool flag = (byte)num != 0; Quaternion val3 = (flag ? ToShipLocalRotation(val, noteAnchor.rotation) : Quaternion.Euler(VanillaFlatRestingEuler)); ((Component)note).transform.rotation = (((Object)(object)val != (Object)null) ? (val.rotation * val3) : val3); ((GrabbableObject)note).floorYRot = Mathf.RoundToInt(((Quaternion)(ref val3)).eulerAngles.y); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Restored CCTV sticky note came back from the save with no rotation; re-applied the " + (flag ? "authored note anchor orientation." : "vanilla flat resting orientation."))); } } } internal static string RespawnForAuthoring() { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsServer || !singleton.IsListening) { return "HOST ONLY respawn skipped - the pose applies when a host spawns the note from this profile"; } CCTVStickyNoteProp trackedNote = _trackedNote; if ((Object)(object)trackedNote == (Object)null) { return "no live note tracked yet - it will spawn at the authored pose"; } if (!CanRepositionNote(trackedNote)) { return "note is held or parented right now - the authored pose applies on its next respawn"; } RespawnNoteAtAnchor(); return "live note is respawning at the authored pose for every client"; } private static bool CanRepositionNote(CCTVStickyNoteProp note) { if ((Object)(object)note != (Object)null && !((GrabbableObject)note).isHeld && !((GrabbableObject)note).isPocketed && !((GrabbableObject)note).isHeldByEnemy) { return (Object)(object)((GrabbableObject)note).parentObject == (Object)null; } return false; } private static void RespawnNoteAtAnchor() { CCTVStickyNoteProp trackedNote = _trackedNote; if (!CanRepositionNote(trackedNote) || (Object)(object)CCTVOperatorStation.NoteAnchor == (Object)null) { return; } try { NetworkObject component = ((Component)trackedNote).GetComponent(); if ((Object)(object)component != (Object)null && component.IsSpawned) { component.Despawn(true); } else { Object.Destroy((Object)(object)((Component)trackedNote).gameObject); } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Failed to despawn the CCTV sticky note for its re-place: " + ex.Message)); } return; } _trackedNote = null; _settleAt = 0f; _nextExistingScanAt = Time.realtimeSinceStartup + 0.25f; _spawnLogged = false; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogMessage((object)"[LethalCCTV] CCTV sticky note edit session ended; despawned the note so the next tick respawns it at the authored anchor pose for every client."); } } private static void PlaceAtAnchor(GameObject note, Transform anchor) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00ad: 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_012b: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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_015c: 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) if ((Object)(object)note == (Object)null || (Object)(object)anchor == (Object)null) { return; } GrabbableObject component = note.GetComponent(); if (!((Object)(object)component == (Object)null)) { Transform val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.elevatorTransform : null); NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && singleton.IsServer && singleton.IsListening && (Object)(object)val != (Object)null && (Object)(object)note.transform.parent != (Object)(object)val) { note.transform.SetParent(val, true); } note.transform.SetPositionAndRotation(anchor.position, anchor.rotation); if (component is CCTVStickyNoteProp cCTVStickyNoteProp) { cCTVStickyNoteProp.AdoptAuthoredScale(anchor.localScale); } else { note.transform.localScale = anchor.localScale; } component.isInShipRoom = true; component.isInElevator = true; component.isInFactory = false; component.scrapPersistedThroughRounds = true; component.isHeld = false; component.isPocketed = false; component.heldByPlayerOnServer = false; component.playerHeldBy = null; component.fallTime = 1f; component.hasHitGround = true; component.reachedFloorTarget = true; component.targetFloorPosition = (((Object)(object)val != (Object)null) ? val.InverseTransformPoint(anchor.position) : note.transform.localPosition); component.startFallingPosition = component.targetFloorPosition; Quaternion val2 = ToShipLocalRotation(val, anchor.rotation); component.floorYRot = Mathf.RoundToInt(((Quaternion)(ref val2)).eulerAngles.y); } } private static Quaternion ToShipLocalRotation(Transform ship, Quaternion worldRotation) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_0009: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ship != (Object)null)) { return worldRotation; } return Quaternion.Inverse(ship.rotation) * worldRotation; } private static int ResolveLayer(string name, int fallback) { int num = LayerMask.NameToLayer(name); if (num < 0) { return fallback; } return num; } private static void SetTagSafe(GameObject obj, string tag) { if ((Object)(object)obj == (Object)null) { return; } try { obj.tag = tag; } catch { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Tag '" + tag + "' was not available for " + ((Object)obj).name + ".")); } } } } internal sealed class CCTVStickyNoteProp : PhysicsProp { private const int MaxVisualAttempts = 1200; private bool _visualApplied; private int _visualAttempts; private bool _gaveUpLogged; private bool _authoredScale; private int _seenBindGeneration = -1; internal void AdoptAuthoredScale(Vector3 scale) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (!(scale.x <= 0.0001f) && !(scale.y <= 0.0001f) && !(scale.z <= 0.0001f)) { _authoredScale = true; ((Component)this).transform.localScale = scale; ((GrabbableObject)this).originalScale = scale; } } public override void Start() { //IL_0031: 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) ((GrabbableObject)this).Start(); if (!((GrabbableObject)this).reachedFloorTarget && ((GrabbableObject)this).hasHitGround && ((GrabbableObject)this).fallTime >= 1f) { ((GrabbableObject)this).reachedFloorTarget = true; ((GrabbableObject)this).targetFloorPosition = ((Component)this).transform.localPosition; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] CCTV sticky note re-settled after an external Start patch un-settled it (GeneralImprovements keep-in-place); authored orientation preserved."); } } ApplyVisual(); } public override void OnNetworkSpawn() { ((NetworkBehaviour)this).OnNetworkSpawn(); ApplyVisual(); } public override void Update() { ((GrabbableObject)this).Update(); int visualBindGeneration = CCTVStickyNoteItem.VisualBindGeneration; if (_seenBindGeneration != visualBindGeneration) { _seenBindGeneration = visualBindGeneration; _visualAttempts = 0; _gaveUpLogged = false; _visualApplied = false; } if (_visualApplied && !HasLiveMesh()) { _visualApplied = false; } if (_visualApplied || _visualAttempts >= 1200) { return; } _visualAttempts++; ApplyVisual(); if (!_visualApplied && _visualAttempts >= 1200 && !_gaveUpLogged) { _gaveUpLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] The CCTV sticky note could not borrow the vanilla note's mesh, so it has no mesh at all and is completely invisible in the ship. Tried " + CCTVStickyNoteItem.DescribeResolutionSources() + ".")); } } } private bool HasLiveMesh() { MeshFilter component = ((Component)this).GetComponent(); if ((Object)(object)component != (Object)null) { return (Object)(object)component.sharedMesh != (Object)null; } return false; } private void ApplyVisual() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00cb: 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_00eb: 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_0101: Unknown result type (might be due to invalid IL or missing references) if (_visualApplied || !CCTVStickyNoteItem.TryResolveVisual(out var mesh, out var material)) { return; } MeshFilter component = ((Component)this).GetComponent(); MeshRenderer component2 = ((Component)this).GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { return; } component.sharedMesh = mesh; ((Renderer)component2).sharedMaterial = material; ((GrabbableObject)this).mainObjectRenderer = component2; if (CCTVStickyNoteItem.TryResolveColliderShape(out var size, out var centre, out var scale)) { BoxCollider component3 = ((Component)this).GetComponent(); if ((Object)(object)component3 != (Object)null) { component3.size = size; component3.center = centre; } if (!_authoredScale && !Mathf.Approximately(((Component)this).transform.localScale.x, 0.104262345f)) { AdoptAuthoredScale(((Component)this).transform.localScale); } if (!_authoredScale && scale > 0.0001f && !Mathf.Approximately(((Component)this).transform.localScale.x, scale)) { ((Component)this).transform.localScale = Vector3.one * scale; ((GrabbableObject)this).originalScale = ((Component)this).transform.localScale; } } _visualApplied = true; } protected override void __initializeVariables() { ((PhysicsProp)this).__initializeVariables(); } protected override void __initializeRpcs() { ((PhysicsProp)this).__initializeRpcs(); } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "CCTVStickyNoteProp"; } } internal static class CctvTargetCache { internal enum TargetKind { Item, Hostile, Player, Objective } internal readonly struct RendererTarget { internal readonly Renderer Renderer; internal readonly TargetKind Kind; internal RendererTarget(Renderer renderer, TargetKind kind) { Renderer = renderer; Kind = kind; } } internal readonly struct ScreenTarget { internal readonly Bounds Bounds; internal readonly Transform Root; internal readonly TargetKind Kind; internal readonly int SourceId; internal readonly string Label; internal readonly bool TracksRoot; private readonly Vector3 _rootPositionAtCapture; internal ScreenTarget(Bounds bounds, Transform root, TargetKind kind, int sourceId, string label) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) Bounds = bounds; Root = root; Kind = kind; SourceId = sourceId; Label = label; TracksRoot = (Object)(object)root != (Object)null; _rootPositionAtCapture = (((Object)(object)root != (Object)null) ? root.position : Vector3.zero); } internal Bounds ResolveCurrentBounds() { //IL_0017: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_004c: Unknown result type (might be due to invalid IL or missing references) if (!TracksRoot || (Object)(object)Root == (Object)null) { return Bounds; } Bounds bounds = Bounds; ((Bounds)(ref bounds)).center = ((Bounds)(ref bounds)).center + (Root.position - _rootPositionAtCapture); return bounds; } } internal readonly struct GroundTarget { internal readonly Vector3 Position; internal readonly float Radius; internal readonly TargetKind Kind; internal GroundTarget(Vector3 position, float radius, TargetKind kind) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) Position = position; Radius = Mathf.Clamp(radius, 0.35f, 5f); Kind = kind; } } private readonly struct PendingRootWork { internal readonly GameObject Root; internal readonly TargetKind Kind; internal readonly Vector3 FallbackPosition; internal readonly float FallbackRadius; internal readonly string Label; internal readonly bool AddGroundWhenNoRenderer; internal readonly bool TryParentForRenderers; internal PendingRootWork(GameObject root, TargetKind kind, Vector3 fallbackPosition, float fallbackRadius, string label, bool addGroundWhenNoRenderer, bool tryParentForRenderers) { //IL_000f: 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) Root = root; Kind = kind; FallbackPosition = fallbackPosition; FallbackRadius = fallbackRadius; Label = label; AddGroundWhenNoRenderer = addGroundWhenNoRenderer; TryParentForRenderers = tryParentForRenderers; } } private readonly struct ObjectiveMarkerInfo { internal readonly string Label; internal readonly Vector3 Position; internal readonly float Radius; internal readonly bool IsComplete; internal readonly Component Target; internal ObjectiveMarkerInfo(string label, Vector3 position, float radius, bool isComplete, Component target) { //IL_0017: 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) Label = (string.IsNullOrWhiteSpace(label) ? "OBJECTIVE" : label); Position = position; Radius = Mathf.Clamp(radius, 0.35f, 5f); IsComplete = isComplete; Target = target; } } private const float FallbackRefreshIntervalSeconds = 4f; private const float StalePruneIntervalSeconds = 1f; private const int MaxLabelCharacters = 18; private const int MaxRootsPerRefreshSlice = 32; private const int MaxItemsPerRefreshSlice = 64; private static List _rendererTargets = new List(320); private static List _screenTargets = new List(180); private static List _groundTargets = new List(32); private static Dictionary _rendererIndexById = new Dictionary(320); private static Dictionary _screenIndexByRoot = new Dictionary(180); private static List _stagingRendererTargets = new List(320); private static List _stagingScreenTargets = new List(180); private static List _stagingGroundTargets = new List(32); private static Dictionary _stagingRendererIndexById = new Dictionary(320); private static Dictionary _stagingScreenIndexByRoot = new Dictionary(180); private static readonly List _scratchRenderers = new List(16); private static readonly List _objectiveMarkers = new List(32); private static readonly List _pendingRoots = new List(256); private static GrabbableObject[] _pendingItems; private static int _pendingItemIndex; private static int _pendingRootIndex; private static int _pendingCollectorIndex; private static bool _slicedRefreshActive; private static bool _writeToStaging; private static bool _enqueueRootTargets; private static bool _loggedSlicedRefresh; private static Type _objectiveApiType; private static MethodInfo _getActiveMarkersMethod; private static bool _objectiveApiResolveAttempted; private static float _nextRefreshAt; private static float _nextStalePruneAt; private static int _nextSyntheticSourceId = -1; private static readonly Func[] SlicedCollectors = new Func[7] { CollectObjectiveMarkers, CollectSystemTargets, CollectEntranceTargets, CollectContractObjectiveTargets, CollectPlayerTargets, CollectHostileTargets, CollectItemTargets }; internal static IReadOnlyList RendererTargets => _rendererTargets; internal static IReadOnlyList ScreenTargets => _screenTargets; internal static IReadOnlyList GroundTargets => _groundTargets; private static List BuildRendererTargets { get { if (!_writeToStaging) { return _rendererTargets; } return _stagingRendererTargets; } } private static List BuildScreenTargets { get { if (!_writeToStaging) { return _screenTargets; } return _stagingScreenTargets; } } private static List BuildGroundTargets { get { if (!_writeToStaging) { return _groundTargets; } return _stagingGroundTargets; } } private static Dictionary BuildRendererIndexById { get { if (!_writeToStaging) { return _rendererIndexById; } return _stagingRendererIndexById; } } private static Dictionary BuildScreenIndexByRoot { get { if (!_writeToStaging) { return _screenIndexByRoot; } return _stagingScreenIndexByRoot; } } internal static void RefreshIfDue(bool force = false) { float unscaledTime = Time.unscaledTime; if (_slicedRefreshActive) { AdvanceSlicedRefresh(); return; } if (!force && unscaledTime < _nextRefreshAt) { PruneDestroyedTargetsIfDue(unscaledTime); return; } _nextRefreshAt = unscaledTime + 4f; _nextStalePruneAt = unscaledTime + 1f; BeginSlicedRefresh(); AdvanceSlicedRefresh(); } internal static void Invalidate() { _nextRefreshAt = 0f; } internal static void Clear() { CancelSlicedRefresh(); _rendererTargets.Clear(); _screenTargets.Clear(); _groundTargets.Clear(); _screenIndexByRoot.Clear(); _objectiveMarkers.Clear(); _rendererIndexById.Clear(); _nextRefreshAt = 0f; _nextStalePruneAt = 0f; _nextSyntheticSourceId = -1; } private static void BeginSlicedRefresh() { _stagingRendererTargets.Clear(); _stagingScreenTargets.Clear(); _stagingGroundTargets.Clear(); _stagingRendererIndexById.Clear(); _stagingScreenIndexByRoot.Clear(); _pendingRoots.Clear(); _pendingRootIndex = 0; _pendingCollectorIndex = 0; ClearPendingItemScan(); _objectiveMarkers.Clear(); _nextSyntheticSourceId = -1; _slicedRefreshActive = true; } private static void AdvanceSlicedRefresh() { //IL_0121: Unknown result type (might be due to invalid IL or missing references) if (!_slicedRefreshActive) { return; } if (_pendingCollectorIndex < SlicedCollectors.Length) { long timestamp = Stopwatch.GetTimestamp(); bool flag = true; _writeToStaging = true; _enqueueRootTargets = true; try { flag = SlicedCollectors[_pendingCollectorIndex](); } finally { _enqueueRootTargets = false; _writeToStaging = false; if (flag) { _pendingCollectorIndex++; } } if (MonitorFocus.IsFocused) { FocusPerfProbe.RecordStep("CctvTargetCache.RefreshCollect", Stopwatch.GetTimestamp() - timestamp); } if (_pendingCollectorIndex >= SlicedCollectors.Length && !_loggedSlicedRefresh) { _loggedSlicedRefresh = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV.Timing] target cache rebuild is sliced: one collector per pass " + $"(items at {64} per pass), then " + $"{_pendingRoots.Count} root(s) at {32} per pass (#279).")); } } return; } long timestamp2 = Stopwatch.GetTimestamp(); _writeToStaging = true; try { int num = Mathf.Min(_pendingRootIndex + 32, _pendingRoots.Count); while (_pendingRootIndex < num) { PendingRootWork pendingRootWork = _pendingRoots[_pendingRootIndex]; AddRootTarget(pendingRootWork.Root, pendingRootWork.Kind, pendingRootWork.FallbackPosition, pendingRootWork.FallbackRadius, pendingRootWork.Label, pendingRootWork.AddGroundWhenNoRenderer, pendingRootWork.TryParentForRenderers); _pendingRootIndex++; } } finally { _writeToStaging = false; } if (_pendingRootIndex >= _pendingRoots.Count) { CommitSlicedRefresh(); } if (MonitorFocus.IsFocused) { FocusPerfProbe.RecordStep("CctvTargetCache.RefreshSlice", Stopwatch.GetTimestamp() - timestamp2); } } private static void CommitSlicedRefresh() { List stagingRendererTargets = _stagingRendererTargets; List rendererTargets = _rendererTargets; _rendererTargets = stagingRendererTargets; _stagingRendererTargets = rendererTargets; List stagingScreenTargets = _stagingScreenTargets; List screenTargets = _screenTargets; _screenTargets = stagingScreenTargets; _stagingScreenTargets = screenTargets; List stagingGroundTargets = _stagingGroundTargets; List groundTargets = _groundTargets; _groundTargets = stagingGroundTargets; _stagingGroundTargets = groundTargets; Dictionary stagingRendererIndexById = _stagingRendererIndexById; Dictionary rendererIndexById = _rendererIndexById; _rendererIndexById = stagingRendererIndexById; _stagingRendererIndexById = rendererIndexById; Dictionary stagingScreenIndexByRoot = _stagingScreenIndexByRoot; rendererIndexById = _screenIndexByRoot; _screenIndexByRoot = stagingScreenIndexByRoot; _stagingScreenIndexByRoot = rendererIndexById; _stagingRendererTargets.Clear(); _stagingScreenTargets.Clear(); _stagingGroundTargets.Clear(); _stagingRendererIndexById.Clear(); _stagingScreenIndexByRoot.Clear(); _pendingRoots.Clear(); _pendingRootIndex = 0; _pendingCollectorIndex = 0; ClearPendingItemScan(); _slicedRefreshActive = false; } private static void CancelSlicedRefresh() { _stagingRendererTargets.Clear(); _stagingScreenTargets.Clear(); _stagingGroundTargets.Clear(); _stagingRendererIndexById.Clear(); _stagingScreenIndexByRoot.Clear(); _pendingRoots.Clear(); _pendingRootIndex = 0; _pendingCollectorIndex = 0; ClearPendingItemScan(); _slicedRefreshActive = false; _writeToStaging = false; _enqueueRootTargets = false; } private static void ClearPendingItemScan() { _pendingItems = null; _pendingItemIndex = 0; } private static bool CollectSystemTargets() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) List activeTargets = CctvCommandTargetBridge.GetActiveTargets(); for (int i = 0; i < activeTargets.Count; i++) { CctvCommandTargetBridge.TargetInfo targetInfo = activeTargets[i]; if (targetInfo != null && !((Object)(object)targetInfo.Component == (Object)null)) { AddRootTarget(targetInfo.Component.gameObject, TargetKind.Objective, targetInfo.Position, targetInfo.Radius, targetInfo.DisplayName, addGroundWhenNoRenderer: true, tryParentForRenderers: true); } } TryAddTypeTargets("MainframeSupport", TargetKind.Objective); TryAddTypeTargets("CompanyStashController", TargetKind.Objective, "COMPANY STASH"); TryAddRadarBoosterTargets(); return true; } private static bool CollectEntranceTargets() { //IL_0039: 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) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) EntranceTeleport[] array = Object.FindObjectsOfType(false); foreach (EntranceTeleport val in array) { if (!((Object)(object)val == (Object)null)) { Vector3 fallbackPosition = (((Object)(object)val.entrancePoint != (Object)null) ? val.entrancePoint.position : ((Component)val).transform.position); AddRootTarget(((Component)val).gameObject, TargetKind.Objective, fallbackPosition, (val.entranceId == 0) ? 1.25f : 0.95f, (val.entranceId == 0) ? "MAIN ENTRANCE" : "FIRE EXIT", addGroundWhenNoRenderer: true); } } return true; } private static bool CollectContractObjectiveTargets() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0088: 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) for (int i = 0; i < _objectiveMarkers.Count; i++) { ObjectiveMarkerInfo objectiveMarkerInfo = _objectiveMarkers[i]; if (!objectiveMarkerInfo.IsComplete) { if ((Object)(object)objectiveMarkerInfo.Target != (Object)null) { AddRootTarget(objectiveMarkerInfo.Target.gameObject, TargetKind.Objective, objectiveMarkerInfo.Position, objectiveMarkerInfo.Radius, objectiveMarkerInfo.Label, addGroundWhenNoRenderer: true, tryParentForRenderers: true); continue; } AddBoundsTarget(new Bounds(objectiveMarkerInfo.Position, Vector3.one * Mathf.Max(0.7f, objectiveMarkerInfo.Radius * 2f)), TargetKind.Objective, objectiveMarkerInfo.Label); AddGroundTarget(objectiveMarkerInfo.Position, objectiveMarkerInfo.Radius, TargetKind.Objective); } } return true; } private static bool CollectPlayerTargets() { //IL_008f: 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_0099: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null || array.Length == 0) { array = Object.FindObjectsOfType(false); } foreach (PlayerControllerB val in array) { if (!((Object)(object)val == (Object)null) && !val.isPlayerDead && (val.isPlayerControlled || val.isHostPlayerObject) && !((Object)(object)((Component)val).gameObject == (Object)null) && ((Component)val).gameObject.activeInHierarchy) { string label = ((!string.IsNullOrWhiteSpace(val.playerUsername)) ? val.playerUsername : "PLAYER"); AddRootTarget(((Component)val).gameObject, TargetKind.Player, ((Component)val).transform.position + Vector3.up, 0.85f, label); } } return true; } private static bool CollectHostileTargets() { List list = RoundManager.Instance?.SpawnedEnemies; if (list != null && list.Count > 0) { for (int i = 0; i < list.Count; i++) { AddHostileTarget(list[i]); } return true; } EnemyAI[] array = Object.FindObjectsOfType(false); for (int j = 0; j < array.Length; j++) { AddHostileTarget(array[j]); } return true; } private static void AddHostileTarget(EnemyAI enemy) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)enemy == (Object)null) && !enemy.isEnemyDead && !enemy.isInsidePlayerShip && !enemy.isOutside && !((Object)(object)((Component)enemy).gameObject == (Object)null) && ((Component)enemy).gameObject.activeInHierarchy) { TargetKind kind = ((!IsObjectiveTarget((Component)(object)enemy, ((Component)enemy).transform.position)) ? TargetKind.Hostile : TargetKind.Objective); string label = (((Object)(object)enemy.enemyType != (Object)null && !string.IsNullOrWhiteSpace(enemy.enemyType.enemyName)) ? enemy.enemyType.enemyName : ((object)enemy).GetType().Name); AddRootTarget(((Component)enemy).gameObject, kind, ((Component)enemy).transform.position + Vector3.up, 1f, label); } } private static bool CollectItemTargets() { //IL_00be: 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) if (_pendingItems == null) { _pendingItems = Object.FindObjectsOfType(false); _pendingItemIndex = 0; if (_pendingItems.Length != 0) { return false; } } int num = Mathf.Min(_pendingItemIndex + 64, _pendingItems.Length); while (_pendingItemIndex < num) { GrabbableObject val = _pendingItems[_pendingItemIndex]; if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null) && !val.isHeldByEnemy && !((Object)(object)val.itemProperties == (Object)null) && !val.isInShipRoom && !val.isInElevator && (val.isInFactory || val.isHeld || ((Component)val).gameObject.activeInHierarchy)) { bool flag = IsObjectiveTarget((Component)(object)val, ((Component)val).transform.position) || IsRadarSystem(((Component)val).gameObject, ((object)val).GetType()); TargetKind kind = (flag ? TargetKind.Objective : TargetKind.Item); string text = (((Object)(object)val.itemProperties != (Object)null && !string.IsNullOrWhiteSpace(val.itemProperties.itemName)) ? val.itemProperties.itemName : ((Object)((Component)val).gameObject).name); AddRootTarget(((Component)val).gameObject, kind, ((Component)val).transform.position, 0.45f, flag ? "RADAR" : text); } _pendingItemIndex++; } if (_pendingItemIndex < _pendingItems.Length) { return false; } ClearPendingItemScan(); return true; } private static void TryAddTypeTargets(string typeName, TargetKind kind, string displayLabel = null) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) Type type = ResolveLguContractHudType(typeName); if (type == null) { return; } Object[] array = Object.FindObjectsOfType(type); foreach (Object obj in array) { Component val = (Component)(object)((obj is Component) ? obj : null); if (!((Object)(object)val == (Object)null)) { AddRootTarget(val.gameObject, kind, val.transform.position, 1f, displayLabel ?? CleanTypeLabel(typeName), addGroundWhenNoRenderer: true); } } } private static Type ResolveLguContractHudType(string typeName) { if (string.IsNullOrWhiteSpace(typeName)) { return null; } return Type.GetType("Y4NGZCompany.Facility.Mainframe." + typeName + ", LethalCCTV", throwOnError: false) ?? Type.GetType("Y4NGZCompany.Facility.Stash." + typeName + ", LethalCCTV", throwOnError: false) ?? Type.GetType("LGUContractHUD." + typeName + ", LGUContractHUD", throwOnError: false); } private static void TryAddRadarBoosterTargets() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) Type type = Type.GetType("RadarBoosterItem, Assembly-CSharp", throwOnError: false); if (type == null) { return; } Object[] array = Object.FindObjectsOfType(type); foreach (Object obj in array) { Component val = (Component)(object)((obj is Component) ? obj : null); if (!((Object)(object)val == (Object)null)) { AddRootTarget(val.gameObject, TargetKind.Objective, val.transform.position, 0.9f, "RADAR", addGroundWhenNoRenderer: true); } } } private static void AddRootTarget(GameObject root, TargetKind kind, Vector3 fallbackPosition, float fallbackRadius, string label = null, bool addGroundWhenNoRenderer = false, bool tryParentForRenderers = false) { //IL_0033: 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_004a: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) if (_enqueueRootTargets && (Object)(object)root != (Object)null) { _pendingRoots.Add(new PendingRootWork(root, kind, fallbackPosition, fallbackRadius, label, addGroundWhenNoRenderer, tryParentForRenderers)); return; } if ((Object)(object)root == (Object)null) { AddBoundsTarget(new Bounds(fallbackPosition, Vector3.one * Mathf.Max(0.4f, fallbackRadius * 2f)), kind, label); if (addGroundWhenNoRenderer) { AddGroundTarget(fallbackPosition, fallbackRadius, kind); } return; } Bounds bounds; Transform boundsRoot; int num = AddRenderersAndResolveBounds(root, kind, out bounds, out boundsRoot); if (num == 0 && tryParentForRenderers && (Object)(object)root.transform != (Object)null && (Object)(object)root.transform.parent != (Object)null) { num = AddRenderersAndResolveBounds(((Component)root.transform.parent).gameObject, kind, out bounds, out boundsRoot); } Transform root2 = ((num > 0 && (Object)(object)boundsRoot != (Object)null) ? boundsRoot : root.transform); Bounds bounds2 = (Bounds)((num > 0) ? bounds : new Bounds(fallbackPosition, Vector3.one * Mathf.Max(0.4f, fallbackRadius * 2f))); AddScreenRootTarget(root2, bounds2, kind, label, ((Object)root).name); if (num == 0 && addGroundWhenNoRenderer) { AddGroundTarget(fallbackPosition, fallbackRadius, kind); } } private static int AddRenderersAndResolveBounds(GameObject root, TargetKind kind, out Bounds bounds, out Transform boundsRoot) { //IL_0001: 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_0064: 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) bounds = default(Bounds); boundsRoot = (((Object)(object)root != (Object)null) ? root.transform : null); bool flag = false; int num = 0; if ((Object)(object)root == (Object)null) { return 0; } _scratchRenderers.Clear(); root.GetComponentsInChildren(true, _scratchRenderers); for (int i = 0; i < _scratchRenderers.Count; i++) { Renderer val = _scratchRenderers[i]; if (IsEligibleRenderer(val)) { AddRendererTarget(val, kind); if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } num++; } } return num; } private static void AddRendererTarget(Renderer renderer, TargetKind kind) { if ((Object)(object)renderer == (Object)null) { return; } List buildRendererTargets = BuildRendererTargets; Dictionary buildRendererIndexById = BuildRendererIndexById; int instanceID = ((Object)renderer).GetInstanceID(); if (buildRendererIndexById.TryGetValue(instanceID, out var value)) { RendererTarget rendererTarget = buildRendererTargets[value]; if (Priority(kind) > Priority(rendererTarget.Kind)) { buildRendererTargets[value] = new RendererTarget(renderer, kind); } } else { buildRendererIndexById[instanceID] = buildRendererTargets.Count; buildRendererTargets.Add(new RendererTarget(renderer, kind)); } } private static void AddScreenRootTarget(Transform root, Bounds bounds, TargetKind kind, string label, string fallbackName) { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0065: 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) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) List buildScreenTargets = BuildScreenTargets; Dictionary buildScreenIndexByRoot = BuildScreenIndexByRoot; int num = (((Object)(object)root != (Object)null) ? ((Object)((Component)root).gameObject).GetInstanceID() : _nextSyntheticSourceId--); string label2 = NormalizeLabel(label, fallbackName, kind); if (buildScreenIndexByRoot.TryGetValue(num, out var value)) { ScreenTarget screenTarget = buildScreenTargets[value]; Bounds bounds2 = screenTarget.Bounds; ((Bounds)(ref bounds2)).Encapsulate(bounds); screenTarget = new ScreenTarget(bounds2, screenTarget.Root, screenTarget.Kind, num, screenTarget.Label); if (Priority(kind) > Priority(screenTarget.Kind)) { screenTarget = new ScreenTarget(bounds2, screenTarget.Root, kind, num, screenTarget.Label); } if (string.IsNullOrEmpty(screenTarget.Label)) { screenTarget = new ScreenTarget(bounds2, screenTarget.Root, screenTarget.Kind, num, label2); } buildScreenTargets[value] = screenTarget; } else { buildScreenIndexByRoot[num] = buildScreenTargets.Count; buildScreenTargets.Add(new ScreenTarget(bounds, root, kind, num, label2)); } } private static void AddBoundsTarget(Bounds bounds, TargetKind kind, string label = null) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) int sourceId = _nextSyntheticSourceId--; BuildScreenTargets.Add(new ScreenTarget(bounds, null, kind, sourceId, NormalizeLabel(label, null, kind))); } private static void AddGroundTarget(Vector3 position, float radius, TargetKind kind) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) BuildGroundTargets.Add(new GroundTarget(position, radius, kind)); } private static bool CollectObjectiveMarkers() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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) if (!TryResolveObjectiveApi()) { return true; } try { if (!(_getActiveMarkersMethod.Invoke(null, null) is IEnumerable enumerable)) { return true; } foreach (object item in enumerable) { if (item != null) { bool isComplete = ReadMemberBool(item, "IsComplete", fallback: false); Vector3 val = ReadMemberVector3(item, "Position", Vector3.zero); if (!float.IsNaN(val.x) && !float.IsNaN(val.y) && !float.IsNaN(val.z)) { _objectiveMarkers.Add(new ObjectiveMarkerInfo(ReadMemberString(item, "Label", "OBJECTIVE"), val, ReadMemberFloat(item, "Radius", 1f), isComplete, ReadMemberComponent(item, "Target"))); } } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] CCTV target cache marker read failed: " + ex.Message)); } } return true; } private static bool TryResolveObjectiveApi() { if (_getActiveMarkersMethod != null) { return true; } if (_objectiveApiResolveAttempted) { return false; } _objectiveApiResolveAttempted = true; _objectiveApiType = CompanyAssemblyBridge.ResolveType("Y4NGZCompany.Contracts._Shared.MoonContractObjectiveMarkerApi"); _getActiveMarkersMethod = _objectiveApiType?.GetMethod("GetActiveMarkers", BindingFlags.Static | BindingFlags.Public); return _getActiveMarkersMethod != null; } private static bool IsObjectiveTarget(Component component, Vector3 position) { //IL_0009: 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_00b3: 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_00bd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)component == (Object)null) { return IsNearObjectiveMarker(position); } for (int i = 0; i < _objectiveMarkers.Count; i++) { ObjectiveMarkerInfo objectiveMarkerInfo = _objectiveMarkers[i]; if (objectiveMarkerInfo.IsComplete) { continue; } if ((Object)(object)objectiveMarkerInfo.Target != (Object)null) { if (objectiveMarkerInfo.Target == component) { return true; } if ((Object)(object)component.transform != (Object)null && (Object)(object)objectiveMarkerInfo.Target.transform != (Object)null && (component.transform.IsChildOf(objectiveMarkerInfo.Target.transform) || objectiveMarkerInfo.Target.transform.IsChildOf(component.transform))) { return true; } } float num = Mathf.Max(objectiveMarkerInfo.Radius, 0.8f) + 1f; Vector3 val = position - objectiveMarkerInfo.Position; if (((Vector3)(ref val)).sqrMagnitude <= num * num) { return true; } } return false; } private static bool IsNearObjectiveMarker(Vector3 position) { //IL_002f: 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) //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) for (int i = 0; i < _objectiveMarkers.Count; i++) { ObjectiveMarkerInfo objectiveMarkerInfo = _objectiveMarkers[i]; if (!objectiveMarkerInfo.IsComplete) { float num = Mathf.Max(objectiveMarkerInfo.Radius, 0.8f) + 1f; Vector3 val = position - objectiveMarkerInfo.Position; if (((Vector3)(ref val)).sqrMagnitude <= num * num) { return true; } } } return false; } private static void PruneDestroyedTargetsIfDue(float now) { if (now < _nextStalePruneAt) { return; } _nextStalePruneAt = now + 1f; bool flag = false; for (int num = _rendererTargets.Count - 1; num >= 0; num--) { if (!((Object)(object)_rendererTargets[num].Renderer != (Object)null)) { _rendererTargets.RemoveAt(num); flag = true; } } if (flag) { _rendererIndexById.Clear(); for (int i = 0; i < _rendererTargets.Count; i++) { Renderer renderer = _rendererTargets[i].Renderer; if ((Object)(object)renderer != (Object)null) { _rendererIndexById[((Object)renderer).GetInstanceID()] = i; } } } bool flag2 = false; for (int num2 = _screenTargets.Count - 1; num2 >= 0; num2--) { ScreenTarget screenTarget = _screenTargets[num2]; if (screenTarget.TracksRoot && !((Object)(object)screenTarget.Root != (Object)null)) { _screenTargets.RemoveAt(num2); flag2 = true; } } if (!flag2) { return; } _screenIndexByRoot.Clear(); for (int j = 0; j < _screenTargets.Count; j++) { ScreenTarget screenTarget2 = _screenTargets[j]; if (screenTarget2.TracksRoot && (Object)(object)screenTarget2.Root != (Object)null) { _screenIndexByRoot[screenTarget2.SourceId] = j; } } } private static bool IsEligibleRenderer(Renderer renderer) { if ((Object)(object)renderer == (Object)null || !renderer.enabled) { return false; } if (renderer is ParticleSystemRenderer) { return false; } if (renderer is LineRenderer) { return false; } if ((Object)(object)((Component)renderer).gameObject == (Object)null) { return false; } string text = ((Object)((Component)renderer).gameObject).name ?? string.Empty; if (text.StartsWith("LethalCCTVCamera_", StringComparison.OrdinalIgnoreCase)) { return false; } if (text.StartsWith("LethalCCTV_", StringComparison.OrdinalIgnoreCase)) { return false; } if ((Object)(object)((Component)renderer).GetComponentInParent() != (Object)null) { return false; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if (val != null) { return (Object)(object)val.sharedMesh != (Object)null; } if (renderer is MeshRenderer) { MeshFilter component = ((Component)renderer).GetComponent(); if ((Object)(object)component != (Object)null) { return (Object)(object)component.sharedMesh != (Object)null; } return false; } return false; } private static bool IsRadarSystem(GameObject root, Type type) { string text = ((type != null) ? type.Name : string.Empty); string text2 = (((Object)(object)root != (Object)null) ? ((Object)root).name : string.Empty); if (!Contains(text, "Radar")) { return Contains(text2, "Radar"); } return true; } private static string CleanTypeLabel(string typeName) { if (string.IsNullOrWhiteSpace(typeName)) { return null; } return typeName.Replace("Support", string.Empty).Replace("System", string.Empty); } private static string NormalizeLabel(string label, string fallbackName, TargetKind kind) { string text = ((!string.IsNullOrWhiteSpace(label)) ? label : fallbackName); if (string.IsNullOrWhiteSpace(text)) { text = kind switch { TargetKind.Objective => "OBJECTIVE", TargetKind.Player => "PLAYER", TargetKind.Hostile => "HOSTILE", _ => "ITEM", }; } text = text.Replace("(Clone)", string.Empty).Replace("_", " ").Replace("-", " ") .Trim(); text = CollapseSpaces(text).ToUpperInvariant(); if (text.Length > 18) { text = text.Substring(0, 18); } return text; } private static string CollapseSpaces(string text) { if (string.IsNullOrEmpty(text)) { return string.Empty; } StringBuilder stringBuilder = null; bool flag = false; for (int i = 0; i < text.Length; i++) { char c = text[i]; bool flag2 = char.IsWhiteSpace(c); if (!(flag2 && flag)) { flag = flag2; if (stringBuilder != null) { stringBuilder.Append(flag2 ? ' ' : c); } else if (flag2 && c != ' ') { stringBuilder = new StringBuilder(text.Length); stringBuilder.Append(text, 0, i); stringBuilder.Append(' '); } } } if (stringBuilder == null) { return text; } return stringBuilder.ToString(); } private static int Priority(TargetKind kind) { return kind switch { TargetKind.Objective => 4, TargetKind.Player => 3, TargetKind.Hostile => 2, _ => 1, }; } private static bool Contains(string text, string needle) { if (!string.IsNullOrEmpty(text)) { return text.IndexOf(needle, StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static string ReadMemberString(object target, string name, string fallback) { return ReadMember(target, name, fallback); } private static float ReadMemberFloat(object target, string name, float fallback) { return ReadMember(target, name, fallback); } private static bool ReadMemberBool(object target, string name, bool fallback) { return ReadMember(target, name, fallback); } private static Vector3 ReadMemberVector3(object target, string name, Vector3 fallback) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) return ReadMember(target, name, fallback); } private static Component ReadMemberComponent(object target, string name) { return ReadMember(target, name, null); } private static T ReadMember(object target, string name, T fallback) { if (target == null) { return fallback; } try { Type type = target.GetType(); PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public); object obj = ((property != null) ? property.GetValue(target) : type.GetField(name, BindingFlags.Instance | BindingFlags.Public)?.GetValue(target)); if (obj == null) { return fallback; } if (obj is T result) { return result; } return (T)Convert.ChangeType(obj, typeof(T)); } catch { return fallback; } } } [HarmonyPatch(typeof(StartOfRound), "SpawnUnlockable")] internal static class CctvTerminalStoreSpawnPatch { private static bool _wokeTemplate; [HarmonyPrefix] private static void Prefix(int unlockableIndex) { _wokeTemplate = CCTVTerminalUnlockable.BeginVanillaFurnitureSpawn(unlockableIndex); } [HarmonyPostfix] private static void Postfix(int unlockableIndex) { bool wokeTemplate = _wokeTemplate; _wokeTemplate = false; CCTVTerminalUnlockable.EndVanillaFurnitureSpawn(unlockableIndex, wokeTemplate); } } internal static class CCTVTerminalUnlockable { internal const string UnlockableName = "CCTV Terminal"; private const string PrefabName = "Y4NGZ_CCTVTerminal_Furniture"; private const int PlaceableObjectLayer = 26; private static readonly Vector3 PlacementColliderSize = new Vector3(1.12f, 0.82f, 0.36f); private const int DefaultVanillaStorePrice = 200; private static bool _registrationAttempted; private static GameObject _prefab; private static UnlockableItem _unlockable; private static MethodInfo _spawnUnlockableMethod; private static bool _cachedPurchased; private static float _purchasedCacheValidUntil; private static MethodInfo _shipSystemsHasUpgradeMethod; private static bool _shipSystemsMethodResolved; private static bool? _shipSystemsPresent; private static bool _soldInVanillaStore; private static float _defaultPlaceableYOffset; private static bool _vanillaStoreSpawnTipShown; internal static bool SoldInVanillaStore => _soldInVanillaStore; internal static void Register() { if (_registrationAttempted) { return; } _registrationAttempted = true; try { BuildPrefab(); if (_unlockable == null) { return; } if (IsShipSystemsPresent()) { Unlockables.RegisterUnlockable(_unlockable, (StoreType)0, (TerminalNode)null, (TerminalNode)null, (TerminalNode)null, -1); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Registered CCTV Terminal as a hidden ship unlockable (invisible upgrade marker; no console furniture)."); } } else { int num = ResolveVanillaStorePrice(); _unlockable.alwaysInStock = true; Unlockables.RegisterUnlockable(_unlockable, (StoreType)1, (TerminalNode)null, (TerminalNode)null, (TerminalNode)null, num); _soldInVanillaStore = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV] Registered CCTV Terminal as a vanilla store ship upgrade for {num} credits (Contracted ship systems absent)."); } } NetworkPrefabs.RegisterNetworkPrefab(_prefab); WarnIfLethalLibCannotDeliverTheStoreItem(); } catch (Exception ex) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV] CCTV terminal unlockable registration failed: " + ex.Message)); } WarnIfLethalLibCannotDeliverTheStoreItem(); } } private static void WarnIfLethalLibCannotDeliverTheStoreItem() { string text = DependencyVersionAudit.DescribeOutdated("evaisa.lethallib"); bool flag = DependencyVersionAudit.IsLoadedButDead("evaisa.lethallib"); if (text != null || flag) { string text2 = text ?? "LethalLib is installed but failed to initialise, so its terminal and store patches never ran"; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogError((object)("[LethalCCTV] The CCTV Terminal will NOT appear in the ship store: " + text2 + ". Update it in your mod manager; another installed mod may be pinning an old version (e.g. LethalPhones pins LethalLib 0.16.2 / InputUtils 0.6.3).")); } } } private static int ResolveVanillaStorePrice() { try { LethalCCTVConfig config = SurveillanceBootstrap.Config; if (config?.CctvTerminalPrice != null) { return Mathf.Max(0, config.CctvTerminalPrice.Value); } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Falling back to the default CCTV terminal price: " + ex.Message)); } } return 200; } internal static bool BeginVanillaFurnitureSpawn(int unlockableIndex) { if (!_soldInVanillaStore || (Object)(object)_prefab == (Object)null) { return false; } try { if (!TryFindUnlockable(out var id, out var item) || id != unlockableIndex || item == null) { return false; } StampUnlockableId(_prefab, id); if (ShouldUseDefaultPose(item)) { ApplyDefaultFurniturePose(_prefab); } if (_prefab.activeSelf) { return false; } _prefab.SetActive(true); return true; } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Failed to prepare the CCTV terminal template for a vanilla store spawn: " + ex.Message)); } return false; } } internal static void EndVanillaFurnitureSpawn(int unlockableIndex, bool restorePrefabInactive) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (!_soldInVanillaStore) { return; } try { if (restorePrefabInactive && (Object)(object)_prefab != (Object)null) { _prefab.SetActive(false); } InvalidatePurchaseCache(); if (TryFindUnlockable(out var id, out var _) && id == unlockableIndex && TryGetSpawnedFurnitureRoot(out var root)) { PrepareSpawnedFurnitureRoot(root, id); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] CCTV terminal unlocked from the vanilla store purchase; no console furniture is spawned " + $"(invisible upgrade marker at world={root.transform.position} shipLocal={root.transform.localPosition}). " + "The CCTV access button is the purchased affordance.")); } AnnounceVanillaStoreInstall(); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Failed to finish a vanilla store CCTV terminal spawn: " + ex.Message)); } } } private static void AnnounceVanillaStoreInstall() { if (_vanillaStoreSpawnTipShown) { return; } _vanillaStoreSpawnTipShown = true; try { HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip("CCTV Terminal installed", "Press the red access button in front of the ship's monitor wall to view the cameras.", false, false, "LC_Tip1"); } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] CCTV terminal install tip failed: " + ex.Message)); } } } internal static bool IsPurchased() { if (Time.unscaledTime < _purchasedCacheValidUntil) { return _cachedPurchased; } _purchasedCacheValidUntil = Time.unscaledTime + 0.5f; _cachedPurchased = ComputeIsPurchased(); return _cachedPurchased; } internal static void InvalidatePurchaseCache() { _purchasedCacheValidUntil = 0f; } private static bool ComputeIsPurchased() { int id; UnlockableItem item; bool flag = TryFindUnlockable(out id, out item) && item != null && (item.hasBeenUnlockedByPlayer || item.alreadyUnlocked); if (TryReadShipSystemsPurchaseState(out var purchased)) { return purchased || flag; } if (_soldInVanillaStore) { return flag; } return !IsShipSystemsPresent() || flag; } private static bool TryGetSpawnedFurnitureRoot(out GameObject root) { root = null; if (!TryFindUnlockable(out var id, out var _)) { return false; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && instance.SpawnedShipUnlockables != null && instance.SpawnedShipUnlockables.TryGetValue(id, out var value) && (Object)(object)value != (Object)null) { if (IsPrefabTemplateRoot(value)) { instance.SpawnedShipUnlockables.Remove(id); return false; } root = value; PrepareSpawnedFurnitureRoot(root, id); return true; } PlaceableShipObject[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (PlaceableShipObject val in array) { if (!((Object)(object)val == (Object)null) && val.unlockableID == id) { GameObject val2 = (((Object)(object)val.parentObject != (Object)null) ? ((Component)val.parentObject).gameObject : ((Component)val).gameObject); if (!IsPrefabTemplateRoot(val2)) { root = val2; PrepareSpawnedFurnitureRoot(root, id); return (Object)(object)root != (Object)null; } } } return false; } internal static bool UnlockFromShipUpgrade(Terminal terminal) { Register(); if (!TryFindUnlockable(out var id, out var item) || item == null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] CCTV terminal unlockable was not present in StartOfRound.unlockablesList yet."); } return false; } StampUnlockableId(_prefab, id); StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return false; } if (!item.hasBeenUnlockedByPlayer && !item.alreadyUnlocked) { try { int num = (((Object)(object)terminal != (Object)null) ? terminal.groupCredits : FindObjectCredits()); instance.BuyShipUnlockableServerRpc(id, num); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)"[LethalCCTV] CCTV terminal unlock requested through StartOfRound."); } } catch (Exception ex) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV] BuyShipUnlockableServerRpc failed for CCTV terminal: " + ex.Message)); } return false; } } InvalidatePurchaseCache(); return EnsureFurnitureSpawned(id, item); } private static void BuildPrefab() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_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_009e: 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_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_00dc: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown //IL_0121: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: 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_01e1: 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: 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_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Expected O, but got Unknown GameObject val = new GameObject("Y4NGZ_CCTVTerminal_Furniture"); val.SetActive(false); ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val); NetworkObject obj = val.AddComponent(); obj.SynchronizeTransform = true; obj.SceneMigrationSynchronization = true; obj.SpawnWithObservers = true; obj.DontDestroyWithOwner = true; obj.AutoObjectParentSync = true; AssignStableNetworkHash(obj); AutoParentToShip val2 = val.AddComponent(); val2.overrideOffset = true; val2.positionOffset = ResolveDefaultLocalPosition(); val2.rotationOffset = ResolveDefaultEuler(); val2.disableObject = false; MeshFilter val3 = CreatePlacementMeshProxy(val.transform); Bounds val4 = CalculateLocalBounds(val.transform, ((Component)val3).transform); _defaultPlaceableYOffset = Mathf.Max(0f, 0f - (((Bounds)(ref val4)).center.y - ((Bounds)(ref val4)).extents.y)); GameObject val5 = new GameObject("CCTVTerminal_PlaceableHandle"); val5.transform.SetParent(val.transform, false); val5.transform.localPosition = ((Bounds)(ref val4)).center; val5.transform.localRotation = Quaternion.identity; val5.transform.localScale = Vector3.one; val5.layer = 26; SetTagSafe(val5, "PlaceableObject"); BoxCollider val6 = val5.AddComponent(); val6.size = EnsureMinimumColliderSize(((Bounds)(ref val4)).size); val6.center = Vector3.zero; ((Collider)val6).enabled = false; AudioSource obj2 = val5.AddComponent(); obj2.playOnAwake = false; obj2.spatialBlend = 1f; obj2.rolloffMode = (AudioRolloffMode)1; obj2.minDistance = 1f; obj2.maxDistance = 16f; PlaceableShipObject obj3 = val5.AddComponent(); obj3.parentObject = val2; obj3.mainMesh = val3; obj3.mainTransform = ((Component)val3).transform; obj3.placeObjectCollider = (Collider)(object)val6; obj3.yOffset = ResolveDefaultHeight(); obj3.overrideWallOffset = true; obj3.wallOffset = 0.18f; obj3.AllowPlacementOnWalls = true; obj3.AllowPlacementOnCounters = false; obj3.doCollisionPointCheck = false; _unlockable = new UnlockableItem { unlockableName = "CCTV Terminal", prefabObject = val, unlockableType = 1, IsPlaceable = true, canBeStored = false, maxNumber = 1, spawnPrefab = true, alwaysInStock = false, alreadyUnlocked = false, hasBeenUnlockedByPlayer = false }; _prefab = val; } private static void StampUnlockableId(GameObject root, int id) { if ((Object)(object)root == (Object)null || id < 0) { return; } try { AutoParentToShip component = root.GetComponent(); if ((Object)(object)component != (Object)null) { component.unlockableID = id; } PlaceableShipObject[] componentsInChildren = root.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { componentsInChildren[i].unlockableID = id; } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)$"[LethalCCTV] Failed to stamp CCTV terminal unlockable id {id}: {ex.Message}"); } } } private static MeshFilter CreatePlacementMeshProxy(Transform parent) { //IL_0024: 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_0044: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)obj).name = "CCTVTerminal_PlacementMeshProxy"; obj.transform.SetParent(parent, false); obj.transform.localPosition = Vector3.zero; obj.transform.localRotation = Quaternion.identity; obj.transform.localScale = PlacementColliderSize; Object.Destroy((Object)(object)obj.GetComponent()); MeshRenderer component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).enabled = false; } return obj.GetComponent(); } private static Bounds CalculateLocalBounds(Transform root, Transform source) { //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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: 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_024f: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0273: 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_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null || (Object)(object)source == (Object)null) { return new Bounds(Vector3.zero, PlacementColliderSize); } Bounds bounds = default(Bounds); ((Bounds)(ref bounds))..ctor(Vector3.zero, Vector3.zero); bool initialized = false; MeshFilter[] componentsInChildren = ((Component)source).GetComponentsInChildren(true); foreach (MeshFilter val in componentsInChildren) { Mesh val2 = (((Object)(object)val != (Object)null) ? val.sharedMesh : null); if (!((Object)(object)val2 == (Object)null)) { Bounds bounds2 = val2.bounds; EncapsulateLocalPoint(root, ((Component)val).transform.TransformPoint(((Bounds)(ref bounds2)).center + new Vector3(((Bounds)(ref bounds2)).extents.x, ((Bounds)(ref bounds2)).extents.y, ((Bounds)(ref bounds2)).extents.z)), ref bounds, ref initialized); EncapsulateLocalPoint(root, ((Component)val).transform.TransformPoint(((Bounds)(ref bounds2)).center + new Vector3(((Bounds)(ref bounds2)).extents.x, ((Bounds)(ref bounds2)).extents.y, 0f - ((Bounds)(ref bounds2)).extents.z)), ref bounds, ref initialized); EncapsulateLocalPoint(root, ((Component)val).transform.TransformPoint(((Bounds)(ref bounds2)).center + new Vector3(((Bounds)(ref bounds2)).extents.x, 0f - ((Bounds)(ref bounds2)).extents.y, ((Bounds)(ref bounds2)).extents.z)), ref bounds, ref initialized); EncapsulateLocalPoint(root, ((Component)val).transform.TransformPoint(((Bounds)(ref bounds2)).center + new Vector3(((Bounds)(ref bounds2)).extents.x, 0f - ((Bounds)(ref bounds2)).extents.y, 0f - ((Bounds)(ref bounds2)).extents.z)), ref bounds, ref initialized); EncapsulateLocalPoint(root, ((Component)val).transform.TransformPoint(((Bounds)(ref bounds2)).center + new Vector3(0f - ((Bounds)(ref bounds2)).extents.x, ((Bounds)(ref bounds2)).extents.y, ((Bounds)(ref bounds2)).extents.z)), ref bounds, ref initialized); EncapsulateLocalPoint(root, ((Component)val).transform.TransformPoint(((Bounds)(ref bounds2)).center + new Vector3(0f - ((Bounds)(ref bounds2)).extents.x, ((Bounds)(ref bounds2)).extents.y, 0f - ((Bounds)(ref bounds2)).extents.z)), ref bounds, ref initialized); EncapsulateLocalPoint(root, ((Component)val).transform.TransformPoint(((Bounds)(ref bounds2)).center + new Vector3(0f - ((Bounds)(ref bounds2)).extents.x, 0f - ((Bounds)(ref bounds2)).extents.y, ((Bounds)(ref bounds2)).extents.z)), ref bounds, ref initialized); EncapsulateLocalPoint(root, ((Component)val).transform.TransformPoint(((Bounds)(ref bounds2)).center - ((Bounds)(ref bounds2)).extents), ref bounds, ref initialized); } } if (!initialized) { return new Bounds(Vector3.zero, PlacementColliderSize); } return bounds; } private static void EncapsulateLocalPoint(Transform root, Vector3 worldPoint, ref Bounds bounds, ref bool initialized) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0018: Unknown result type (might be due to invalid IL or missing references) Vector3 val = root.InverseTransformPoint(worldPoint); if (!initialized) { bounds = new Bounds(val, Vector3.zero); initialized = true; } else { ((Bounds)(ref bounds)).Encapsulate(val); } } private static Vector3 EnsureMinimumColliderSize(Vector3 size) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) return new Vector3(Mathf.Max(PlacementColliderSize.x, Mathf.Abs(size.x)), Mathf.Max(PlacementColliderSize.y, Mathf.Abs(size.y)), Mathf.Max(PlacementColliderSize.z, Mathf.Abs(size.z))); } private static void ApplyDefaultFurniturePose(GameObject root) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_003c: 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_004d: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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) if ((Object)(object)root == (Object)null) { return; } AutoParentToShip component = root.GetComponent(); if ((Object)(object)component != (Object)null) { component.overrideOffset = true; component.positionOffset = ResolveDefaultLocalPosition(); component.rotationOffset = ResolveDefaultEuler(); component.startingPosition = component.positionOffset; component.startingRotation = component.rotationOffset; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] CCTV terminal upgrade-marker default pose (no visible furniture): " + $"hangarLocal={ResolveConfiguredHangarLocalPosition()} shipLocal={component.positionOffset} " + $"world={ResolveConfiguredWorldPosition()} rotOffset={component.rotationOffset}.")); } } PlaceableShipObject[] componentsInChildren = root.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { componentsInChildren[i].yOffset = ResolveDefaultHeight(); } } } private static bool ShouldUseDefaultPose(UnlockableItem item) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (item != null && !item.hasBeenMoved && item.placedPosition == Vector3.zero) { return item.placedRotation == Vector3.zero; } return false; } private static void PrepareSpawnedFurnitureRoot(GameObject root, int id, UnlockableItem item = null, bool forceDefaultPose = false) { //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) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_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_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)root == (Object)null) { return; } StampUnlockableId(root, id); try { if (!root.activeSelf) { root.SetActive(true); } AutoParentToShip component = root.GetComponent(); if ((Object)(object)component != (Object)null) { if (forceDefaultPose) { ApplyDefaultFurniturePose(root); } component.disableObject = false; component.overrideOffset = true; if (component.positionOffset == Vector3.zero) { component.positionOffset = ResolveDefaultLocalPosition(); } if (component.rotationOffset == Vector3.zero) { component.rotationOffset = ResolveDefaultEuler(); } component.MoveToOffset(); } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Failed preparing spawned CCTV terminal furniture root: " + ex.Message)); } } } private static bool IsPrefabTemplateRoot(GameObject root) { if ((Object)(object)root == (Object)null || (Object)(object)_prefab == (Object)null) { return false; } if (root == _prefab) { return true; } Transform val = root.transform; while ((Object)(object)val != (Object)null) { if (((Component)val).gameObject == _prefab) { return true; } val = val.parent; } return false; } private static bool EnsureFurnitureSpawned(int id, UnlockableItem item) { if (id < 0 || item == null) { return false; } item.unlockableType = 1; item.IsPlaceable = true; item.spawnPrefab = true; item.prefabObject = _prefab; if (TryGetSpawnedFurnitureRoot(out var root)) { PrepareSpawnedFurnitureRoot(root, id, item); return true; } if (item.inStorage) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] CCTV terminal furniture is unlocked but currently stored; not forcing a spawn."); } return false; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return false; } if (!((NetworkBehaviour)instance).IsServer) { return false; } try { if (ShouldUseDefaultPose(item)) { ApplyDefaultFurniturePose(_prefab); } if (instance.SpawnedShipUnlockables != null && instance.SpawnedShipUnlockables.TryGetValue(id, out var value) && (Object)(object)value == (Object)null) { instance.SpawnedShipUnlockables.Remove(id); } item.hasBeenUnlockedByPlayer = true; if ((object)_spawnUnlockableMethod == null) { _spawnUnlockableMethod = typeof(StartOfRound).GetMethod("SpawnUnlockable", BindingFlags.Instance | BindingFlags.NonPublic); } if (_spawnUnlockableMethod == null) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)"[LethalCCTV] Could not resolve StartOfRound.SpawnUnlockable for CCTV terminal furniture."); } return false; } bool flag = (Object)(object)_prefab != (Object)null && !_prefab.activeSelf; if (flag) { _prefab.SetActive(true); } try { _spawnUnlockableMethod.Invoke(instance, new object[2] { id, true }); } finally { if (flag && (Object)(object)_prefab != (Object)null) { _prefab.SetActive(false); } } if (TryGetSpawnedFurnitureRoot(out var root2)) { PrepareSpawnedFurnitureRoot(root2, id, item); ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)"[LethalCCTV] Ensured the CCTV terminal upgrade marker is spawned after the ship-upgrade purchase (no visible furniture)."); } return true; } } catch (Exception ex) { ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogWarning((object)("[LethalCCTV] Failed to ensure CCTV terminal furniture spawn: " + ex.Message)); } } return false; } private static int FindObjectCredits() { try { Terminal val = Object.FindObjectOfType(); return ((Object)(object)val != (Object)null) ? val.groupCredits : 0; } catch { return 0; } } private static Vector3 ResolveConfiguredWorldPosition() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0047: Unknown result type (might be due to invalid IL or missing references) Quaternion val = ResolveConfiguredWorldRotation(); return (Vector3)((SurveillanceBootstrap.Config != null) ? SurveillanceBootstrap.Config.MonitorPosition : new Vector3(11f, 3f, -13f)) + val * new Vector3(0f, 0f, -0.14f); } private static Quaternion ResolveConfiguredWorldRotation() { //IL_0021: 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) if (SurveillanceBootstrap.Config == null) { return Quaternion.Euler(0f, 90f, 0f); } return SurveillanceBootstrap.Config.MonitorRotation; } private static Vector3 ResolveConfiguredHangarLocalPosition() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ResolveConfiguredWorldPosition(); Transform val2 = ResolveHangarShipTransform(); if (!((Object)(object)val2 != (Object)null)) { return val; } return val2.InverseTransformPoint(val); } private static Transform ResolveHangarShipTransform() { GameObject val = GameObject.Find("Environment/HangarShip"); if (!((Object)(object)val != (Object)null)) { return null; } return val.transform; } private static Vector3 ResolveDefaultLocalPosition() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_002a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ResolveConfiguredWorldPosition(); Transform val2 = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.elevatorTransform : null); if (!((Object)(object)val2 != (Object)null)) { return val; } return val2.InverseTransformPoint(val); } private static Vector3 ResolveDefaultEuler() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) Quaternion val = ResolveConfiguredWorldRotation(); Transform val2 = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.elevatorTransform : null); Quaternion val3 = (((Object)(object)val2 != (Object)null) ? (Quaternion.Inverse(val2.rotation) * val) : val); return ((Quaternion)(ref val3)).eulerAngles; } private static float ResolveDefaultHeight() { return _defaultPlaceableYOffset; } private static bool TryFindUnlockable(out int id, out UnlockableItem item) { id = -1; item = null; List list = StartOfRound.Instance?.unlockablesList?.unlockables; if (list == null) { return false; } for (int i = 0; i < list.Count; i++) { UnlockableItem val = list[i]; if (val != null && (val == _unlockable || string.Equals(val.unlockableName, "CCTV Terminal", StringComparison.OrdinalIgnoreCase))) { id = i; item = val; return true; } } return false; } private static bool TryReadShipSystemsPurchaseState(out bool purchased) { purchased = false; try { if (!_shipSystemsMethodResolved) { _shipSystemsMethodResolved = true; _shipSystemsHasUpgradeMethod = ResolveShipSystemsApiType()?.GetMethod("HasCctvTerminalUpgrade", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } if (_shipSystemsHasUpgradeMethod == null) { return false; } if (_shipSystemsHasUpgradeMethod.Invoke(null, null) is bool flag) { purchased = flag; return true; } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Failed to read ship-system CCTV terminal state: " + ex.Message)); } } return false; } private static Type ResolveShipSystemsApiType() { return Type.GetType("Y4NGZCompany.ShipSystems.Layout.ShipSystemsApi, Y4NGZCompany", throwOnError: false) ?? Type.GetType("LGUShipSystems.ShipSystemsApi, LGUShipSystems", throwOnError: false); } private static bool IsShipSystemsPresent() { if (_shipSystemsPresent.HasValue) { return _shipSystemsPresent.Value; } _shipSystemsPresent = ResolveShipSystemsApiType() != null; return _shipSystemsPresent.Value; } private static void AssignStableNetworkHash(NetworkObject networkObject) { if ((Object)(object)networkObject == (Object)null) { return; } try { uint num; using (MD5 mD = MD5.Create()) { num = BitConverter.ToUInt32(mD.ComputeHash(Encoding.UTF8.GetBytes("com.y4ngz.company.lethalcctv.Y4NGZ_CCTVTerminal_Furniture")), 0); } Type typeFromHandle = typeof(NetworkObject); PropertyInfo property = typeFromHandle.GetProperty("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite) { property.SetValue(networkObject, num); } else { (typeFromHandle.GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? typeFromHandle.GetField("k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic))?.SetValue(networkObject, num); } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Failed to assign CCTV terminal NetworkObject hash: " + ex.Message)); } } } private static void SetTagSafe(GameObject obj, string tag) { if ((Object)(object)obj == (Object)null) { return; } try { obj.tag = tag; } catch { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Tag '" + tag + "' was unavailable for CCTV terminal furniture.")); } } } } internal static class CCTVVanillaMonitorButtons { private sealed class TakenOverButton { internal InteractTrigger Trigger; internal string OriginalHoverTip; internal string OriginalDisabledHoverTip; internal bool OriginalInteractable; internal UnityAction Listener; internal AudioSource Audio; } private const string RedHoverTip = "View cameras : [E]"; private const string GreyHoverTip = "Switch monitor feed : [E]"; private static readonly float[] ProbeBackoffSeconds = new float[3] { 1f, 5f, 15f }; private const float TipRefreshIntervalSeconds = 0.2f; private const float PressSfxVolume = 0.9f; private static TakenOverButton _redButton; private static TakenOverButton _greyButton; private static float _nextProbeAt; private static int _probeFailures; private static StartOfRound _probeScopeOwner; private static ManualCameraRenderer _probeScopeMapScreen; private static bool _loggedProbeExhausted; private static float _nextTipRefreshAt; private static bool _loggedTakeover; private static bool _redButtonVanillaPowerMode; private static bool _loggedRedButtonVanillaPowerMode; internal static Transform RedButtonTransform { get { if (_redButton == null || !((Object)(object)_redButton.Trigger != (Object)null)) { return null; } return ((Component)_redButton.Trigger).transform; } } internal static void Tick() { if (EnsureButtons() && Time.unscaledTime >= _nextTipRefreshAt) { _nextTipRefreshAt = Time.unscaledTime + 0.2f; RefreshRedButtonState(); RefreshGreyButtonState(); } } internal static void Shutdown() { Release(ref _redButton); Release(ref _greyButton); _redButtonVanillaPowerMode = false; _loggedRedButtonVanillaPowerMode = false; _loggedTakeover = false; _probeScopeOwner = null; _probeScopeMapScreen = null; ResetProbeBackoff(); } private static bool EnsureButtons() { bool flag = _redButton != null && (Object)(object)_redButton.Trigger != (Object)null; bool flag2 = _greyButton != null && (Object)(object)_greyButton.Trigger != (Object)null; if (flag && flag2) { return true; } if (_redButton != null && !flag) { _redButton = null; _redButtonVanillaPowerMode = false; } if (_greyButton != null && !flag2) { _greyButton = null; } StartOfRound instance = StartOfRound.Instance; ManualCameraRenderer val = (((Object)(object)instance != (Object)null) ? instance.mapScreen : null); Transform val2 = ResolveProbeScope(instance, val); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return false; } if (instance != _probeScopeOwner || val != _probeScopeMapScreen) { _probeScopeOwner = instance; _probeScopeMapScreen = val; ResetProbeBackoff(); } if (Time.unscaledTime < _nextProbeAt) { if (_redButton == null) { return _greyButton != null; } return true; } InteractTrigger[] array; try { array = ((Component)val2).GetComponentsInChildren(true); } catch { array = null; } if (array == null) { NoteProbeFailure(); return false; } foreach (InteractTrigger val3 in array) { if (!((Object)(object)val3 == (Object)null) && val3.onInteract != null) { if (_redButton == null && HasPersistentCall((UnityEventBase)(object)val3.onInteract, val, "SwitchScreenButton")) { _redButton = TakeOver(val3, OnRedPressed, "red/power"); _redButtonVanillaPowerMode = false; } else if (_greyButton == null && HasPersistentCall((UnityEventBase)(object)val3.onInteract, val, "SwitchRadarTargetForward")) { _greyButton = TakeOver(val3, OnGreyPressed, "grey/switch"); } } } if (_redButton == null || _greyButton == null) { NoteProbeFailure(); return false; } ResetProbeBackoff(); if (!_loggedTakeover) { _loggedTakeover = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Vanilla monitor buttons taken over: red=" + GetPath(((Component)_redButton.Trigger).transform) + " grey=" + GetPath(((Component)_greyButton.Trigger).transform) + ".")); } } return true; } private static Transform ResolveProbeScope(StartOfRound sor, ManualCameraRenderer mapScreen) { Transform val = (((Object)(object)sor != (Object)null) ? sor.elevatorTransform : null); if ((Object)(object)val != (Object)null) { Transform val2 = val.Find("ShipModels2b/MonitorWall"); if ((Object)(object)val2 != (Object)null) { return val2; } return val; } if (!((Object)(object)mapScreen != (Object)null)) { return null; } return ((Component)mapScreen).transform.root; } private static void ResetProbeBackoff() { _probeFailures = 0; _nextProbeAt = 0f; _loggedProbeExhausted = false; } private static void NoteProbeFailure() { int num = Mathf.Min(_probeFailures, ProbeBackoffSeconds.Length - 1); _nextProbeAt = Time.unscaledTime + ProbeBackoffSeconds[num]; if (_probeFailures < ProbeBackoffSeconds.Length) { _probeFailures++; } if (_probeFailures >= ProbeBackoffSeconds.Length && !_loggedProbeExhausted) { _loggedProbeExhausted = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Vanilla monitor buttons did not resolve in the ship subtree; " + $"retrying at {ProbeBackoffSeconds[ProbeBackoffSeconds.Length - 1]:0}s intervals (logged once).")); } } } private static bool HasPersistentCall(UnityEventBase unityEvent, ManualCameraRenderer target, string methodName) { int persistentEventCount = unityEvent.GetPersistentEventCount(); for (int i = 0; i < persistentEventCount; i++) { if ((object)unityEvent.GetPersistentTarget(i) == target && string.Equals(unityEvent.GetPersistentMethodName(i), methodName, StringComparison.Ordinal)) { return true; } } return false; } private static TakenOverButton TakeOver(InteractTrigger trigger, UnityAction listener, string label) { TakenOverButton takenOverButton = new TakenOverButton { Trigger = trigger, OriginalHoverTip = trigger.hoverTip, OriginalDisabledHoverTip = trigger.disabledHoverTip, OriginalInteractable = trigger.interactable, Listener = listener }; int persistentEventCount = ((UnityEventBase)trigger.onInteract).GetPersistentEventCount(); for (int i = 0; i < persistentEventCount; i++) { ((UnityEventBase)trigger.onInteract).SetPersistentListenerState(i, (UnityEventCallState)0); } ((UnityEvent)(object)trigger.onInteract).AddListener(listener); takenOverButton.Audio = ((Component)trigger).GetComponent(); if ((Object)(object)takenOverButton.Audio == (Object)null) { takenOverButton.Audio = ((Component)trigger).gameObject.AddComponent(); takenOverButton.Audio.playOnAwake = false; takenOverButton.Audio.spatialBlend = 1f; takenOverButton.Audio.minDistance = 0.8f; takenOverButton.Audio.maxDistance = 12f; } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Monitor button takeover (" + label + "): " + GetPath(((Component)trigger).transform) + ".")); } return takenOverButton; } private static void Release(ref TakenOverButton button) { if (button == null) { return; } InteractTrigger trigger = button.Trigger; if ((Object)(object)trigger != (Object)null) { if (button.Listener != null && trigger.onInteract != null) { ((UnityEvent)(object)trigger.onInteract).RemoveListener(button.Listener); } int num = ((trigger.onInteract != null) ? ((UnityEventBase)trigger.onInteract).GetPersistentEventCount() : 0); for (int i = 0; i < num; i++) { ((UnityEventBase)trigger.onInteract).SetPersistentListenerState(i, (UnityEventCallState)2); } trigger.hoverTip = button.OriginalHoverTip; trigger.disabledHoverTip = button.OriginalDisabledHoverTip; trigger.interactable = button.OriginalInteractable; } button = null; } private static void RefreshRedButtonState() { if (_redButton != null && !((Object)(object)_redButton.Trigger == (Object)null)) { InteractTrigger trigger = _redButton.Trigger; SetRedButtonVanillaPowerMode(CCTVVanillaMonitorDisplay.IsGeneralImprovementsMonitorWallActive() && !CCTVVanillaMonitorDisplay.OwnsGeneralImprovementsMapScreen() && CCTVAccessButton.IsAvailable); string unavailableReason; if (_redButtonVanillaPowerMode) { trigger.interactable = _redButton.OriginalInteractable; trigger.hoverTip = _redButton.OriginalHoverTip; trigger.disabledHoverTip = _redButton.OriginalDisabledHoverTip; } else if (CCTVAccessButton.IsAvailable) { trigger.interactable = false; trigger.disabledHoverTip = string.Empty; } else if (CCTVMonitorFeedSync.IsEntryAvailable(out unavailableReason)) { trigger.interactable = true; trigger.hoverTip = "View cameras : [E]"; } else { trigger.interactable = false; trigger.disabledHoverTip = unavailableReason ?? string.Empty; } } } private static void SetRedButtonVanillaPowerMode(bool vanillaPower) { TakenOverButton redButton = _redButton; if (redButton == null || (Object)(object)redButton.Trigger == (Object)null || redButton.Trigger.onInteract == null || _redButtonVanillaPowerMode == vanillaPower) { return; } _redButtonVanillaPowerMode = vanillaPower; InteractEvent onInteract = redButton.Trigger.onInteract; int persistentEventCount = ((UnityEventBase)onInteract).GetPersistentEventCount(); for (int i = 0; i < persistentEventCount; i++) { ((UnityEventBase)onInteract).SetPersistentListenerState(i, (UnityEventCallState)(vanillaPower ? 2 : 0)); } if (redButton.Listener != null) { ((UnityEvent)(object)onInteract).RemoveListener(redButton.Listener); if (!vanillaPower) { ((UnityEvent)(object)onInteract).AddListener(redButton.Listener); } } if (vanillaPower && !_loggedRedButtonVanillaPowerMode) { _loggedRedButtonVanillaPowerMode = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] GeneralImprovements better monitors are active; the red bezel button keeps its vanilla monitor-power behaviour and the physical CCTV access button owns entry."); } } } private static void RefreshGreyButtonState() { if (_greyButton != null && !((Object)(object)_greyButton.Trigger == (Object)null)) { InteractTrigger trigger = _greyButton.Trigger; if (CCTVMonitorFeedSync.IsFeedToggleAvailable()) { trigger.interactable = true; trigger.hoverTip = "Switch monitor feed : [E]"; } else { trigger.interactable = false; trigger.disabledHoverTip = string.Empty; } } } private static void OnRedPressed(PlayerControllerB player) { RequestEntry(player); } internal static void RequestEntry(PlayerControllerB player) { PlayerControllerB local = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)local == (Object)null || ((Object)(object)player != (Object)null && (Object)(object)player != (Object)(object)local)) { return; } if (!CCTVMonitorFeedSync.IsEntryAvailable(out var unavailableReason)) { if (!string.IsNullOrEmpty(unavailableReason)) { HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip("CCTV", unavailableReason, false, false, "LC_Tip1"); } } return; } CCTVMonitorFeedSync.RequestEntry(local, delegate { BeginEntry(local); }, delegate(string message) { if (!string.IsNullOrEmpty(message)) { HUDManager instance2 = HUDManager.Instance; if (instance2 != null) { instance2.DisplayTip("CCTV", message, true, false, "LC_Tip1"); } } }); } private static void BeginEntry(PlayerControllerB player) { if ((Object)(object)QuadMonitor.MonitorRoot == (Object)null || QuadMonitor.QuadRTs == null) { QuadMonitor.Spawn(); } MonitorFocus.BeginEntryPoseSettle(player); } private static void OnGreyPressed(PlayerControllerB player) { PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if (!((Object)(object)val == (Object)null) && (!((Object)(object)player != (Object)null) || !((Object)(object)player != (Object)(object)val)) && CCTVMonitorFeedSync.IsFeedToggleAvailable()) { PlayPressSfx(_greyButton); CCTVMonitorFeedSync.RequestFeedToggle(val); } } internal static void PlayRedButtonPressSfx() { PlayPressSfx(_redButton); } private static void PlayPressSfx(TakenOverButton button) { try { AudioClip buttonPressClip = CCTVOperatorStation.GetButtonPressClip(); if ((Object)(object)button?.Audio != (Object)null && (Object)(object)buttonPressClip != (Object)null) { button.Audio.PlayOneShot(buttonPressClip, 0.9f); } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Monitor button press sfx failed: " + ex.Message)); } } } private static string GetPath(Transform transform) { if ((Object)(object)transform == (Object)null) { return ""; } string text = ((Object)transform).name; Transform parent = transform.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } } internal static class CCTVVanillaMonitorDisplay { private sealed class ScreenBinding { private readonly string _label; private readonly List<(ManualCameraRenderer driver, bool wasEnabled)> _disabledDrivers = new List<(ManualCameraRenderer, bool)>(); private MeshRenderer _renderer; private int _materialIndex = -1; private Material _savedSlotMaterial; private Material _runtimeMaterial; private Material[] _ownedSharedMaterials; private readonly List _scratchSharedMaterials = new List(8); private float _nextDriverRediscoveryAt; private bool _isGeneralImprovementsScreen; private bool _isGeneralImprovementsMapScreen; private ManualCameraRenderer _identityDriver; internal bool IsBound { get { if ((Object)(object)_renderer != (Object)null) { return _materialIndex >= 0; } return false; } } internal MeshRenderer Renderer => _renderer; internal int MaterialIndex => _materialIndex; internal bool IsGeneralImprovementsScreen => _isGeneralImprovementsScreen; internal bool IsGeneralImprovementsMapScreen { get { if (_isGeneralImprovementsScreen) { return _isGeneralImprovementsMapScreen; } return false; } } private bool StandDownForGeneralImprovementsPower { get { if (_isGeneralImprovementsScreen && !_isGeneralImprovementsMapScreen) { return !GeneralImprovementsMonitorCompat.MonitorsPoweredOn(); } return false; } } internal ScreenBinding(string label) { _label = label; } internal bool OwnsDriver(ManualCameraRenderer driver) { if ((Object)(object)driver == (Object)null) { return false; } for (int i = 0; i < _disabledDrivers.Count; i++) { if ((Object)(object)_disabledDrivers[i].driver == (Object)(object)driver) { return true; } } if ((Object)(object)_identityDriver != (Object)null && (Object)(object)driver == (Object)(object)_identityDriver) { return true; } if (IsBound) { if (!((Object)(object)driver.mesh == (Object)(object)_renderer)) { return (Object)(object)driver.mesh2 == (Object)(object)_renderer; } return true; } return false; } internal bool Bind(MeshRenderer renderer, int materialIndex, Texture texture, bool generalImprovementsScreen = false, ManualCameraRenderer identityDriver = null, bool generalImprovementsMapScreen = false) { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)renderer == (Object)null || (Object)(object)texture == (Object)null || materialIndex < 0) { return false; } if ((Object)(object)_renderer == (Object)(object)renderer && _materialIndex == materialIndex) { _isGeneralImprovementsMapScreen = generalImprovementsScreen && generalImprovementsMapScreen; if ((Object)(object)identityDriver != (Object)null && (Object)(object)_identityDriver != (Object)(object)identityDriver) { _identityDriver = identityDriver; DisableDriver(identityDriver); } return Reassert(); } Restore(); Material[] sharedMaterials; try { sharedMaterials = ((Renderer)renderer).sharedMaterials; } catch { return false; } if (materialIndex >= sharedMaterials.Length || (Object)(object)sharedMaterials[materialIndex] == (Object)null) { return false; } if (IsCeremonyHeldMaterial(sharedMaterials[materialIndex])) { return false; } _renderer = renderer; _materialIndex = materialIndex; _isGeneralImprovementsScreen = generalImprovementsScreen; _isGeneralImprovementsMapScreen = generalImprovementsScreen && generalImprovementsMapScreen; _identityDriver = identityDriver; _savedSlotMaterial = sharedMaterials[materialIndex]; _runtimeMaterial = (Material)(generalImprovementsScreen ? ((object)CreateGeneralImprovementsScreenMaterial(_label, _savedSlotMaterial)) : ((object)new Material(_savedSlotMaterial) { name = ((Object)_savedSlotMaterial).name + "_LethalCCTV_" + _label })); ApplyTextureToMaterial(_runtimeMaterial, texture); sharedMaterials[materialIndex] = _runtimeMaterial; _ownedSharedMaterials = sharedMaterials; try { ((Renderer)renderer).sharedMaterials = sharedMaterials; } catch { } DisableDrivers(); ScheduleNextDriverRediscovery(Time.unscaledTime); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV] CCTV {_label} monitor bound to {GetPath(((Component)renderer).transform)} materialIndex={materialIndex}" + ((!generalImprovementsScreen) ? string.Empty : (_isGeneralImprovementsMapScreen ? " (GeneralImprovements MAP screen)" : " (GeneralImprovements screen)")) + "; hydraulic door monitor untouched.")); } return true; } private static Material CreateGeneralImprovementsScreenMaterial(string label, Material fallbackTemplate) { //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_0076: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown Shader val = null; try { val = Shader.Find("HDRP/Unlit"); } catch { } if ((Object)(object)val == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] HDRP/Unlit was not found; falling back to cloning the GeneralImprovements screen material for the " + label + " monitor.")); } return new Material(fallbackTemplate) { name = ((Object)fallbackTemplate).name + "_LethalCCTV_" + label }; } Material val2 = new Material(val) { name = "LethalCCTV_" + label + "_GIScreen" }; if (val2.HasProperty("_AlbedoAffectEmissive")) { val2.SetFloat("_AlbedoAffectEmissive", 1f); } if (val2.HasProperty("_EmissiveColor")) { val2.SetColor("_EmissiveColor", Color.white); } return val2; } internal bool Reassert() { if (!IsBound || (Object)(object)_runtimeMaterial == (Object)null) { return false; } if (StandDownForGeneralImprovementsPower) { DisableTrackedDriverCameras(); return false; } Material[] sharedMaterials; try { sharedMaterials = ((Renderer)_renderer).sharedMaterials; } catch { return false; } if (_materialIndex >= sharedMaterials.Length) { return false; } bool flag = false; if ((Object)(object)sharedMaterials[_materialIndex] != (Object)(object)_runtimeMaterial && !IsCeremonyHeldMaterial(sharedMaterials[_materialIndex])) { sharedMaterials[_materialIndex] = _runtimeMaterial; try { ((Renderer)_renderer).sharedMaterials = sharedMaterials; } catch { } _ownedSharedMaterials = sharedMaterials; flag = true; } for (int i = 0; i < _disabledDrivers.Count; i++) { ManualCameraRenderer item = _disabledDrivers[i].driver; if (!((Object)(object)item == (Object)null)) { if (((Behaviour)item).enabled) { ((Behaviour)item).enabled = false; flag = true; } flag |= DisableDriverCamera(item); } } return flag; } internal void ReassertFast(bool verifyMaterial) { if (!IsBound || (Object)(object)_runtimeMaterial == (Object)null) { return; } if (StandDownForGeneralImprovementsPower) { DisableTrackedDriverCameras(); return; } if (verifyMaterial && !IsRuntimeMaterialStillAssigned(out var currentSlotMaterial)) { if (IsCeremonyHeldMaterial(currentSlotMaterial)) { DisableTrackedDriverCameras(); return; } if (_ownedSharedMaterials == null || _materialIndex < 0 || _materialIndex >= _ownedSharedMaterials.Length || !((Object)(object)_ownedSharedMaterials[_materialIndex] == (Object)(object)_runtimeMaterial)) { Reassert(); return; } try { ((Renderer)_renderer).sharedMaterials = _ownedSharedMaterials; } catch { Reassert(); return; } } DisableTrackedDriverCameras(); } private bool IsRuntimeMaterialStillAssigned(out Material currentSlotMaterial) { currentSlotMaterial = null; if (!IsBound || (Object)(object)_runtimeMaterial == (Object)null) { return false; } try { _scratchSharedMaterials.Clear(); ((Renderer)_renderer).GetSharedMaterials(_scratchSharedMaterials); if (_materialIndex < 0 || _materialIndex >= _scratchSharedMaterials.Count) { return false; } currentSlotMaterial = _scratchSharedMaterials[_materialIndex]; return (Object)(object)currentSlotMaterial == (Object)(object)_runtimeMaterial; } catch { return false; } } private void DisableTrackedDriverCameras() { for (int i = 0; i < _disabledDrivers.Count; i++) { ManualCameraRenderer item = _disabledDrivers[i].driver; if ((Object)(object)item == (Object)null) { continue; } try { if (((Behaviour)item).enabled) { ((Behaviour)item).enabled = false; } } catch { } DisableDriverCamera(item); } } internal bool RediscoverDriversIfDue(float now) { if (!IsBound) { return false; } if (_nextDriverRediscoveryAt > 0f && now < _nextDriverRediscoveryAt) { return false; } ScheduleNextDriverRediscovery(now); return DisableDrivers(); } private void ScheduleNextDriverRediscovery(float now) { _nextDriverRediscoveryAt = now + 30f; } private bool DisableDrivers() { bool flag = TrackIdentityDriver(); ManualCameraRenderer[] array; try { array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); } catch { return flag; } foreach (ManualCameraRenderer val in array) { if ((Object)(object)val == (Object)null || ((Object)(object)val.mesh != (Object)(object)_renderer && (Object)(object)val.mesh2 != (Object)(object)_renderer)) { continue; } bool flag2 = false; for (int j = 0; j < _disabledDrivers.Count; j++) { if ((Object)(object)_disabledDrivers[j].driver == (Object)(object)val) { flag2 = true; break; } } if (flag2) { flag |= DisableDriver(val); continue; } _disabledDrivers.Add((val, ((Behaviour)val).enabled)); flag = true; flag |= DisableDriver(val); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Disabled ManualCameraRenderer on " + GetPath(((Component)val).transform) + " while CCTV owns the " + _label + " monitor.")); } } return flag; } private bool TrackIdentityDriver() { ManualCameraRenderer identityDriver = _identityDriver; if ((Object)(object)identityDriver == (Object)null) { return false; } for (int i = 0; i < _disabledDrivers.Count; i++) { if ((Object)(object)_disabledDrivers[i].driver == (Object)(object)identityDriver) { return DisableDriver(identityDriver); } } _disabledDrivers.Add((identityDriver, ((Behaviour)identityDriver).enabled)); DisableDriver(identityDriver); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Disabled ManualCameraRenderer on " + GetPath(((Component)identityDriver).transform) + " by driver identity while CCTV owns the " + _label + " GeneralImprovements screen.")); } return true; } private static bool DisableDriver(ManualCameraRenderer driver) { if ((Object)(object)driver == (Object)null) { return false; } bool flag = false; try { if (((Behaviour)driver).enabled) { ((Behaviour)driver).enabled = false; flag = true; } } catch { } return flag | DisableDriverCamera(driver); } private static bool DisableDriverCamera(ManualCameraRenderer driver) { if ((Object)(object)driver == (Object)null) { return false; } bool result = false; try { if ((Object)(object)driver.cam != (Object)null && ((Behaviour)driver.cam).enabled) { ((Behaviour)driver.cam).enabled = false; result = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Disabled frozen-on camera '" + ((Object)driver.cam).name + "' of suppressed ManualCameraRenderer " + GetPath(((Component)driver).transform) + ".")); } } if ((Object)(object)driver.mapCamera != (Object)null && (Object)(object)driver.mapCamera != (Object)(object)driver.cam && ((Behaviour)driver.mapCamera).enabled) { ((Behaviour)driver.mapCamera).enabled = false; result = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] Disabled frozen-on map camera '" + ((Object)driver.mapCamera).name + "' of suppressed ManualCameraRenderer " + GetPath(((Component)driver).transform) + ".")); } } } catch { } return result; } internal bool Restore() { bool result = false; if ((Object)(object)_renderer != (Object)null && (Object)(object)_savedSlotMaterial != (Object)null) { try { Material[] sharedMaterials = ((Renderer)_renderer).sharedMaterials; if (_materialIndex >= 0 && _materialIndex < sharedMaterials.Length && (Object)(object)sharedMaterials[_materialIndex] == (Object)(object)_runtimeMaterial) { sharedMaterials[_materialIndex] = _savedSlotMaterial; ((Renderer)_renderer).sharedMaterials = sharedMaterials; result = true; } } catch { } } for (int i = 0; i < _disabledDrivers.Count; i++) { var (val, flag) = _disabledDrivers[i]; if (!((Object)(object)val != (Object)null)) { continue; } try { if (((Behaviour)val).enabled != flag) { result = true; } ((Behaviour)val).enabled = flag; } catch { } } _disabledDrivers.Clear(); if ((Object)(object)_runtimeMaterial != (Object)null) { Object.Destroy((Object)(object)_runtimeMaterial); result = true; } _runtimeMaterial = null; _renderer = null; _materialIndex = -1; _savedSlotMaterial = null; _ownedSharedMaterials = null; _nextDriverRediscoveryAt = 0f; _isGeneralImprovementsScreen = false; _isGeneralImprovementsMapScreen = false; _identityDriver = null; return result; } } private const string LowerLeftRootName = "LethalCCTV_LowerLeftCCTVOverlay"; private const string RigRootName = "LethalCCTV_VanillaMonitorRenderRig"; private const string LowerLeftMonitorPath = "Environment/HangarShip/ShipModels2b/MonitorWall/Cube.001"; private const int FallbackLowerLeftMaterialIndex = 1; private const int UiRenderLayer = 31; private const int MonitorWidth = 768; private const int MonitorHeight = 432; private const int MonitorRenderScale = 1; private const int MonitorRenderWidth = 768; private const int MonitorRenderHeight = 432; private const float RadarImageRotationDegrees = 0f; private const float RadarImageScale = 1f; private const float ProbeIntervalSeconds = 1f; private static GameObject _rigRoot; private static RenderTexture _leftRenderTexture; private static RenderTexture _rightRenderTexture; private static Camera _leftCamera; private static Camera _rightCamera; private static RawImage[] _slotImages; private static RawImage _rightRadarImage; private static TextMeshProUGUI _rightRadarLabel; private static TextMeshProUGUI _rightRadarLegend; private static GameObject _lowerLeftRoot; private static RawImage _lowerLeftImage; private static TextMeshProUGUI _leftCameraLabel; private static TextMeshProUGUI _leftPageLabel; private static Image _leftSwitchFlashImage; private static GameObject _leftReticleRoot; private static RectTransform _leftTerminalOverlayRoot; private static float _leftSwitchFlashStartedAt; private static float _leftSwitchFlashUntil; private static string _lastLeftCameraLabel; private static string _lastLeftPageLabel; private static TextMeshProUGUI _leftClockLabel; private static Image _leftRecDot; private static TextMeshProUGUI _leftRecLabel; private static TextMeshProUGUI _leftStatusLabel; private static Image[] _leftSignalBars; private static GameObject _leftSignalLostRoot; private static RawImage _leftSignalLostStatic; private static TextMeshProUGUI _leftSignalLostLabel; private static Texture2D _signalLostNoiseTexture; private static int _signalLostStaticStep; private static string _lastLeftClockText; private static string _lastLeftStatusText; private static string _lastLeftSignalLostText; private static int _lastLeftSignalBars = -1; private static bool _lastLeftRecOn; private static bool _lastLeftSignalLost; private const float RecBlinkPeriodSeconds = 1f; private const float RecBlinkOnFraction = 0.55f; private const int SignalBarCount = 5; private static readonly ScreenBinding _lowerLeftBinding = new ScreenBinding("lower-left"); private static readonly ScreenBinding _lowerRightBinding = new ScreenBinding("lower-right"); private static readonly ScreenBinding _lowerRightAuxBinding = new ScreenBinding("lower-right-aux"); private static bool _suppressionCaptured; private static bool _levelDescriptionWasEnabled; private static bool _videoReelWasEnabled; private static bool _videoReelWasPlaying; private static bool _mapScreenWasEnabled; private static RawImage _mapScreenRawImage; private static Texture _mapScreenRawImageTexture; private static Graphic[] _lowerLeftSuppressedGraphics; private static bool[] _lowerLeftSuppressedGraphicStates; private static bool _cctvModeActive; private static float _nextProbeAt; private const float BindMaintenanceIntervalSeconds = 1f; private const float DriverRediscoveryIntervalSeconds = 30f; private const float FocusedCompositorPassiveIntervalSeconds = 0.1f; private const float FocusedCompositorInteractiveIntervalSeconds = 1f / 18f; private const float RightFocusedCompositorIntervalSeconds = 0.25f; private const float RightFocusedIdleCompositorIntervalSeconds = 0.5f; private const float VisibleAmbientCompositorIntervalSeconds = 0.5f; private const float HiddenAmbientCompositorIntervalSeconds = 1f; private const float ReassertIntervalSeconds = 1f; private const float FullSuppressionIntervalSeconds = 0.2f; private const float FastMaterialVerifyIntervalSeconds = 0.2f; private static float _nextBindMaintenanceAt; private static float _nextCompositorRenderAt; private static float _nextRightCompositorRenderAt; private static float _nextReassertAt; private static float _nextFullSuppressionAt; private static float _nextFastMaterialVerifyAt; private static bool _forceFastMaterialVerify; private static bool _compositorDirty = true; private static bool _rightCompositorDirty = true; private static float _lastCompositorRenderAt; private static bool _wasMonitorVisible; private static bool _bindMaintenancePending; private static long _suppressedUnobservedBindMaintenancePasses; private static float _nextBindMaintenanceSuppressionReportAt; private static bool _bindMaintenanceGateLogged; private static bool _bindMaintenanceResumeLogged; private static long _suppressedUnobservedRepaints; private static float _nextSuppressionReportAt; private const float SuppressionReportIntervalSeconds = 30f; private static bool _powerBlanked; private static bool _targetOutlinesActive; private static bool _diagnosticsDumped; private static bool _loggedWaitingForTarget; private static bool _loggedCreated; private static bool _loggedLeftMissing; private static bool _loggedRightMissing; private static bool _loggedPinningMapVideo; private static bool _loggedMapCameraFrozenOff; private const float LeftSwitchFlashDurationSeconds = 0.075f; private const float LeftSwitchTotalDurationSeconds = 0.18f; private const float FastReassertIntervalSeconds = 0.1f; private static float _nextFastReassertAt; private static bool _stoodDownForQuotaPresentation; private const string CeremonyCloneMarker = "_LGUCeremonyCamera"; private static int _giWallProbeFrame = -1; private static bool _giWallProbeResult; private static bool _generalImprovementsWallSeen; private const float VanillaCameraGuardIntervalSeconds = 0.5f; private const float VanillaCameraGuardReportIntervalSeconds = 60f; private const float HeadMountedLookupIntervalSeconds = 5f; private static float _nextVanillaCameraGuardAt; private static float _nextVanillaCameraGuardReportAt; private static float _nextHeadMountedLookupAt; private static Camera _vanillaHeadMountedCamera; private static long _headMountedGuardDisables; private static long _mapCameraGuardDisables; private static bool _headMountedGuardLogged; private static bool _mapScreenUnfreezeLogged; private static Camera[] _cameraScanBuffer = (Camera[])(object)new Camera[16]; internal static bool IsCctvModeActive => _cctvModeActive; internal static bool IsMonitorLocallyVisible => _wasMonitorVisible; private static void CreateLeftCameraLabel(RectTransform canvas) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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) //IL_004c: Expected O, but got Unknown //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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Expected O, but got Unknown //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Expected O, but got Unknown //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("CCTVCameraLabel", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val, 31); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(1f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(1f, 1f); component.anchoredPosition = new Vector2(-32f, -26f); component.sizeDelta = new Vector2(180f, 42f); _leftCameraLabel = val.GetComponent(); ((TMP_Text)_leftCameraLabel).text = "CAM_--"; ((Graphic)_leftCameraLabel).raycastTarget = false; ((TMP_Text)_leftCameraLabel).enableWordWrapping = false; ((TMP_Text)_leftCameraLabel).richText = false; ((TMP_Text)_leftCameraLabel).alignment = (TextAlignmentOptions)260; ((TMP_Text)_leftCameraLabel).fontSize = 34f; ((Graphic)_leftCameraLabel).color = new Color(0.12f, 1f, 0.28f, 0.96f); TryAssignHudFont(_leftCameraLabel); GameObject val2 = new GameObject("CCTVPageLabel", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val2.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val2, 31); RectTransform component2 = val2.GetComponent(); component2.anchorMin = new Vector2(1f, 1f); component2.anchorMax = new Vector2(1f, 1f); component2.pivot = new Vector2(1f, 1f); component2.anchoredPosition = new Vector2(-34f, -64f); component2.sizeDelta = new Vector2(220f, 30f); _leftPageLabel = val2.GetComponent(); ((TMP_Text)_leftPageLabel).text = "01/01"; ((Graphic)_leftPageLabel).raycastTarget = false; ((TMP_Text)_leftPageLabel).enableWordWrapping = false; ((TMP_Text)_leftPageLabel).richText = false; ((TMP_Text)_leftPageLabel).alignment = (TextAlignmentOptions)260; ((TMP_Text)_leftPageLabel).fontSize = 20f; ((Graphic)_leftPageLabel).color = new Color(0.12f, 1f, 0.28f, 0.82f); TryAssignHudFont(_leftPageLabel); GameObject val3 = new GameObject("CCTVClockLabel", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val3.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val3, 31); RectTransform component3 = val3.GetComponent(); component3.anchorMin = new Vector2(1f, 1f); component3.anchorMax = new Vector2(1f, 1f); component3.pivot = new Vector2(1f, 1f); component3.anchoredPosition = new Vector2(-34f, -90f); component3.sizeDelta = new Vector2(220f, 32f); _leftClockLabel = val3.GetComponent(); ((TMP_Text)_leftClockLabel).text = "--:--"; _lastLeftClockText = "--:--"; ((Graphic)_leftClockLabel).raycastTarget = false; ((TMP_Text)_leftClockLabel).enableWordWrapping = false; ((TMP_Text)_leftClockLabel).richText = false; ((TMP_Text)_leftClockLabel).alignment = (TextAlignmentOptions)260; ((TMP_Text)_leftClockLabel).fontSize = 22f; ((Graphic)_leftClockLabel).color = new Color(0.12f, 1f, 0.28f, 0.88f); TryAssignHudFont(_leftClockLabel); } private static void CreateLeftRecIndicator(RectTransform canvas) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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) //IL_004c: Expected O, but got Unknown //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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("CCTVRecDot", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val, 31); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = new Vector2(30f, -24f); component.sizeDelta = new Vector2(14f, 14f); _leftRecDot = val.GetComponent(); ((Graphic)_leftRecDot).color = new Color(1f, 0.16f, 0.14f, 1f); ((Graphic)_leftRecDot).raycastTarget = false; GameObject val2 = new GameObject("CCTVRecLabel", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val2.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val2, 31); RectTransform component2 = val2.GetComponent(); component2.anchorMin = new Vector2(0f, 1f); component2.anchorMax = new Vector2(0f, 1f); component2.pivot = new Vector2(0f, 1f); component2.anchoredPosition = new Vector2(52f, -18f); component2.sizeDelta = new Vector2(110f, 26f); _leftRecLabel = val2.GetComponent(); ((TMP_Text)_leftRecLabel).text = "REC"; ((Graphic)_leftRecLabel).raycastTarget = false; ((TMP_Text)_leftRecLabel).enableWordWrapping = false; ((TMP_Text)_leftRecLabel).richText = false; ((TMP_Text)_leftRecLabel).alignment = (TextAlignmentOptions)4097; ((TMP_Text)_leftRecLabel).fontSize = 22f; ((Graphic)_leftRecLabel).color = new Color(1f, 0.3f, 0.26f, 0.95f); TryAssignHudFont(_leftRecLabel); _lastLeftRecOn = true; } private static void CreateLeftCornerBrackets(RectTransform canvas) { //IL_002b: 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_0049: 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_006e: 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_0093: 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_00b1: 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_00d6: 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) Color color = default(Color); ((Color)(ref color))..ctor(0.12f, 1f, 0.28f, 0.55f); CreateCornerBracket(canvas, "TL", new Vector2(0f, 1f), new Vector2(12f, -12f), 34f, 3f, color); CreateCornerBracket(canvas, "TR", new Vector2(1f, 1f), new Vector2(-12f, -12f), 34f, 3f, color); CreateCornerBracket(canvas, "BL", new Vector2(0f, 0f), new Vector2(12f, 12f), 34f, 3f, color); CreateCornerBracket(canvas, "BR", new Vector2(1f, 0f), new Vector2(-12f, 12f), 34f, 3f, color); } private static void CreateCornerBracket(RectTransform canvas, string corner, Vector2 anchor, Vector2 position, float arm, float thickness, Color color) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //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_0034: 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_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) CreateBracketArm(canvas, "CCTVBracket" + corner + "H", anchor, position, new Vector2(arm, thickness), color); CreateBracketArm(canvas, "CCTVBracket" + corner + "V", anchor, position, new Vector2(thickness, arm), color); } private static void CreateBracketArm(RectTransform canvas, string name, Vector2 anchor, Vector2 position, Vector2 size, Color color) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //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_0056: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val, 31); RectTransform component = val.GetComponent(); component.anchorMin = anchor; component.anchorMax = anchor; component.pivot = anchor; component.anchoredPosition = position; component.sizeDelta = size; Image component2 = val.GetComponent(); ((Graphic)component2).color = color; ((Graphic)component2).raycastTarget = false; } private static void CreateLeftStatusLine(RectTransform canvas) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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) //IL_004c: Expected O, but got Unknown //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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Expected O, but got Unknown //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("CCTVStatusLabel", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val, 31); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(0f, 0f); component.pivot = new Vector2(0f, 0f); component.anchoredPosition = new Vector2(30f, 18f); component.sizeDelta = new Vector2(300f, 26f); _leftStatusLabel = val.GetComponent(); ((TMP_Text)_leftStatusLabel).text = BuildStatusLineText(); _lastLeftStatusText = ((TMP_Text)_leftStatusLabel).text; ((Graphic)_leftStatusLabel).raycastTarget = false; ((TMP_Text)_leftStatusLabel).enableWordWrapping = false; ((TMP_Text)_leftStatusLabel).richText = false; ((TMP_Text)_leftStatusLabel).alignment = (TextAlignmentOptions)4097; ((TMP_Text)_leftStatusLabel).fontSize = 18f; ((Graphic)_leftStatusLabel).color = new Color(0.12f, 1f, 0.28f, 0.72f); TryAssignHudFont(_leftStatusLabel); _leftSignalBars = (Image[])(object)new Image[5]; for (int i = 0; i < 5; i++) { GameObject val2 = new GameObject($"CCTVSignalBar{i}", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val2.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val2, 31); RectTransform component2 = val2.GetComponent(); component2.anchorMin = new Vector2(0f, 0f); component2.anchorMax = new Vector2(0f, 0f); component2.pivot = new Vector2(0f, 0f); component2.anchoredPosition = new Vector2(250f + (float)i * 9f, 18f); component2.sizeDelta = new Vector2(5f, 6f + (float)i * 3f); _leftSignalBars[i] = val2.GetComponent(); ((Graphic)_leftSignalBars[i]).color = new Color(0.12f, 1f, 0.28f, 0.18f); ((Graphic)_leftSignalBars[i]).raycastTarget = false; } } private static string BuildStatusLineText() { return $"{768}x{432} | 24FPS"; } private static void CreateLeftSignalLostPlate(RectTransform canvas) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown //IL_0197: 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_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: 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) GameObject val = new GameObject("CCTVSignalLostPlate", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val, 31); RectTransform component = val.GetComponent(); ApplySingleCameraRect(component, 14f); Image component2 = val.GetComponent(); ((Graphic)component2).color = new Color(0f, 0f, 0f, 0.88f); ((Graphic)component2).raycastTarget = false; GameObject val2 = new GameObject("CCTVSignalLostStatic", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage) }); val2.transform.SetParent((Transform)(object)component, false); SetLayerRecursive(val2, 31); Stretch(val2.GetComponent()); _leftSignalLostStatic = val2.GetComponent(); _leftSignalLostStatic.texture = (Texture)(object)EnsureSignalLostNoiseTexture(); ((Graphic)_leftSignalLostStatic).color = new Color(1f, 1f, 1f, 0.42f); ((Graphic)_leftSignalLostStatic).raycastTarget = false; _leftSignalLostStatic.uvRect = new Rect(0f, 0f, 12f, 6.75f); GameObject val3 = new GameObject("CCTVSignalLostLabel", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val3.transform.SetParent((Transform)(object)component, false); SetLayerRecursive(val3, 31); RectTransform component3 = val3.GetComponent(); component3.anchorMin = new Vector2(0.5f, 0.5f); component3.anchorMax = new Vector2(0.5f, 0.5f); component3.pivot = new Vector2(0.5f, 0.5f); component3.anchoredPosition = Vector2.zero; component3.sizeDelta = new Vector2(620f, 60f); _leftSignalLostLabel = val3.GetComponent(); ((TMP_Text)_leftSignalLostLabel).text = "SIGNAL LOST"; ((Graphic)_leftSignalLostLabel).raycastTarget = false; ((TMP_Text)_leftSignalLostLabel).enableWordWrapping = false; ((TMP_Text)_leftSignalLostLabel).richText = false; ((TMP_Text)_leftSignalLostLabel).alignment = (TextAlignmentOptions)514; ((TMP_Text)_leftSignalLostLabel).fontSize = 38f; ((Graphic)_leftSignalLostLabel).color = new Color(1f, 0.32f, 0.26f, 0.96f); TryAssignHudFont(_leftSignalLostLabel); _leftSignalLostRoot = val; _leftSignalLostRoot.SetActive(false); } private static Texture2D EnsureSignalLostNoiseTexture() { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //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)_signalLostNoiseTexture != (Object)null) { return _signalLostNoiseTexture; } Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false) { name = "LethalCCTV_SignalLostStatic", filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)0, hideFlags = (HideFlags)61 }; Color32[] array = (Color32[])(object)new Color32[4096]; Random random = new Random(20260803); for (int i = 0; i < array.Length; i++) { byte b = (byte)random.Next(18, 236); array[i] = new Color32(b, b, b, byte.MaxValue); } val.SetPixels32(array); val.Apply(false, false); _signalLostNoiseTexture = val; return val; } private static void CreateLeftSwitchFlash(RectTransform canvas) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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) //IL_004c: Expected O, but got Unknown //IL_004c: 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_006c: 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) GameObject val = new GameObject("CCTVSwitchFlash", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val, 31); ApplySingleCameraRect(val.GetComponent(), 14f); _leftSwitchFlashImage = val.GetComponent(); ((Graphic)_leftSwitchFlashImage).color = Color.clear; ((Graphic)_leftSwitchFlashImage).raycastTarget = false; val.SetActive(false); val.transform.SetAsLastSibling(); if ((Object)(object)_leftCameraLabel != (Object)null) { ((TMP_Text)_leftCameraLabel).transform.SetAsLastSibling(); } } private static void CreateLeftReticle(RectTransform canvas) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00e2: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_0151: 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_0165: 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_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: 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_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: 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_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) _leftReticleRoot = new GameObject("CCTVCameraReticle", new Type[1] { typeof(RectTransform) }); _leftReticleRoot.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(_leftReticleRoot, 31); RectTransform component = _leftReticleRoot.GetComponent(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = Vector2.zero; component.sizeDelta = new Vector2(96f, 96f); Color val = default(Color); ((Color)(ref val))..ctor(0.1f, 1f, 0.28f, 0.76f); CreateReticleSegment(component, "Top", new Vector2(0f, 24f), new Vector2(3f, 18f), val); CreateReticleSegment(component, "Bottom", new Vector2(0f, -24f), new Vector2(3f, 18f), val); CreateReticleSegment(component, "Left", new Vector2(-24f, 0f), new Vector2(18f, 3f), val); CreateReticleSegment(component, "Right", new Vector2(24f, 0f), new Vector2(18f, 3f), val); CreateReticleSegment(component, "CenterH", Vector2.zero, new Vector2(12f, 2f), new Color(val.r, val.g, val.b, 0.48f)); CreateReticleSegment(component, "CenterV", Vector2.zero, new Vector2(2f, 12f), new Color(val.r, val.g, val.b, 0.48f)); } private static void CreateLeftTerminalOverlayRoot(RectTransform canvas) { //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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_0041: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00a5: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("LethalCCTV_LowerLeftTerminalOverlay", new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val, 31); _leftTerminalOverlayRoot = val.GetComponent(); _leftTerminalOverlayRoot.anchorMin = Vector2.zero; _leftTerminalOverlayRoot.anchorMax = Vector2.one; _leftTerminalOverlayRoot.pivot = new Vector2(0.5f, 0.5f); _leftTerminalOverlayRoot.offsetMin = Vector2.zero; _leftTerminalOverlayRoot.offsetMax = Vector2.zero; ((Transform)_leftTerminalOverlayRoot).localRotation = Quaternion.identity; ((Transform)_leftTerminalOverlayRoot).localScale = Vector3.one; ((Transform)_leftTerminalOverlayRoot).SetAsLastSibling(); } private static void CreateReticleSegment(RectTransform parent, string name, Vector2 position, Vector2 size, Color color) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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) //IL_009e: 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) GameObject val = new GameObject("Reticle_" + name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)parent, false); SetLayerRecursive(val, 31); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = position; component.sizeDelta = size; Image component2 = val.GetComponent(); ((Graphic)component2).color = color; ((Graphic)component2).raycastTarget = false; } private static bool RefreshLeftCameraLabel(float now, bool monitorVisible) { CCTVCamera boundCamera = QuadCameraAssignment.GetBoundCamera(0); return RefreshLeftCameraAndPageLabels(boundCamera) | RefreshLeftScreenFurniture(now, monitorVisible, boundCamera); } private static bool RefreshLeftCameraAndPageLabels(CCTVCamera active) { if ((Object)(object)_leftCameraLabel == (Object)null && (Object)(object)_leftPageLabel == (Object)null) { return false; } string text = (((Object)(object)active != (Object)null && !string.IsNullOrWhiteSpace(active.ResolvedLabel)) ? active.ResolvedLabel : "CAM_--"); string text2 = ((QuadCameraAssignment.TotalPages > 0) ? $"{QuadCameraAssignment.CurrentPage + 1:00}/{QuadCameraAssignment.TotalPages:00}" : "00/00"); bool num = !string.Equals(text, _lastLeftCameraLabel, StringComparison.Ordinal); bool flag = !string.Equals(text2, _lastLeftPageLabel, StringComparison.Ordinal); if (!num && !flag) { return false; } bool num2 = !string.IsNullOrEmpty(_lastLeftCameraLabel) || !string.IsNullOrEmpty(_lastLeftPageLabel); _lastLeftCameraLabel = text; _lastLeftPageLabel = text2; if ((Object)(object)_leftCameraLabel != (Object)null) { ((TMP_Text)_leftCameraLabel).text = text; } if ((Object)(object)_leftPageLabel != (Object)null) { ((TMP_Text)_leftPageLabel).text = text2; } _compositorDirty = true; if (num2 && _cctvModeActive) { TriggerLeftSwitchFlash(); } return true; } private static bool RefreshLeftScreenFurniture(float now, bool monitorVisible, CCTVCamera active) { bool flag = false; bool flag2 = (Object)(object)active != (Object)null && active.IsSecurityBroken; if (flag2 != _lastLeftSignalLost) { _lastLeftSignalLost = flag2; if ((Object)(object)_leftSignalLostRoot != (Object)null) { _leftSignalLostRoot.SetActive(flag2); } flag = true; } if (flag2 && (Object)(object)_leftSignalLostLabel != (Object)null) { string text = ((!string.IsNullOrWhiteSpace(active.ResolvedLabel)) ? active.ResolvedLabel : "CAM_--"); string text2 = "SIGNAL LOST - " + text; if (!string.Equals(text2, _lastLeftSignalLostText, StringComparison.Ordinal)) { _lastLeftSignalLostText = text2; ((TMP_Text)_leftSignalLostLabel).text = text2; flag = true; } } int num = ((!((Object)(object)active == (Object)null)) ? (flag2 ? 1 : 5) : 0); if (num != _lastLeftSignalBars) { _lastLeftSignalBars = num; ApplyLeftSignalBars(num); flag = true; } string text3 = BuildStatusLineText(); if ((Object)(object)_leftStatusLabel != (Object)null && !string.Equals(text3, _lastLeftStatusText, StringComparison.Ordinal)) { _lastLeftStatusText = text3; ((TMP_Text)_leftStatusLabel).text = text3; flag = true; } if (!monitorVisible || !_cctvModeActive) { if (flag) { _compositorDirty = true; } return flag; } string shipTime24h = CctvScreenClock.GetShipTime24h(); if ((Object)(object)_leftClockLabel != (Object)null && !string.Equals(shipTime24h, _lastLeftClockText, StringComparison.Ordinal)) { _lastLeftClockText = shipTime24h; ((TMP_Text)_leftClockLabel).text = shipTime24h; CctvScreenClock.LogComparisonOnce(shipTime24h); flag = true; } bool flag3 = Mathf.Repeat(now, 1f) < 0.55f; if (flag3 != _lastLeftRecOn) { _lastLeftRecOn = flag3; ApplyLeftRecBlink(flag3); flag = true; } if (flag2) { ScrollLeftSignalLostStatic(); } if (flag) { _compositorDirty = true; } return flag; } private static void ApplyLeftRecBlink(bool on) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_leftRecDot != (Object)null) { ((Graphic)_leftRecDot).color = new Color(1f, 0.16f, 0.14f, on ? 1f : 0.12f); } if ((Object)(object)_leftRecLabel != (Object)null) { ((Graphic)_leftRecLabel).color = new Color(1f, 0.3f, 0.26f, on ? 0.95f : 0.22f); } } private static void ApplyLeftSignalBars(int litCount) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (_leftSignalBars == null) { return; } for (int i = 0; i < _leftSignalBars.Length; i++) { if (!((Object)(object)_leftSignalBars[i] == (Object)null)) { bool flag = i < litCount; ((Graphic)_leftSignalBars[i]).color = new Color(0.12f, 1f, 0.28f, flag ? 0.85f : 0.18f); } } } private static void ScrollLeftSignalLostStatic() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_leftSignalLostStatic == (Object)null)) { _signalLostStaticStep++; float num = (float)_signalLostStaticStep * 0.618034f; float num2 = (float)_signalLostStaticStep * 0.41421357f; Rect uvRect = _leftSignalLostStatic.uvRect; _leftSignalLostStatic.uvRect = new Rect(num - Mathf.Floor(num), num2 - Mathf.Floor(num2), ((Rect)(ref uvRect)).width, ((Rect)(ref uvRect)).height); } } private static void TriggerLeftSwitchFlash() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) _leftSwitchFlashStartedAt = Time.unscaledTime; _leftSwitchFlashUntil = _leftSwitchFlashStartedAt + 0.18f; if ((Object)(object)_leftSwitchFlashImage != (Object)null) { ((Component)_leftSwitchFlashImage).gameObject.SetActive(true); ((Graphic)_leftSwitchFlashImage).color = new Color(0.82f, 0.86f, 0.82f, 0.58f); ((Component)_leftSwitchFlashImage).transform.SetAsLastSibling(); if ((Object)(object)_leftPageLabel != (Object)null) { ((TMP_Text)_leftPageLabel).transform.SetAsLastSibling(); } if ((Object)(object)_leftCameraLabel != (Object)null) { ((TMP_Text)_leftCameraLabel).transform.SetAsLastSibling(); } } } private static void UpdateLeftSwitchFlash(float now) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_leftSwitchFlashImage == (Object)null) { return; } if (now >= _leftSwitchFlashUntil) { if (((Component)_leftSwitchFlashImage).gameObject.activeSelf) { ((Component)_leftSwitchFlashImage).gameObject.SetActive(false); } ResetLeftSlotUv(); return; } float num = Mathf.Max(0f, now - _leftSwitchFlashStartedAt); float num2 = Mathf.Clamp01(num / 0.075f); float num3 = Mathf.Lerp(0.58f, 0f, num2); ((Graphic)_leftSwitchFlashImage).color = new Color(0.82f, 0.86f, 0.82f, num3); ApplyLeftSlotSwitchRoll(num); if (!((Component)_leftSwitchFlashImage).gameObject.activeSelf) { ((Component)_leftSwitchFlashImage).gameObject.SetActive(true); } } private static void ApplyLeftSlotSwitchRoll(float elapsed) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (_slotImages != null && _slotImages.Length != 0 && !((Object)(object)_slotImages[0] == (Object)null)) { float num = Mathf.Sin(Mathf.Clamp01(elapsed / 0.18f) * MathF.PI) * 0.018f; _slotImages[0].uvRect = new Rect(num, (0f - num) * 0.35f, 1f, 1f); } } private static void ResetLeftSlotUv() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (_slotImages != null && _slotImages.Length != 0 && !((Object)(object)_slotImages[0] == (Object)null)) { _slotImages[0].uvRect = new Rect(0f, 0f, 1f, 1f); } } private static bool IsLeftSwitchAnimating(float now) { if ((Object)(object)_leftSwitchFlashImage != (Object)null) { return now < _leftSwitchFlashUntil; } return false; } private static bool IsCeremonyHeldMaterial(Material material) { if ((Object)(object)material == (Object)null) { return false; } string name; try { name = ((Object)material).name; } catch { return false; } if (name == null || name.IndexOf("_LGUCeremonyCamera", StringComparison.Ordinal) < 0) { return false; } return CCTVShipSystemsBridge.IsQuotaPresentationActive(); } private static void TrackQuotaPresentationScope() { if (CCTVShipSystemsBridge.IsQuotaPresentationActive()) { _stoodDownForQuotaPresentation = true; } else if (_stoodDownForQuotaPresentation) { _stoodDownForQuotaPresentation = false; _forceFastMaterialVerify = true; _nextFullSuppressionAt = 0f; _nextReassertAt = 0f; } } private static void ReassertCctvScreenOwnershipFast(float now, bool force = false) { TrackQuotaPresentationScope(); if (force || _forceFastMaterialVerify || !(now < _nextFastReassertAt)) { _nextFastReassertAt = now + 0.1f; ReassertSuppressedLowerMonitorFeedsFrame(); if (now >= _nextFullSuppressionAt) { _nextFullSuppressionAt = now + 0.2f; ReassertSuppressedLowerMonitorFeedsFast(); } bool flag = _forceFastMaterialVerify || now >= _nextFastMaterialVerifyAt; if (flag) { _forceFastMaterialVerify = false; _nextFastMaterialVerifyAt = now + 0.2f; } _lowerLeftBinding.ReassertFast(flag); _lowerRightBinding.ReassertFast(flag); _lowerRightAuxBinding.ReassertFast(flag); if ((Object)(object)_mapScreenRawImage != (Object)null && (Object)(object)_leftRenderTexture != (Object)null && (Object)(object)_mapScreenRawImage.texture != (Object)(object)_leftRenderTexture) { _mapScreenRawImage.texture = (Texture)(object)_leftRenderTexture; } } } internal static void ReassertCctvScreenOwnershipAfterVanilla() { if (_cctvModeActive && (!((Object)(object)_leftRenderTexture == (Object)null) || !((Object)(object)_rightRenderTexture == (Object)null))) { ReassertCctvScreenOwnershipFast(Time.unscaledTime, force: true); } } internal static bool IsGeneralImprovementsMonitorWallActive() { if (!GeneralImprovementsMonitorCompat.IsLoaded) { return false; } int frameCount = Time.frameCount; if (_giWallProbeFrame == frameCount) { return _giWallProbeResult; } _giWallProbeFrame = frameCount; _giWallProbeResult = GeneralImprovementsMonitorCompat.AreBetterMonitorsActive(); return _giWallProbeResult; } internal static bool ShouldSuppressVanillaMonitorRendererUpdate(ManualCameraRenderer renderer) { if (!_cctvModeActive || (Object)(object)renderer == (Object)null) { return false; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)renderer == (Object)(object)instance.mapScreen && (!IsGeneralImprovementsMonitorWallActive() || OwnsGeneralImprovementsMapScreen())) { return true; } if (!_lowerLeftBinding.OwnsDriver(renderer) && !_lowerRightBinding.OwnsDriver(renderer)) { return _lowerRightAuxBinding.OwnsDriver(renderer); } return true; } private static void ReassertCctvScreenOwnership() { TrackQuotaPresentationScope(); if (_suppressionCaptured) { SuppressVanillaLowerMonitorFeeds(); } _lowerLeftBinding.Reassert(); _lowerRightBinding.Reassert(); _lowerRightAuxBinding.Reassert(); if ((Object)(object)_mapScreenRawImage != (Object)null && (Object)(object)_leftRenderTexture != (Object)null) { _mapScreenRawImage.texture = (Texture)(object)_leftRenderTexture; } } internal static string GetRenderDiagnostics() { string text = (((Object)(object)_leftRenderTexture != (Object)null) ? $"{((Texture)_leftRenderTexture).width}x{((Texture)_leftRenderTexture).height}" : ""); string text2 = (((Object)(object)_rightRenderTexture != (Object)null) ? $"{((Texture)_rightRenderTexture).width}x{((Texture)_rightRenderTexture).height}" : ""); return $"monitor compositor: active={_cctvModeActive} focusedPassiveInterval={0.1f:F3}s " + $"focusedBurstInterval={1f / 18f:F3}s " + $"visibleInterval={0.5f:F3}s hiddenInterval={1f:F3}s " + $"rightFocusInterval={0.25f:F3}s rightIdleFocusInterval={0.5f:F3}s " + $"scale={1}x " + "leftRT=" + text + " rightRT=" + text2 + " " + $"leftCamEnabled={(Object)(object)_leftCamera != (Object)null && ((Behaviour)_leftCamera).enabled} rightCamEnabled={(Object)(object)_rightCamera != (Object)null && ((Behaviour)_rightCamera).enabled} " + $"fastReassert={0.1f:F2}s-polled+event-forced materialVerify={0.2f:F2}s " + $"reassertInterval={1f:F2}s"; } internal static void SetCctvModeActive(bool active, bool announce = true) { if (_cctvModeActive == active) { return; } _cctvModeActive = active; if (active) { _compositorDirty = true; _nextCompositorRenderAt = 0f; _nextReassertAt = 0f; _nextFullSuppressionAt = 0f; _nextFastMaterialVerifyAt = 0f; _forceFastMaterialVerify = true; _lastCompositorRenderAt = 0f; CCTVShipSystemsBridge.BeginExternalMonitorTakeover(); } else { TickCctvTargetOutlines(active: false); SetActive(active: false); CCTVShipSystemsBridge.EndExternalMonitorTakeover(); } if (announce) { HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip("CCTV MONITORS", active ? "CCTV view enabled." : "Vanilla monitor view restored.", false, false, "LC_Tip1"); } } } internal static void PrimeMonitorOwnershipNow(bool renderNow = true) { if (!CCTVTerminalUnlockable.IsPurchased() || !_cctvModeActive || QuadMonitor.QuadRTs == null) { return; } EnsureRenderRig(); if (!((Object)(object)_leftRenderTexture == (Object)null) && !((Object)(object)_rightRenderTexture == (Object)null)) { float unscaledTime = Time.unscaledTime; VanillaRadarFeed.SetActive(active: true); DumpMonitorDiagnosticsOnce(); EnsureWorldUiOverlays(); SuppressVanillaLowerMonitorFeeds(); BindLeftMonitorTexture(); BindRightMonitorTexture(); SyncSlotTextures(); RefreshLeftCameraLabel(unscaledTime, monitorVisible: true); SyncRightMonitor(allowRadarWork: true); if ((Object)(object)_lowerLeftRoot != (Object)null && !_lowerLeftRoot.activeSelf) { _lowerLeftRoot.SetActive(true); _lowerLeftRoot.transform.SetAsLastSibling(); } _compositorDirty = true; _forceFastMaterialVerify = true; ReassertCctvScreenOwnershipFast(unscaledTime, force: true); ReassertCctvScreenOwnership(); if (renderNow) { RenderMonitorTextures(unscaledTime, monitorVisible: true); PinLowerLeftVideoTexture(); _lastCompositorRenderAt = unscaledTime; _nextCompositorRenderAt = unscaledTime + ResolveCompositorInterval(monitorVisible: true); _nextRightCompositorRenderAt = unscaledTime + ResolveRightCompositorInterval(monitorVisible: true); _compositorDirty = false; _rightCompositorDirty = false; } } } internal static void NotifySlotTextureChanged(int slot, Texture texture) { if (_slotImages != null && slot >= 0 && slot < _slotImages.Length && !((Object)(object)_slotImages[slot] == (Object)null)) { _slotImages[slot].texture = (Texture)(((Object)(object)texture != (Object)null) ? ((object)texture) : ((object)Texture2D.blackTexture)); _compositorDirty = true; _forceFastMaterialVerify = true; } } internal static void Shutdown() { TickCctvTargetOutlines(active: false); VanillaRadarFeed.SetActive(active: false); RestoreVanillaLowerMonitorFeeds(); _lowerRightAuxBinding.Restore(); _lowerRightBinding.Restore(); _lowerLeftBinding.Restore(); CCTVShipSystemsBridge.EndExternalMonitorTakeover(); if ((Object)(object)_lowerLeftRoot != (Object)null) { Object.Destroy((Object)(object)_lowerLeftRoot); } if ((Object)(object)_rigRoot != (Object)null) { Object.Destroy((Object)(object)_rigRoot); } ReleaseRenderTexture(ref _leftRenderTexture); ReleaseRenderTexture(ref _rightRenderTexture); _rigRoot = null; _leftCamera = null; _rightCamera = null; _slotImages = null; _rightRadarImage = null; _rightRadarLabel = null; _rightRadarLegend = null; _lowerLeftRoot = null; _lowerLeftImage = null; _leftCameraLabel = null; _leftPageLabel = null; _leftSwitchFlashImage = null; _leftReticleRoot = null; _leftTerminalOverlayRoot = null; ClearLeftScreenFurnitureRefs(); if ((Object)(object)_signalLostNoiseTexture != (Object)null) { Object.Destroy((Object)(object)_signalLostNoiseTexture); _signalLostNoiseTexture = null; } CctvScreenClock.ResetDiagnostics(); _leftSwitchFlashStartedAt = 0f; _leftSwitchFlashUntil = 0f; _lastLeftCameraLabel = null; _lastLeftPageLabel = null; _cctvModeActive = false; _loggedWaitingForTarget = false; _loggedCreated = false; _loggedLeftMissing = false; _loggedRightMissing = false; _loggedPinningMapVideo = false; _nextProbeAt = 0f; _nextBindMaintenanceAt = 0f; _nextCompositorRenderAt = 0f; _nextRightCompositorRenderAt = 0f; _nextReassertAt = 0f; _nextFullSuppressionAt = 0f; _nextFastMaterialVerifyAt = 0f; _nextFastReassertAt = 0f; _stoodDownForQuotaPresentation = false; _forceFastMaterialVerify = false; _compositorDirty = true; _rightCompositorDirty = true; _lastCompositorRenderAt = 0f; _wasMonitorVisible = false; _bindMaintenancePending = false; _suppressedUnobservedBindMaintenancePasses = 0L; _nextBindMaintenanceSuppressionReportAt = 0f; _bindMaintenanceGateLogged = false; _bindMaintenanceResumeLogged = false; _powerBlanked = false; _diagnosticsDumped = false; _generalImprovementsWallSeen = false; _giWallProbeFrame = -1; _giWallProbeResult = false; GeneralImprovementsMonitorCompat.ResetDiagnostics(); } private static void EnsureRenderRig() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_rigRoot != (Object)null) || !((Object)(object)_leftRenderTexture != (Object)null) || !((Object)(object)_rightRenderTexture != (Object)null)) { ShutdownRenderRigOnly(); _rigRoot = new GameObject("LethalCCTV_VanillaMonitorRenderRig"); Object.DontDestroyOnLoad((Object)(object)_rigRoot); _rigRoot.transform.position = new Vector3(OffscreenRigParking.SlotX((OffscreenRigSlot)5), -10000f, 0f); CreateLowerLeftRigUi(CreateMonitorCanvas("LowerLeft", 0f, out _leftCamera, out _leftRenderTexture)); CreateRightRigUi(CreateMonitorCanvas("Right", 1024f, out _rightCamera, out _rightRenderTexture)); } } private static void ShutdownRenderRigOnly() { if ((Object)(object)_rigRoot != (Object)null) { Object.Destroy((Object)(object)_rigRoot); } ReleaseRenderTexture(ref _leftRenderTexture); ReleaseRenderTexture(ref _rightRenderTexture); _rigRoot = null; _leftCamera = null; _rightCamera = null; _slotImages = null; _rightRadarImage = null; _rightRadarLabel = null; _rightRadarLegend = null; _leftReticleRoot = null; _leftTerminalOverlayRoot = null; ClearLeftScreenFurnitureRefs(); _lastLeftCameraLabel = null; _lastLeftPageLabel = null; _powerBlanked = false; } private static void ClearLeftScreenFurnitureRefs() { _leftClockLabel = null; _leftRecDot = null; _leftRecLabel = null; _leftStatusLabel = null; _leftSignalBars = null; _leftSignalLostRoot = null; _leftSignalLostStatic = null; _leftSignalLostLabel = null; _lastLeftClockText = null; _lastLeftStatusText = null; _lastLeftSignalLostText = null; _lastLeftSignalBars = -1; _lastLeftRecOn = false; _lastLeftSignalLost = false; _signalLostStaticStep = 0; } private static RectTransform CreateMonitorCanvas(string name, float xOffset, out Camera camera, out RenderTexture renderTexture) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) //IL_004c: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_018d: 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_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) renderTexture = new RenderTexture(768, 432, 0, (RenderTextureFormat)0) { name = "LethalCCTV_" + name + "_VanillaMonitorRT", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1, antiAliasing = 1, useMipMap = false, autoGenerateMips = false }; renderTexture.Create(); GameObject val = new GameObject(name + "MonitorCamera"); val.transform.SetParent(_rigRoot.transform, false); val.transform.localPosition = new Vector3(xOffset, 0f, -10f); camera = val.AddComponent(); camera.clearFlags = (CameraClearFlags)2; camera.backgroundColor = Color.black; camera.orthographic = true; camera.orthographicSize = 216f; camera.aspect = 1.7777778f; camera.nearClipPlane = 0.1f; camera.farClipPlane = 30f; camera.cullingMask = int.MinValue; camera.targetTexture = renderTexture; ((Behaviour)camera).enabled = false; HDAdditionalCameraData obj = val.AddComponent(); obj.clearColorMode = (ClearColorMode)1; obj.backgroundColorHDR = camera.backgroundColor; GameObject val2 = new GameObject(name + "MonitorCanvas", new Type[5] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster), typeof(Image) }); val2.transform.SetParent(_rigRoot.transform, false); val2.transform.localPosition = new Vector3(xOffset, 0f, 0f); SetLayerRecursive(val2, 31); Canvas component = val2.GetComponent(); component.renderMode = (RenderMode)2; component.worldCamera = camera; RectTransform component2 = val2.GetComponent(); component2.sizeDelta = new Vector2(768f, 432f); ((Transform)component2).localScale = Vector3.one; Image component3 = val2.GetComponent(); ((Graphic)component3).color = Color.black; ((Graphic)component3).raycastTarget = false; return component2; } private static void CreateLowerLeftRigUi(RectTransform canvas) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) _slotImages = (RawImage[])(object)new RawImage[4]; _slotImages[0] = CreateSlotImage(canvas, 0); CctvScreenOutlineOverlay.Initialize((Transform)(object)canvas); CreateLeftSignalLostPlate(canvas); CreateLeftCornerBrackets(canvas); CreateLeftCameraLabel(canvas); CreateLeftRecIndicator(canvas); CreateLeftStatusLine(canvas); CreateLeftSwitchFlash(canvas); CreateLeftReticle(canvas); CreateBorder(canvas, new Color(0f, 0.8f, 0.2f, 0.65f), 5f); CreateLeftTerminalOverlayRoot(canvas); } internal static bool TryAttachToLowerLeftOverlay(GameObject root) { if ((Object)(object)root == (Object)null) { return false; } EnsureRenderRig(); if ((Object)(object)_leftTerminalOverlayRoot == (Object)null) { return false; } root.transform.SetParent((Transform)(object)_leftTerminalOverlayRoot, false); root.transform.SetAsLastSibling(); SetLayerRecursive(root, 31); return true; } internal static Vector2 GetLowerLeftOverlayDockPosition() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return Vector2.zero; } internal static Vector2 GetLowerLeftOverlayDockSize() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return new Vector2(960f, 520f); } internal static bool TryGetCctvPaneGeometry(out Vector2 center, out Vector2 size) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0079: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) center = Vector2.zero; size = Vector2.zero; if (_slotImages == null || _slotImages.Length == 0 || (Object)(object)_slotImages[0] == (Object)null) { return false; } Transform parent = ((Component)_slotImages[0]).transform.parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val == (Object)null) { val = ((Graphic)_slotImages[0]).rectTransform; } center = val.anchoredPosition; Rect rect = val.rect; size = ((Rect)(ref rect)).size; if (size.x <= 1f || size.y <= 1f) { size = new Vector2(740f, 404f); } if (size.x > 1f) { return size.y > 1f; } return false; } private static void TickCctvTargetOutlines(bool active) { if (!active) { ClearCctvTargetOutlinesIfActive(); return; } CCTVCamera boundCamera = QuadCameraAssignment.GetBoundCamera(0); if ((Object)(object)boundCamera == (Object)null) { ClearCctvTargetOutlinesIfActive(); return; } _targetOutlinesActive = true; CctvOutlineManager.Tick(boundCamera, isActive: true); CctvScreenOutlineOverlay.Tick(focused: true); } private static bool ShouldRunTargetOutlines() { if (MonitorFocus.IsFocused) { return _cctvModeActive; } return false; } private static void ClearCctvTargetOutlinesIfActive() { if (_targetOutlinesActive) { CctvOutlineManager.Tick(null, isActive: false); CctvScreenOutlineOverlay.Tick(focused: false); _targetOutlinesActive = false; } } private static void CreateRightRigUi(RectTransform canvas) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00cb: 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0153: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Expected O, but got Unknown //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) CreateBorder(canvas, new Color(0f, 0.8f, 0.2f, 0.65f), 5f); GameObject val = new GameObject("RadarView", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage) }); val.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val, 31); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = Vector2.zero; component.sizeDelta = new Vector2(732f, 396f); ((Transform)component).localEulerAngles = new Vector3(0f, 0f, 0f); _rightRadarImage = val.GetComponent(); _rightRadarImage.texture = (Texture)(object)Texture2D.blackTexture; ((Graphic)_rightRadarImage).color = Color.white; ((Graphic)_rightRadarImage).raycastTarget = false; GameObject val2 = new GameObject("RadarFloorLabel", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val2.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val2, 31); RectTransform component2 = val2.GetComponent(); component2.anchorMin = new Vector2(0f, 1f); component2.anchorMax = new Vector2(0f, 1f); component2.pivot = new Vector2(0f, 1f); component2.anchoredPosition = new Vector2(30f, -24f); component2.sizeDelta = new Vector2(420f, 34f); _rightRadarLabel = val2.GetComponent(); ((TMP_Text)_rightRadarLabel).text = "RADAR MAP"; ((Graphic)_rightRadarLabel).raycastTarget = false; ((TMP_Text)_rightRadarLabel).enableWordWrapping = false; ((TMP_Text)_rightRadarLabel).richText = false; ((TMP_Text)_rightRadarLabel).alignment = (TextAlignmentOptions)257; ((TMP_Text)_rightRadarLabel).fontSize = 22f; ((Graphic)_rightRadarLabel).color = new Color(1f, 0.58f, 0.08f, 0.94f); TryAssignHudFont(_rightRadarLabel); GameObject val3 = new GameObject("RadarLegend", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val3.transform.SetParent((Transform)(object)canvas, false); SetLayerRecursive(val3, 31); RectTransform component3 = val3.GetComponent(); component3.anchorMin = new Vector2(0f, 0f); component3.anchorMax = new Vector2(0f, 0f); component3.pivot = new Vector2(0f, 0f); component3.anchoredPosition = new Vector2(30f, 18f); component3.sizeDelta = new Vector2(940f, 42f); _rightRadarLegend = val3.GetComponent(); ((TMP_Text)_rightRadarLegend).text = string.Empty; ((Graphic)_rightRadarLegend).raycastTarget = false; ((TMP_Text)_rightRadarLegend).enableWordWrapping = false; ((TMP_Text)_rightRadarLegend).richText = true; ((TMP_Text)_rightRadarLegend).alignment = (TextAlignmentOptions)1025; ((TMP_Text)_rightRadarLegend).fontSize = 26f; ((Graphic)_rightRadarLegend).color = Color.white; TryAssignHudFont(_rightRadarLegend); } private static RawImage CreateSlotImage(RectTransform parent, int slot) { //IL_003d: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_00d6: 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) GameObject val = new GameObject($"CCTVSlot{slot}Back", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)parent, false); SetLayerRecursive(val, 31); RectTransform component = val.GetComponent(); ApplySingleCameraRect(component, 14f); Image component2 = val.GetComponent(); ((Graphic)component2).color = Color.black; ((Graphic)component2).raycastTarget = false; GameObject val2 = new GameObject($"CCTVSlot{slot}", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage) }); val2.transform.SetParent((Transform)(object)component, false); SetLayerRecursive(val2, 31); Stretch(val2.GetComponent()); RawImage component3 = val2.GetComponent(); component3.texture = (Texture)(((object)QuadMonitor.GetCurrentDisplayTexture(slot)) ?? ((object)Texture2D.blackTexture)); ((Graphic)component3).color = Color.white; ((Graphic)component3).raycastTarget = false; return component3; } private static void ApplySlotRect(RectTransform rt, int slot, float margin) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) bool flag = slot % 2 == 1; bool flag2 = slot < 2; rt.anchorMin = new Vector2(flag ? 0.5f : 0f, flag2 ? 0.5f : 0f); rt.anchorMax = new Vector2(flag ? 1f : 0.5f, flag2 ? 1f : 0.5f); rt.pivot = new Vector2(0.5f, 0.5f); rt.offsetMin = new Vector2(flag ? (margin * 0.5f) : margin, flag2 ? (margin * 0.5f) : margin); rt.offsetMax = new Vector2(flag ? (0f - margin) : ((0f - margin) * 0.5f), flag2 ? (0f - margin) : ((0f - margin) * 0.5f)); ((Transform)rt).localRotation = Quaternion.identity; ((Transform)rt).localScale = Vector3.one; } private static void ApplySingleCameraRect(RectTransform rt, float margin) { //IL_000b: 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_002b: 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_0047: 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_005d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rt == (Object)null)) { rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; rt.pivot = new Vector2(0.5f, 0.5f); rt.offsetMin = new Vector2(margin, margin); rt.offsetMax = new Vector2(0f - margin, 0f - margin); ((Transform)rt).localRotation = Quaternion.identity; ((Transform)rt).localScale = Vector3.one; } } private static bool EnsureWorldUiOverlays() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_lowerLeftRoot != (Object)null) { return false; } if (Time.unscaledTime < _nextProbeAt) { return false; } _nextProbeAt = Time.unscaledTime + 1f; RectTransform val = ResolveLowerLeftMonitorTarget(); if ((Object)(object)val == (Object)null) { if (!_loggedWaitingForTarget) { _loggedWaitingForTarget = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Vanilla monitor display waiting for screenLevelDescription RectTransform."); } } return false; } CreateWorldOverlay(val, "LethalCCTV_LowerLeftCCTVOverlay", (Texture)(object)_leftRenderTexture, out _lowerLeftRoot, out _lowerLeftImage, Vector3.zero); _loggedWaitingForTarget = false; if (!_loggedCreated) { _loggedCreated = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] Vanilla monitor CCTV overlay bound from lower-left monitor target '" + GetPath((Transform)(object)val) + "'.")); } } return true; } private static void CreateWorldOverlay(RectTransform target, string name, Texture texture, out GameObject root, out RawImage image, Vector3 localOffset) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_00b9: Unknown result type (might be due to invalid IL or missing references) Transform val = (Transform)(((Object)(object)((Transform)target).parent != (Object)null) ? ((object)((Transform)target).parent) : ((object)target)); root = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage) }); root.transform.SetParent(val, false); RectTransform component = root.GetComponent(); if ((Object)(object)((Transform)target).parent != (Object)null) { CopyRectTransform(target, component); ((Transform)component).localPosition = ((Transform)component).localPosition + localOffset; } else { Stretch(component); } image = root.GetComponent(); image.texture = (Texture)(((Object)(object)texture != (Object)null) ? ((object)texture) : ((object)Texture2D.blackTexture)); ((Graphic)image).color = Color.white; ((Graphic)image).raycastTarget = false; root.transform.SetAsLastSibling(); } private static RectTransform ResolveLowerLeftMonitorTarget() { StartOfRound instance = StartOfRound.Instance; RectTransform val = (((Object)(object)instance != (Object)null && (Object)(object)instance.screenLevelDescription != (Object)null) ? ((TMP_Text)instance.screenLevelDescription).rectTransform : null); if ((Object)(object)val == (Object)null) { return null; } Transform parent = ((Transform)val).parent; RectTransform val2 = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (!((Object)(object)val2 != (Object)null)) { return val; } return val2; } private static bool SyncSlotTextures() { if (_slotImages == null) { return false; } bool result = false; for (int i = 0; i < _slotImages.Length; i++) { if (!((Object)(object)_slotImages[i] == (Object)null)) { Texture val = (Texture)(((object)QuadMonitor.GetCurrentDisplayTexture(i)) ?? ((object)Texture2D.blackTexture)); if ((Object)(object)_slotImages[i].texture != (Object)(object)val) { _slotImages[i].texture = val; result = true; } } } if ((Object)(object)_lowerLeftImage != (Object)null && (Object)(object)_lowerLeftImage.texture != (Object)(object)_leftRenderTexture) { _lowerLeftImage.texture = (Texture)(object)_leftRenderTexture; result = true; } return result; } private static void SyncRightMonitor(bool allowRadarWork) { if ((Object)(object)_rightRadarImage != (Object)null) { Texture val = (allowRadarWork ? VanillaRadarFeed.ResolveTexture() : VanillaRadarFeed.PeekTexture()); if ((Object)(object)val == (Object)null) { val = RadarOverlay.ResolveMapTexture(); } val = (Texture)(((object)val) ?? ((object)Texture2D.blackTexture)); if ((Object)(object)_rightRadarImage.texture != (Object)(object)val) { _rightRadarImage.texture = val; _rightCompositorDirty = true; } } bool flag = allowRadarWork && VanillaRadarFeed.HasLiveTexture; if ((Object)(object)_rightRadarLabel != (Object)null) { string text = (flag ? VanillaRadarFeed.GetStatusLabel() : RadarOverlay.GetActiveInteriorFloorLabel()); if (!string.Equals(((TMP_Text)_rightRadarLabel).text, text, StringComparison.Ordinal)) { ((TMP_Text)_rightRadarLabel).text = text; _rightCompositorDirty = true; } } if ((Object)(object)_rightRadarLegend != (Object)null) { string text2 = (flag ? VanillaRadarFeed.GetLegendLabel() : string.Empty); if (!string.Equals(((TMP_Text)_rightRadarLegend).text, text2, StringComparison.Ordinal)) { ((TMP_Text)_rightRadarLegend).text = text2; _rightCompositorDirty = true; } } } private static bool ShouldRenderRightCompositor(float now, bool monitorVisible) { if (_rightCompositorDirty) { return true; } if (MonitorFocus.IsStationRadarLookActive && _nextRightCompositorRenderAt - now > 0.25f) { return true; } return now >= _nextRightCompositorRenderAt; } private static float ResolveRightCompositorInterval(bool monitorVisible) { if (MonitorFocus.IsFocused) { if (!MonitorFocus.IsStationRadarLookActive) { return 0.5f; } return 0.25f; } if (!monitorVisible) { return 1f; } return 0.5f; } private static void RenderMonitorTextures(float now, bool monitorVisible) { try { RunDisplayPerfStep("CCTVVanillaMonitorDisplay.RenderMonitorTextures.left", delegate { Camera leftCamera = _leftCamera; if (leftCamera != null) { leftCamera.Render(); } }); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Lower-left CCTV monitor render failed: " + ex.Message)); } } if (!ShouldRenderRightCompositor(now, monitorVisible)) { return; } try { RunDisplayPerfStep("CCTVVanillaMonitorDisplay.RenderMonitorTextures.right", delegate { Camera rightCamera = _rightCamera; if (rightCamera != null) { rightCamera.Render(); } }); _nextRightCompositorRenderAt = now + ResolveRightCompositorInterval(monitorVisible); _rightCompositorDirty = false; } catch (Exception ex2) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Right CCTV monitor render failed: " + ex2.Message)); } } } private static void RunDisplayPerfStep(string stepName, Action action) { if (action == null) { return; } if (!MonitorFocus.IsFocused) { action(); return; } long timestamp = Stopwatch.GetTimestamp(); try { action(); } finally { FocusPerfProbe.RecordStep(stepName, Stopwatch.GetTimestamp() - timestamp); } } private static bool TryResolveGeneralImprovementsScreens(out int feedIndex, out int radarIndex) { if (!TryResolveGeneralImprovementsScreensCore(out feedIndex, out radarIndex)) { return false; } _generalImprovementsWallSeen = true; GeneralImprovementsMonitorCompat.LogBindingOnce(feedIndex, radarIndex); return true; } private static bool TryResolveGeneralImprovementsScreensCore(out int feedIndex, out int radarIndex) { feedIndex = -1; radarIndex = -1; if (!GeneralImprovementsMonitorCompat.IsLoaded) { return false; } if (!GeneralImprovementsMonitorCompat.AreBetterMonitorsActive()) { return false; } LethalCCTVConfig config = SurveillanceBootstrap.Config; int configuredFeed = ((config?.GeneralImprovementsFeedScreenIndex != null) ? config.GeneralImprovementsFeedScreenIndex.Value : (-1)); int configuredRadar = ((config?.GeneralImprovementsRadarScreenIndex != null) ? config.GeneralImprovementsRadarScreenIndex.Value : (-1)); if (!GeneralImprovementsMonitorCompat.TryResolveConfiguredScreens(configuredFeed, configuredRadar, out feedIndex, out radarIndex)) { return false; } return true; } internal static bool TryGetBoundFeedScreen(out MeshRenderer renderer, out int materialIndex, out bool generalImprovementsScreen) { return TryGetVisibleScreen(_lowerLeftBinding, feed: true, out renderer, out materialIndex, out generalImprovementsScreen); } internal static bool TryGetBoundRadarScreen(out MeshRenderer renderer, out int materialIndex, out bool generalImprovementsScreen) { return TryGetVisibleScreen(_lowerRightBinding, feed: false, out renderer, out materialIndex, out generalImprovementsScreen); } private static bool TryGetVisibleScreen(ScreenBinding binding, bool feed, out MeshRenderer renderer, out int materialIndex, out bool generalImprovementsScreen) { renderer = null; materialIndex = -1; generalImprovementsScreen = false; if (binding != null && binding.IsBound && binding.IsGeneralImprovementsScreen && (Object)(object)binding.Renderer != (Object)null) { renderer = binding.Renderer; materialIndex = binding.MaterialIndex; generalImprovementsScreen = true; return true; } if (TryResolveGeneralImprovementsScreensCore(out var feedIndex, out var radarIndex)) { if (GeneralImprovementsMonitorCompat.TryGetResolvedScreen(feed ? feedIndex : radarIndex, out var renderer2, out var materialIndex2) && (Object)(object)renderer2 != (Object)null) { renderer = renderer2; materialIndex = materialIndex2; generalImprovementsScreen = true; return true; } return false; } if (binding != null && binding.IsBound && (Object)(object)binding.Renderer != (Object)null) { renderer = binding.Renderer; materialIndex = binding.MaterialIndex; return true; } return false; } internal static bool OwnsGeneralImprovementsMapScreen() { if (!_lowerLeftBinding.IsGeneralImprovementsMapScreen) { return _lowerRightBinding.IsGeneralImprovementsMapScreen; } return true; } private static bool IsGeneralImprovementsWallPending() { if (_generalImprovementsWallSeen) { return GeneralImprovementsMonitorCompat.IsLoaded; } return false; } private static void PinLowerLeftVideoTexture() { if (_lowerLeftBinding.IsGeneralImprovementsScreen) { return; } VideoPlayer val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.screenLevelVideoReel : null); RenderTexture val2 = (((Object)(object)val != (Object)null) ? val.targetTexture : null); if ((Object)(object)val2 == (Object)null || (Object)(object)_leftRenderTexture == (Object)null) { return; } try { Graphics.Blit((Texture)(object)_leftRenderTexture, val2); if (!_loggedPinningMapVideo) { _loggedPinningMapVideo = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] Pinning vanilla lower-left MapScreenVideo texture to CCTV feed ({((Texture)val2).width}x{((Texture)val2).height})."); } } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Lower-left MapScreenVideo pin failed: " + ex.Message)); } } } private static bool BindLeftMonitorTexture() { if ((Object)(object)_leftRenderTexture == (Object)null) { return false; } if (TryResolveGeneralImprovementsScreens(out var feedIndex, out var _) && GeneralImprovementsMonitorCompat.TryGetResolvedScreen(feedIndex, out var renderer, out var materialIndex)) { _loggedLeftMissing = false; return _lowerLeftBinding.Bind(renderer, materialIndex, (Texture)(object)_leftRenderTexture, generalImprovementsScreen: true, GeneralImprovementsMonitorCompat.ResolveScreenDriver(feedIndex), GeneralImprovementsMonitorCompat.IsMapScreenIndex(feedIndex)); } if (IsGeneralImprovementsWallPending()) { return false; } if (_lowerLeftBinding.IsBound) { return _lowerLeftBinding.Reassert(); } MeshRenderer val = FindMonitorWallRenderer(); if ((Object)(object)val == (Object)null) { if (!_loggedLeftMissing) { _loggedLeftMissing = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Lower-left CCTV monitor renderer Cube.001 not found; using UI overlay fallback only."); } } return false; } int num = ResolveLowerLeftMonitorMaterialIndex(val); if (num < 0) { return false; } _loggedLeftMissing = false; return _lowerLeftBinding.Bind(val, num, (Texture)(object)_leftRenderTexture); } private static bool BindRightMonitorTexture() { if ((Object)(object)_rightRenderTexture == (Object)null) { return false; } if (TryResolveGeneralImprovementsScreens(out var _, out var radarIndex)) { bool flag = _lowerRightAuxBinding.IsBound && _lowerRightAuxBinding.Restore(); if (GeneralImprovementsMonitorCompat.TryGetResolvedScreen(radarIndex, out var renderer, out var materialIndex)) { _loggedRightMissing = false; return flag | _lowerRightBinding.Bind(renderer, materialIndex, (Texture)(object)_rightRenderTexture, generalImprovementsScreen: true, GeneralImprovementsMonitorCompat.ResolveScreenDriver(radarIndex), GeneralImprovementsMonitorCompat.IsMapScreenIndex(radarIndex)); } return flag | (_lowerRightBinding.IsBound && _lowerRightBinding.Restore()); } if (IsGeneralImprovementsWallPending()) { return false; } if (_lowerRightBinding.IsBound) { bool flag2 = _lowerRightBinding.Reassert(); if (_lowerRightAuxBinding.IsBound) { flag2 |= _lowerRightAuxBinding.Restore(); } return flag2; } MeshRenderer val = FindMonitorWallRenderer(); int num = ResolveCubeSecondaryScreenIndex(val); if ((Object)(object)val != (Object)null && num >= 0) { _loggedRightMissing = false; bool flag3 = _lowerRightBinding.Bind(val, num, (Texture)(object)_rightRenderTexture); if (_lowerRightAuxBinding.IsBound) { flag3 |= _lowerRightAuxBinding.Restore(); } return flag3; } if (!_loggedRightMissing) { _loggedRightMissing = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Lower-right CCTV monitor Cube.001 secondary screen slot not found; radar monitor will stay vanilla."); } } return false; } private static int ResolveCubeSecondaryScreenIndex(MeshRenderer renderer) { if ((Object)(object)renderer == (Object)null) { return -1; } Material[] sharedMaterials; try { sharedMaterials = ((Renderer)renderer).sharedMaterials; } catch { return -1; } if (sharedMaterials.Length < 3) { return -1; } int num = (((Object)(object)StartOfRound.Instance?.mapScreen != (Object)null && (Object)(object)StartOfRound.Instance.mapScreen.mesh == (Object)(object)renderer) ? StartOfRound.Instance.mapScreen.materialIndex : (-1)); int num2 = (((Object)(object)_lowerLeftBinding.Renderer == (Object)(object)renderer) ? _lowerLeftBinding.MaterialIndex : (-1)); int result = -1; int num3 = 199; for (int i = 0; i < sharedMaterials.Length; i++) { if (i == num || i == num2) { continue; } Material val = sharedMaterials[i]; if (!((Object)(object)val == (Object)null) && (((Object)val).name == null || ((Object)val).name.IndexOf("_LethalCCTV_", StringComparison.Ordinal) < 0)) { int num4 = 0; string obj2 = (((Object)(object)val.shader != (Object)null) ? ((Object)val.shader).name : string.Empty); string text = ((Object)val).name ?? string.Empty; if (obj2.IndexOf("Unlit", StringComparison.OrdinalIgnoreCase) >= 0) { num4 += 250; } if (text.IndexOf("ShipScreen", StringComparison.OrdinalIgnoreCase) >= 0) { num4 += 180; } if (text.IndexOf("Map", StringComparison.OrdinalIgnoreCase) >= 0) { num4 -= 120; } if (val.HasProperty("_UnlitColorMap")) { num4 += 120; } if (val.mainTexture is RenderTexture) { num4 += 70; } if (obj2.IndexOf("HDRP/Lit", StringComparison.OrdinalIgnoreCase) >= 0) { num4 -= 180; } if (num4 > num3) { num3 = num4; result = i; } } } return result; } private static void DumpMonitorDiagnosticsOnce() { if (_diagnosticsDumped) { return; } _diagnosticsDumped = true; try { GameObject val = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall"); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] --- monitor diagnostics (one-shot) ---"); } if ((Object)(object)val != (Object)null) { MeshRenderer[] componentsInChildren = val.GetComponentsInChildren(true); foreach (MeshRenderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null)) { Material[] sharedMaterials = ((Renderer)val2).sharedMaterials; string arg = string.Join(", ", Array.ConvertAll(sharedMaterials, (Material m) => (!((Object)(object)m != (Object)null)) ? "null" : (((Object)m).name + "(" + (((Object)(object)m.shader != (Object)null) ? ((Object)m.shader).name : "?") + ")"))); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV] {GetPath(((Component)val2).transform)} slots={sharedMaterials.Length} [{arg}]"); } } } } else { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)"[LethalCCTV] MonitorWall not found."); } } if (GeneralImprovementsMonitorCompat.IsLoaded) { int num = GeneralImprovementsMonitorCompat.ActiveMonitorCount(); ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogInfo((object)($"[LethalCCTV] GeneralImprovements loaded: betterMonitorsActive={GeneralImprovementsMonitorCompat.AreBetterMonitorsActive()} " + $"screens={num} poweredOn={GeneralImprovementsMonitorCompat.MonitorsPoweredOn()}")); } for (int num2 = 0; num2 < num; num2++) { if (GeneralImprovementsMonitorCompat.TryGetScreen(num2, out var renderer, out var materialIndex)) { ManualLogSource log5 = SurveillanceBootstrap.Log; if (log5 != null) { log5.LogInfo((object)($"[LethalCCTV] GI screen {num2} {GetPath(((Component)renderer).transform)} slot={materialIndex} " + $"unassigned={GeneralImprovementsMonitorCompat.IsScreenUnassigned(num2)}")); } } } if (GeneralImprovementsMonitorCompat.TryGetMapScreen(out var renderer2, out var materialIndex2)) { ManualLogSource log6 = SurveillanceBootstrap.Log; if (log6 != null) { log6.LogInfo((object)($"[LethalCCTV] GI map screen (index {-2}) " + $"{GetPath(((Component)renderer2).transform)} slot={materialIndex2}")); } } else { ManualLogSource log7 = SurveillanceBootstrap.Log; if (log7 != null) { log7.LogInfo((object)"[LethalCCTV] GI map screen (BigMiddle/MScreen) not resolvable."); } } } ManualCameraRenderer[] array = Object.FindObjectsOfType(); foreach (ManualCameraRenderer val3 in array) { if (!((Object)(object)val3 == (Object)null)) { ManualLogSource log8 = SurveillanceBootstrap.Log; if (log8 != null) { log8.LogInfo((object)("[LethalCCTV] MCR " + GetPath(((Component)val3).transform) + " mesh=" + (((Object)(object)val3.mesh != (Object)null) ? ((Object)val3.mesh).name : "null") + " " + string.Format("mesh2={0} materialIndex={1} enabled={2}", ((Object)(object)val3.mesh2 != (Object)null) ? ((Object)val3.mesh2).name : "null", val3.materialIndex, ((Behaviour)val3).enabled))); } } } ManualLogSource log9 = SurveillanceBootstrap.Log; if (log9 != null) { log9.LogInfo((object)"[LethalCCTV] --- end monitor diagnostics ---"); } } catch (Exception ex) { ManualLogSource log10 = SurveillanceBootstrap.Log; if (log10 != null) { log10.LogDebug((object)("[LethalCCTV] Monitor diagnostics dump failed: " + ex.Message)); } } } private static MeshRenderer FindLegacyRightMonitorRenderer() { GameObject val = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube.001"); MeshRenderer val2 = (((Object)(object)val != (Object)null) ? val.GetComponent() : null); if ((Object)(object)val2 != (Object)null) { return val2; } Transform val3 = (((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.elevatorTransform != (Object)null) ? StartOfRound.Instance.elevatorTransform.Find("ShipModels2b/MonitorWall/Cube.001") : null); if ((Object)(object)val3 != (Object)null) { MeshRenderer component = ((Component)val3).GetComponent(); if ((Object)(object)component != (Object)null) { return component; } } StartOfRound instance = StartOfRound.Instance; MeshRenderer val4 = MonitorWallScreenOrNull(((Object)(object)instance != (Object)null) ? instance.insideCameraScreen : null); if ((Object)(object)val4 != (Object)null) { return val4; } return MonitorWallScreenOrNull(((Object)(object)instance != (Object)null) ? instance.securityCameraScreen : null); } private static MeshRenderer MonitorWallScreenOrNull(ManualCameraRenderer driver) { MeshRenderer val = (((Object)(object)driver != (Object)null) ? driver.mesh : null); if ((Object)(object)val == (Object)null) { return null; } MeshRenderer val2 = FindMonitorWallRenderer(); if ((Object)(object)val == (Object)(object)val2) { return null; } string text = ((Object)((Component)val).gameObject).name ?? string.Empty; if (text.IndexOf("Button", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Door", StringComparison.OrdinalIgnoreCase) >= 0) { return null; } Transform parent = ((Component)val).transform.parent; if (!((Object)(object)parent != (Object)null) || !(((Object)parent).name == "MonitorWall")) { return null; } return val; } private static MeshRenderer FindMonitorWallRenderer() { GameObject val = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube.001"); MeshRenderer val2 = (((Object)(object)val != (Object)null) ? val.GetComponent() : null); if ((Object)(object)val2 != (Object)null) { return val2; } Transform val3 = (((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.elevatorTransform != (Object)null) ? StartOfRound.Instance.elevatorTransform.Find("ShipModels2b/MonitorWall/Cube.001") : null); if (!((Object)(object)val3 != (Object)null)) { return null; } return ((Component)val3).GetComponent(); } private static int ResolveLowerLeftMonitorMaterialIndex(MeshRenderer renderer) { if ((Object)(object)renderer == (Object)null) { return -1; } Material[] sharedMaterials; try { sharedMaterials = ((Renderer)renderer).sharedMaterials; } catch { return -1; } ManualCameraRenderer val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.mapScreen : null); int num = (((Object)(object)val != (Object)null && (Object)(object)val.mesh == (Object)(object)renderer) ? val.materialIndex : (-1)); if (num >= 0 && num < sharedMaterials.Length) { return num; } if (1 >= sharedMaterials.Length) { return -1; } return 1; } private static int ResolveRightMonitorMaterialIndex(MeshRenderer renderer) { if ((Object)(object)renderer == (Object)null) { return -1; } Material[] sharedMaterials; try { sharedMaterials = ((Renderer)renderer).sharedMaterials; } catch { return -1; } if (sharedMaterials.Length == 0) { return -1; } if (sharedMaterials.Length == 1) { return 0; } ManualCameraRenderer val = FindDriverForRenderer(renderer); if ((Object)(object)val != (Object)null && (Object)(object)val.mesh == (Object)(object)renderer && val.materialIndex >= 0 && val.materialIndex < sharedMaterials.Length) { return val.materialIndex; } int num = (((Object)(object)StartOfRound.Instance?.mapScreen != (Object)null && (Object)(object)StartOfRound.Instance.mapScreen.mesh == (Object)(object)renderer) ? StartOfRound.Instance.mapScreen.materialIndex : (-1)); int result = -1; int num2 = int.MinValue; for (int i = 0; i < sharedMaterials.Length; i++) { if (i == num) { continue; } Material val2 = sharedMaterials[i]; if (!((Object)(object)val2 == (Object)null)) { int num3 = 0; string obj2 = (((Object)(object)val2.shader != (Object)null) ? ((Object)val2.shader).name : string.Empty); string text = ((Object)val2).name ?? string.Empty; if (obj2.IndexOf("Unlit", StringComparison.OrdinalIgnoreCase) >= 0) { num3 += 250; } if (text.IndexOf("ShipScreen", StringComparison.OrdinalIgnoreCase) >= 0) { num3 += 180; } if (text.IndexOf("Map", StringComparison.OrdinalIgnoreCase) >= 0) { num3 -= 120; } if (val2.HasProperty("_UnlitColorMap")) { num3 += 120; } if (val2.HasProperty("_BaseColorMap")) { num3 += 60; } if (val2.mainTexture is RenderTexture) { num3 += 70; } if (obj2.IndexOf("HDRP/Lit", StringComparison.OrdinalIgnoreCase) >= 0) { num3 -= 180; } if (num3 > num2) { num2 = num3; result = i; } } } return result; } private static ManualCameraRenderer FindDriverForRenderer(MeshRenderer renderer) { if ((Object)(object)renderer == (Object)null) { return null; } ManualCameraRenderer[] array; try { array = Object.FindObjectsOfType(); } catch { return null; } foreach (ManualCameraRenderer val in array) { if ((Object)(object)val != (Object)null && (Object)(object)val.mesh == (Object)(object)renderer) { return val; } } foreach (ManualCameraRenderer val2 in array) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2.mesh2 == (Object)(object)renderer) { return val2; } } return null; } internal static void Tick() { TickVanillaCameraGuard(Time.unscaledTime); if (!CCTVTerminalUnlockable.IsPurchased()) { SetCctvModeActive(active: false, announce: false); SetActive(active: false); TickCctvTargetOutlines(active: false); return; } if (!_cctvModeActive || QuadMonitor.QuadRTs == null) { SetActive(active: false); TickCctvTargetOutlines(active: false); return; } EnsureRenderRig(); if ((Object)(object)_leftRenderTexture == (Object)null || (Object)(object)_rightRenderTexture == (Object)null) { TickCctvTargetOutlines(active: false); return; } if (!CCTVShipSystemsBridge.IsShipPowerOnline()) { ApplyMonitorPowerBlank(); TickCctvTargetOutlines(active: false); return; } ClearMonitorPowerBlank(); float unscaledTime = Time.unscaledTime; bool flag = IsMonitorWorkVisible(); bool flag2 = MonitorFocus.IsFocused || flag; VanillaRadarFeed.SetActive(flag2); ReassertCctvScreenOwnershipFast(unscaledTime); UpdateLeftSwitchFlash(unscaledTime); TickCctvTargetOutlines(ShouldRunTargetOutlines()); if (ShouldRunBindMaintenance(unscaledTime, flag)) { bool flag3 = false; long timestamp = Stopwatch.GetTimestamp(); DumpMonitorDiagnosticsOnce(); RecordBindMaintenanceStep("CCTVVanillaMonitorDisplay.BindMaintenance.Diagnostics", timestamp); timestamp = Stopwatch.GetTimestamp(); flag3 |= EnsureWorldUiOverlays(); RecordBindMaintenanceStep("CCTVVanillaMonitorDisplay.BindMaintenance.EnsureWorldUiOverlays", timestamp); timestamp = Stopwatch.GetTimestamp(); SuppressVanillaLowerMonitorFeeds(); RecordBindMaintenanceStep("CCTVVanillaMonitorDisplay.BindMaintenance.SuppressVanillaLowerMonitorFeeds", timestamp); timestamp = Stopwatch.GetTimestamp(); flag3 |= BindLeftMonitorTexture(); RecordBindMaintenanceStep("CCTVVanillaMonitorDisplay.BindMaintenance.BindLeftMonitorTexture", timestamp); timestamp = Stopwatch.GetTimestamp(); flag3 |= BindRightMonitorTexture(); RecordBindMaintenanceStep("CCTVVanillaMonitorDisplay.BindMaintenance.BindRightMonitorTexture", timestamp); timestamp = Stopwatch.GetTimestamp(); flag3 |= _lowerLeftBinding.RediscoverDriversIfDue(unscaledTime); RecordBindMaintenanceStep("CCTVVanillaMonitorDisplay.BindMaintenance.RediscoverDrivers.lowerLeft", timestamp); timestamp = Stopwatch.GetTimestamp(); flag3 |= _lowerRightBinding.RediscoverDriversIfDue(unscaledTime); RecordBindMaintenanceStep("CCTVVanillaMonitorDisplay.BindMaintenance.RediscoverDrivers.lowerRight", timestamp); timestamp = Stopwatch.GetTimestamp(); flag3 |= _lowerRightAuxBinding.RediscoverDriversIfDue(unscaledTime); RecordBindMaintenanceStep("CCTVVanillaMonitorDisplay.BindMaintenance.RediscoverDrivers.lowerRightAux", timestamp); timestamp = Stopwatch.GetTimestamp(); flag3 |= SyncSlotTextures(); RecordBindMaintenanceStep("CCTVVanillaMonitorDisplay.BindMaintenance.SyncSlotTextures", timestamp); timestamp = Stopwatch.GetTimestamp(); flag3 |= RefreshLeftCameraLabel(unscaledTime, flag); RecordBindMaintenanceStep("CCTVVanillaMonitorDisplay.BindMaintenance.RefreshLeftCameraLabel", timestamp); timestamp = Stopwatch.GetTimestamp(); if ((Object)(object)_lowerLeftRoot != (Object)null && !_lowerLeftRoot.activeSelf) { _lowerLeftRoot.SetActive(true); _lowerLeftRoot.transform.SetAsLastSibling(); flag3 = true; } RecordBindMaintenanceStep("CCTVVanillaMonitorDisplay.BindMaintenance.ReactivateLowerLeftOverlay", timestamp); if (flag3) { _compositorDirty = true; _forceFastMaterialVerify = true; } } if (unscaledTime >= _nextReassertAt) { _nextReassertAt = unscaledTime + 1f; ReassertCctvScreenOwnership(); } if (flag && !_wasMonitorVisible) { _compositorDirty = true; QuadCameraAssignment.RequestWakeAllSlots(); } _wasMonitorVisible = flag; if (ShouldRenderCompositor(unscaledTime, flag)) { _nextCompositorRenderAt = unscaledTime + ResolveCompositorInterval(flag); SyncRightMonitor(flag2); RefreshLeftCameraLabel(unscaledTime, flag); RenderMonitorTextures(unscaledTime, flag); PinLowerLeftVideoTexture(); _compositorDirty = false; _lastCompositorRenderAt = unscaledTime; } ReportSuppressedUnobservedBindMaintenance(unscaledTime); ReportSuppressedUnobservedRepaints(unscaledTime); } private static void RecordBindMaintenanceStep(string stepName, long startedAt) { SurveillanceBootstrap.RecordLateUpdateNestedStep(stepName, Stopwatch.GetTimestamp() - startedAt); } private static bool ShouldRunBindMaintenance(float now, bool monitorVisible) { bool flag = monitorVisible || MonitorFocus.IsFocused; if (!(now >= _nextBindMaintenanceAt) && !(_bindMaintenancePending && flag)) { return false; } _nextBindMaintenanceAt = now + 1f; if (!flag) { _bindMaintenancePending = true; _suppressedUnobservedBindMaintenancePasses++; if (!_bindMaintenanceGateLogged) { _bindMaintenanceGateLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV.Timing] bind-maintenance gate deferred an unobserved pass; one maintenance pass is pending for the first observable frame."); } } return false; } bool bindMaintenancePending = _bindMaintenancePending; _bindMaintenancePending = false; if (bindMaintenancePending && !_bindMaintenanceResumeLogged) { _bindMaintenanceResumeLogged = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)"[LethalCCTV.Timing] bind-maintenance gate released its pending pass on the first observable frame."); } } return true; } private static void ReportSuppressedUnobservedBindMaintenance(float now) { if (_nextBindMaintenanceSuppressionReportAt <= 0f) { _nextBindMaintenanceSuppressionReportAt = now + 30f; } else { if (now < _nextBindMaintenanceSuppressionReportAt) { return; } _nextBindMaintenanceSuppressionReportAt = now + 30f; if (_suppressedUnobservedBindMaintenancePasses > 0) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV.Timing] bind-maintenance gate suppressed " + $"{_suppressedUnobservedBindMaintenancePasses} unobserved pass(es) in the last " + $"{30f:0}s (pending={_bindMaintenancePending}, " + $"focused={MonitorFocus.IsFocused}).")); } _suppressedUnobservedBindMaintenancePasses = 0L; } } } private static void ReportSuppressedUnobservedRepaints(float now) { if (_nextSuppressionReportAt <= 0f) { _nextSuppressionReportAt = now + 30f; } else { if (now < _nextSuppressionReportAt) { return; } _nextSuppressionReportAt = now + 30f; if (_suppressedUnobservedRepaints > 0) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)($"[LethalCCTV.Timing] compositor gate suppressed {_suppressedUnobservedRepaints} " + $"unobserved repaint(s) in the last {30f:0}s " + $"(dirty={_compositorDirty}, focused={MonitorFocus.IsFocused})")); } _suppressedUnobservedRepaints = 0L; } } } private static bool ShouldRenderCompositor(float now, bool monitorVisible) { if (_lastCompositorRenderAt <= 0f) { return true; } if (!monitorVisible) { _suppressedUnobservedRepaints++; return false; } if (_compositorDirty || IsLeftSwitchAnimating(now)) { return true; } return now >= _nextCompositorRenderAt; } private static float ResolveCompositorInterval(bool monitorVisible) { if (MonitorFocus.IsFocused) { if (!MonitorFocus.IsStationCameraFeedInteractionActive) { return 0.1f; } return 1f / 18f; } if (!monitorVisible) { return 1f; } return 0.5f; } private static bool IsMonitorWorkVisible() { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_00ff: 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_0105: Unknown result type (might be due to invalid IL or missing references) if (MonitorFocus.IsFocused) { return true; } if (IsRendererVisible((Renderer)(object)_lowerLeftBinding.Renderer) || IsRendererVisible((Renderer)(object)_lowerRightBinding.Renderer) || IsRendererVisible((Renderer)(object)_lowerRightAuxBinding.Renderer)) { return true; } if (_lowerLeftBinding.IsBound || _lowerRightBinding.IsBound || _lowerRightAuxBinding.IsBound) { return false; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null) { return false; } if (!val.isInHangarShipRoom && !val.isInElevator) { return false; } Transform val2 = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.elevatorTransform : null); if ((Object)(object)val2 == (Object)null) { return true; } Transform val3 = val2.Find("ShipModels2b/MonitorWall"); Vector3 val4 = (((Object)(object)val3 != (Object)null) ? val3.position : val2.position); Vector3 val5 = ((Component)val).transform.position - val4; return ((Vector3)(ref val5)).sqrMagnitude <= 144f; } private static bool IsRendererVisible(Renderer renderer) { if ((Object)(object)renderer != (Object)null && renderer.enabled && ((Component)renderer).gameObject.activeInHierarchy) { return renderer.isVisible; } return false; } private static void CreateDivider(RectTransform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 sizeDelta) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //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_0056: 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_0065: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)parent, false); SetLayerRecursive(val, 31); RectTransform component = val.GetComponent(); component.anchorMin = anchorMin; component.anchorMax = anchorMax; component.pivot = pivot; component.anchoredPosition = Vector2.zero; component.sizeDelta = sizeDelta; ((Transform)component).localRotation = Quaternion.identity; ((Transform)component).localScale = Vector3.one; Image component2 = val.GetComponent(); ((Graphic)component2).color = new Color(0f, 0.8f, 0.2f, 0.65f); ((Graphic)component2).raycastTarget = false; } private static void CreateBorder(RectTransform parent, Color color, float thickness) { //IL_0010: 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) //IL_002e: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_00a2: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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_00ec: Unknown result type (might be due to invalid IL or missing references) CreateBorderEdge(parent, "BorderTop", new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, thickness), color); CreateBorderEdge(parent, "BorderBottom", Vector2.zero, new Vector2(1f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, thickness), color); CreateBorderEdge(parent, "BorderLeft", Vector2.zero, new Vector2(0f, 1f), new Vector2(0f, 0.5f), new Vector2(thickness, 0f), color); CreateBorderEdge(parent, "BorderRight", new Vector2(1f, 0f), Vector2.one, new Vector2(1f, 0.5f), new Vector2(thickness, 0f), color); } private static void CreateBorderEdge(RectTransform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 sizeDelta, Color color) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //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_0056: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)parent, false); SetLayerRecursive(val, 31); RectTransform component = val.GetComponent(); component.anchorMin = anchorMin; component.anchorMax = anchorMax; component.pivot = pivot; component.sizeDelta = sizeDelta; component.anchoredPosition = Vector2.zero; Image component2 = val.GetComponent(); ((Graphic)component2).color = color; ((Graphic)component2).raycastTarget = false; } private static void CopyRectTransform(RectTransform source, RectTransform destination) { //IL_0015: 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_002d: 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_0045: 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_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) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source == (Object)null) && !((Object)(object)destination == (Object)null)) { destination.anchorMin = source.anchorMin; destination.anchorMax = source.anchorMax; destination.pivot = source.pivot; destination.anchoredPosition = source.anchoredPosition; destination.sizeDelta = source.sizeDelta; destination.offsetMin = source.offsetMin; destination.offsetMax = source.offsetMax; ((Transform)destination).localRotation = ((Transform)source).localRotation; ((Transform)destination).localScale = ((Transform)source).localScale; } } private static void Stretch(RectTransform rt) { //IL_000b: 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_002b: 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_0041: 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_0057: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rt == (Object)null)) { rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; rt.pivot = new Vector2(0.5f, 0.5f); rt.offsetMin = Vector2.zero; rt.offsetMax = Vector2.zero; ((Transform)rt).localRotation = Quaternion.identity; ((Transform)rt).localScale = Vector3.one; } } private static void TryAssignHudFont(TextMeshProUGUI target) { if ((Object)(object)target == (Object)null) { return; } try { HUDManager instance = HUDManager.Instance; TextMeshProUGUI[] array = (((Object)(object)instance != (Object)null) ? instance.controlTipLines : null); if (array != null && array.Length != 0 && (Object)(object)array[0] != (Object)null && (Object)(object)((TMP_Text)array[0]).font != (Object)null) { ((TMP_Text)target).font = ((TMP_Text)array[0]).font; } } catch { } } private static void ApplyTextureToMaterial(Material material, Texture texture) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null) && !((Object)(object)texture == (Object)null)) { try { material.mainTexture = texture; } catch { } SetTextureIfExists(material, "_UnlitColorMap", texture); SetTextureIfExists(material, "_BaseColorMap", texture); SetTextureIfExists(material, "_BaseMap", texture); SetTextureIfExists(material, "_EmissiveColorMap", texture); if (material.HasProperty("_EmissiveColor")) { material.SetColor("_EmissiveColor", Color.white * 1.05f); } if (material.HasProperty("_EmissiveColorLDR")) { material.SetColor("_EmissiveColorLDR", Color.white); } material.EnableKeyword("_EMISSION"); material.EnableKeyword("_EMISSIVE_COLOR_MAP"); } } private static void SetTextureIfExists(Material material, string property, Texture texture) { try { if ((Object)(object)material != (Object)null && material.HasProperty(property)) { material.SetTexture(property, texture); } } catch { } } private static void ReleaseRenderTexture(ref RenderTexture texture) { if (!((Object)(object)texture == (Object)null)) { if (texture.IsCreated()) { texture.Release(); } Object.Destroy((Object)(object)texture); texture = null; } } private static void SetLayerRecursive(GameObject root, int layer) { if (!((Object)(object)root == (Object)null)) { root.layer = layer; for (int i = 0; i < root.transform.childCount; i++) { SetLayerRecursive(((Component)root.transform.GetChild(i)).gameObject, layer); } } } 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++ < 24) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private static void TickVanillaCameraGuard(float now) { if (!(now < _nextVanillaCameraGuardAt)) { _nextVanillaCameraGuardAt = now + 0.5f; try { GuardVanillaHeadMountedCamera(now); GuardVanillaMapCamera(); } catch { } ReportVanillaCameraGuard(now); } } private static void GuardVanillaHeadMountedCamera(float now) { if (!OpenBodyCamsCompat.IsLoaded || (!_suppressionCaptured && CCTVShipSystemsBridge.HasBodycamsUpgrade())) { return; } if ((Object)(object)_vanillaHeadMountedCamera == (Object)null) { if (now < _nextHeadMountedLookupAt) { return; } _nextHeadMountedLookupAt = now + 5f; _vanillaHeadMountedCamera = FindEnabledCameraByName("HeadMountedCamera"); if ((Object)(object)_vanillaHeadMountedCamera == (Object)null) { return; } } if (!((Behaviour)_vanillaHeadMountedCamera).enabled) { return; } ((Behaviour)_vanillaHeadMountedCamera).enabled = false; _headMountedGuardDisables++; if (!_headMountedGuardLogged) { _headMountedGuardLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Vanilla-camera guard disabled the always-on vanilla HeadMountedCamera (Bodycams upgrade unowned or CCTV owns the monitors; y4ngz313/Y4NGZCompany#303)."); } } } private static Camera FindEnabledCameraByName(string cameraName) { int allCamerasCount = Camera.allCamerasCount; if (allCamerasCount <= 0) { return null; } if (_cameraScanBuffer.Length < allCamerasCount) { _cameraScanBuffer = (Camera[])(object)new Camera[Mathf.NextPowerOfTwo(allCamerasCount)]; } int allCameras = Camera.GetAllCameras(_cameraScanBuffer); Camera val = null; for (int i = 0; i < allCameras; i++) { Camera val2 = _cameraScanBuffer[i]; if ((Object)(object)val == (Object)null && (Object)(object)val2 != (Object)null && ((Object)val2).name == cameraName) { val = val2; } _cameraScanBuffer[i] = null; } return val; } private static void GuardVanillaMapCamera() { if (_suppressionCaptured || CCTVShipSystemsBridge.IsPrimaryMonitorTakeoverActive() || CCTVShipSystemsBridge.IsQuotaPresentationActive()) { return; } StartOfRound instance = StartOfRound.Instance; ManualCameraRenderer val = (((Object)(object)instance != (Object)null) ? instance.mapScreen : null); if ((Object)(object)val == (Object)null) { return; } if (!((Behaviour)val).enabled) { ((Behaviour)val).enabled = true; if (!_mapScreenUnfreezeLogged) { _mapScreenUnfreezeLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Vanilla-camera guard re-enabled the frozen vanilla mapScreen renderer so vanilla resumes managing its camera (y4ngz313/Y4NGZCompany#304)."); } } } Camera val2 = (((Object)(object)val.mapCamera != (Object)null) ? val.mapCamera : val.cam); if ((Object)(object)val2 == (Object)null || !((Behaviour)val2).enabled) { return; } PlayerControllerB val3 = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if (!((Object)(object)val3 == (Object)null)) { bool flag = val.currentCameraDisabled; if (!instance.inShipPhase) { flag |= !val3.isInHangarShipRoom && !val.overrideRadarCameraOnAlways; flag |= !instance.shipDoorsEnabled && ((Object)(object)instance.currentPlanetPrefab == (Object)null || !instance.currentPlanetPrefab.activeSelf); } if (flag) { ((Behaviour)val2).enabled = false; _mapCameraGuardDisables++; } } } private static void ReportVanillaCameraGuard(float now) { if (_nextVanillaCameraGuardReportAt <= 0f) { _nextVanillaCameraGuardReportAt = now + 60f; } else { if (now < _nextVanillaCameraGuardReportAt) { return; } _nextVanillaCameraGuardReportAt = now + 60f; if (_headMountedGuardDisables > 0 || _mapCameraGuardDisables > 0) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)($"[LethalCCTV.Timing] vanilla-camera guard re-disabled HeadMountedCamera x{_headMountedGuardDisables}, " + $"MapCamera x{_mapCameraGuardDisables} in the last {60f:0}s " + "(a repeat-enabler is fighting the guard; see #303/#304).")); } _headMountedGuardDisables = 0L; _mapCameraGuardDisables = 0L; } } } private static void SuppressVanillaLowerMonitorFeeds() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return; } if (IsGeneralImprovementsMonitorWallActive()) { if (_suppressionCaptured) { RestoreVanillaLowerMonitorFeeds(); } return; } if (!_suppressionCaptured) { _suppressionCaptured = true; _levelDescriptionWasEnabled = (Object)(object)instance.screenLevelDescription != (Object)null && ((Behaviour)instance.screenLevelDescription).enabled; VideoPlayer screenLevelVideoReel = instance.screenLevelVideoReel; _videoReelWasEnabled = (Object)(object)screenLevelVideoReel != (Object)null && ((Behaviour)screenLevelVideoReel).enabled; _videoReelWasPlaying = (Object)(object)screenLevelVideoReel != (Object)null && screenLevelVideoReel.isPlaying; _mapScreenWasEnabled = (Object)(object)instance.mapScreen != (Object)null && ((Behaviour)instance.mapScreen).enabled; TryCaptureMapScreenRawImage(); CaptureLowerLeftGraphics(); } if ((Object)(object)instance.screenLevelDescription != (Object)null) { ((Behaviour)instance.screenLevelDescription).enabled = false; } SetSuppressedLowerLeftGraphics(enabled: false); if ((Object)(object)instance.screenLevelVideoReel != (Object)null) { if (instance.screenLevelVideoReel.isPlaying) { instance.screenLevelVideoReel.Stop(); } ((Behaviour)instance.screenLevelVideoReel).enabled = false; } if ((Object)(object)instance.mapScreen != (Object)null) { ((Behaviour)instance.mapScreen).enabled = false; try { if ((Object)(object)instance.mapScreen.cam != (Object)null && ((Behaviour)instance.mapScreen.cam).enabled) { ((Behaviour)instance.mapScreen.cam).enabled = false; if (!_loggedMapCameraFrozenOff) { _loggedMapCameraFrozenOff = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Disabled frozen-on vanilla MapCamera while CCTV owns the lower monitors."); } } } } catch { } } if ((Object)(object)_mapScreenRawImage != (Object)null && (Object)(object)_leftRenderTexture != (Object)null) { _mapScreenRawImage.texture = (Texture)(object)_leftRenderTexture; } } private static void ReassertSuppressedLowerMonitorFeedsFast() { if (!_suppressionCaptured) { return; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return; } try { if ((Object)(object)instance.screenLevelDescription != (Object)null && ((Behaviour)instance.screenLevelDescription).enabled) { ((Behaviour)instance.screenLevelDescription).enabled = false; } SetSuppressedLowerLeftGraphics(enabled: false); VideoPlayer screenLevelVideoReel = instance.screenLevelVideoReel; if ((Object)(object)screenLevelVideoReel != (Object)null) { if (screenLevelVideoReel.isPlaying) { screenLevelVideoReel.Stop(); } if (((Behaviour)screenLevelVideoReel).enabled) { ((Behaviour)screenLevelVideoReel).enabled = false; } } ManualCameraRenderer mapScreen = instance.mapScreen; if ((Object)(object)mapScreen != (Object)null) { if (((Behaviour)mapScreen).enabled) { ((Behaviour)mapScreen).enabled = false; } if ((Object)(object)mapScreen.cam != (Object)null && ((Behaviour)mapScreen.cam).enabled) { ((Behaviour)mapScreen.cam).enabled = false; } if ((Object)(object)mapScreen.mapCamera != (Object)null && ((Behaviour)mapScreen.mapCamera).enabled) { ((Behaviour)mapScreen.mapCamera).enabled = false; } } if ((Object)(object)_mapScreenRawImage != (Object)null && (Object)(object)_leftRenderTexture != (Object)null && (Object)(object)_mapScreenRawImage.texture != (Object)(object)_leftRenderTexture) { _mapScreenRawImage.texture = (Texture)(object)_leftRenderTexture; } } catch { } } private static void ReassertSuppressedLowerMonitorFeedsFrame() { if (!_suppressionCaptured) { return; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return; } try { if ((Object)(object)instance.screenLevelDescription != (Object)null && ((Behaviour)instance.screenLevelDescription).enabled) { ((Behaviour)instance.screenLevelDescription).enabled = false; } SetSuppressedLowerLeftGraphics(enabled: false); VideoPlayer screenLevelVideoReel = instance.screenLevelVideoReel; if ((Object)(object)screenLevelVideoReel != (Object)null) { if (((Behaviour)screenLevelVideoReel).enabled) { ((Behaviour)screenLevelVideoReel).enabled = false; } if (screenLevelVideoReel.isPlaying) { screenLevelVideoReel.Stop(); } } ManualCameraRenderer mapScreen = instance.mapScreen; if ((Object)(object)mapScreen != (Object)null) { if (((Behaviour)mapScreen).enabled) { ((Behaviour)mapScreen).enabled = false; } if ((Object)(object)mapScreen.cam != (Object)null && ((Behaviour)mapScreen.cam).enabled) { ((Behaviour)mapScreen.cam).enabled = false; } if ((Object)(object)mapScreen.mapCamera != (Object)null && ((Behaviour)mapScreen.mapCamera).enabled) { ((Behaviour)mapScreen.mapCamera).enabled = false; } } if ((Object)(object)_mapScreenRawImage != (Object)null && (Object)(object)_leftRenderTexture != (Object)null && (Object)(object)_mapScreenRawImage.texture != (Object)(object)_leftRenderTexture) { _mapScreenRawImage.texture = (Texture)(object)_leftRenderTexture; } } catch { } } private static void RestoreVanillaLowerMonitorFeeds() { if (!_suppressionCaptured) { return; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null) { try { if ((Object)(object)instance.screenLevelDescription != (Object)null) { ((Behaviour)instance.screenLevelDescription).enabled = _levelDescriptionWasEnabled; } if ((Object)(object)instance.screenLevelVideoReel != (Object)null) { ((Behaviour)instance.screenLevelVideoReel).enabled = _videoReelWasEnabled; if (_videoReelWasPlaying) { instance.screenLevelVideoReel.Play(); } } if ((Object)(object)instance.mapScreen != (Object)null) { ((Behaviour)instance.mapScreen).enabled = _mapScreenWasEnabled; } } catch { } } if ((Object)(object)_mapScreenRawImage != (Object)null) { try { _mapScreenRawImage.texture = _mapScreenRawImageTexture; } catch { } } RestoreSuppressedLowerLeftGraphics(); _mapScreenRawImage = null; _mapScreenRawImageTexture = null; _lowerLeftSuppressedGraphics = null; _lowerLeftSuppressedGraphicStates = null; _suppressionCaptured = false; _loggedMapCameraFrozenOff = false; } private static void CaptureLowerLeftGraphics() { RectTransform val = ResolveLowerLeftMonitorTarget(); if ((Object)(object)val == (Object)null) { return; } Graphic[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); if (componentsInChildren != null && componentsInChildren.Length != 0) { _lowerLeftSuppressedGraphics = componentsInChildren; _lowerLeftSuppressedGraphicStates = new bool[componentsInChildren.Length]; for (int i = 0; i < componentsInChildren.Length; i++) { _lowerLeftSuppressedGraphicStates[i] = (Object)(object)componentsInChildren[i] != (Object)null && ((Behaviour)componentsInChildren[i]).enabled; } } } private static void SetSuppressedLowerLeftGraphics(bool enabled) { if (_lowerLeftSuppressedGraphics == null) { return; } for (int i = 0; i < _lowerLeftSuppressedGraphics.Length; i++) { Graphic val = _lowerLeftSuppressedGraphics[i]; if (!((Object)(object)val == (Object)null) && (!((Object)(object)((Component)val).transform != (Object)null) || !((Object)((Component)val).transform).name.StartsWith("LethalCCTV_", StringComparison.OrdinalIgnoreCase)) && ((Behaviour)val).enabled != enabled) { ((Behaviour)val).enabled = enabled; } } } private static void RestoreSuppressedLowerLeftGraphics() { if (_lowerLeftSuppressedGraphics == null || _lowerLeftSuppressedGraphicStates == null) { return; } int num = Mathf.Min(_lowerLeftSuppressedGraphics.Length, _lowerLeftSuppressedGraphicStates.Length); for (int i = 0; i < num; i++) { Graphic val = _lowerLeftSuppressedGraphics[i]; if ((Object)(object)val != (Object)null) { ((Behaviour)val).enabled = _lowerLeftSuppressedGraphicStates[i]; } } } private static void TryCaptureMapScreenRawImage() { _mapScreenRawImage = null; _mapScreenRawImageTexture = null; GameObject val = GameObject.Find("Systems/GameSystems/ItemSystems/MapScreenUI"); if ((Object)(object)val == (Object)null) { return; } RawImage[] componentsInChildren = val.GetComponentsInChildren(true); foreach (RawImage val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.texture == (Object)null) && string.Equals(((Object)val2.texture).name, "MapScreenVideo", StringComparison.OrdinalIgnoreCase)) { _mapScreenRawImage = val2; _mapScreenRawImageTexture = val2.texture; break; } } } private static void ApplyMonitorPowerBlank() { VanillaRadarFeed.SetActive(active: false); if (!_powerBlanked) { _powerBlanked = true; ClearRenderTextureToBlack(_leftRenderTexture); ClearRenderTextureToBlack(_rightRenderTexture); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Ship power offline; CCTV feed and radar monitors blanked."); } } } private static void ClearMonitorPowerBlank() { if (_powerBlanked) { _powerBlanked = false; _compositorDirty = true; _rightCompositorDirty = true; _forceFastMaterialVerify = true; _lastCompositorRenderAt = 0f; _nextCompositorRenderAt = 0f; _nextRightCompositorRenderAt = 0f; _nextBindMaintenanceAt = 0f; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Ship power restored; CCTV feed and radar monitors resumed."); } } } private static void ClearRenderTextureToBlack(RenderTexture texture) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)texture == (Object)null) { return; } RenderTexture active = RenderTexture.active; try { RenderTexture.active = texture; GL.Clear(true, true, Color.black); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] CCTV monitor power blank failed: " + ex.Message)); } } finally { RenderTexture.active = active; } } private static void SetActive(bool active) { if ((Object)(object)_lowerLeftRoot != (Object)null && _lowerLeftRoot.activeSelf != active) { _lowerLeftRoot.SetActive(active); } if (!active) { VanillaRadarFeed.SetActive(active: false); if (_suppressionCaptured || _lowerLeftBinding.IsBound || _lowerRightBinding.IsBound || _lowerRightAuxBinding.IsBound) { RestoreVanillaLowerMonitorFeeds(); _lowerRightAuxBinding.Restore(); _lowerRightBinding.Restore(); _lowerLeftBinding.Restore(); _nextBindMaintenanceAt = 0f; _nextCompositorRenderAt = 0f; _nextReassertAt = 0f; _nextFullSuppressionAt = 0f; _nextFastMaterialVerifyAt = 0f; _forceFastMaterialVerify = false; _lastCompositorRenderAt = 0f; _compositorDirty = true; } } } } [Serializable] public sealed class CCTVWalkieMessage { public int Id; public int PlayerId; public bool Speaking; } internal static class CCTVWalkieTalkieBridge { private const string CHANNEL = "cctv_walkie_v1"; private const float OperatorTransmissionVolume = 0.6f; private static LNetworkMessage _message; private static readonly HashSet _seenIds = new HashSet(); private static readonly HashSet _activeVirtualSpeakers = new HashSet(); private static readonly Dictionary _priorSpeakerStates = new Dictionary(); private static int _nextId; private static PlayerControllerB _listeningPlayer; private static bool _priorHoldingWalkieTalkie; private static bool _localSpeaking; private static AudioClip[] _startTransmissionClips; private static AudioClip[] _stopTransmissionClips; internal static bool IsTransmitting => _localSpeaking; internal static bool IsListening => (Object)(object)_listeningPlayer != (Object)null; internal static void Initialize() { if (_message == null) { _message = LNetworkMessage.Connect("cctv_walkie_v1", (Action)OnServerReceived, (Action)OnClientReceived, (Action)null); } } internal static void Shutdown() { ExitFocus(); _message?.ClearSubscriptions(); _message = null; _seenIds.Clear(); _activeVirtualSpeakers.Clear(); _priorSpeakerStates.Clear(); _startTransmissionClips = null; _stopTransmissionClips = null; } internal static void EnterFocus(PlayerControllerB player) { if (!((Object)(object)player == (Object)null)) { Initialize(); if ((Object)(object)_listeningPlayer != (Object)(object)player) { ExitFocus(); _listeningPlayer = player; _priorHoldingWalkieTalkie = player.holdingWalkieTalkie; } player.holdingWalkieTalkie = true; UpdateVoiceEffects(); } } internal static void ExitFocus() { SetLocalSpeaking(speaking: false); if ((Object)(object)_listeningPlayer != (Object)null) { _listeningPlayer.holdingWalkieTalkie = _priorHoldingWalkieTalkie; _listeningPlayer = null; } _priorHoldingWalkieTalkie = false; UpdateVoiceEffects(); } internal static void SetLocalSpeaking(bool speaking) { PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null) { _localSpeaking = false; } else { if ((!speaking && !_localSpeaking) || (speaking && _localSpeaking && val.speakingToWalkieTalkie)) { return; } if (speaking && (Object)(object)_listeningPlayer == (Object)null) { EnterFocus(val); } _localSpeaking = speaking; CCTVWalkieMessage cCTVWalkieMessage = new CCTVWalkieMessage { Id = NextId(), PlayerId = (int)val.playerClientId, Speaking = speaking }; if (ApplySpeaking(cCTVWalkieMessage, localSender: true)) { PlayLocalOperatorTransmissionSfx(speaking); } if (_message == null) { return; } try { _message.SendServer(cCTVWalkieMessage); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] CCTV walkie stayed local: " + ex.Message)); } } } } private static int NextId() { int num = (int)(((Object)(object)GameNetworkManager.Instance?.localPlayerController != (Object)null) ? GameNetworkManager.Instance.localPlayerController.playerClientId : 0); _nextId++; return (num << 20) ^ _nextId ^ Mathf.RoundToInt(Time.realtimeSinceStartup * 1000f); } private static void OnServerReceived(CCTVWalkieMessage data, ulong _) { try { _message?.SendClients(data); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] CCTV walkie server broadcast failed: " + ex.Message)); } } } private static void OnClientReceived(CCTVWalkieMessage data) { ApplySpeaking(data, localSender: false); } private static bool ApplySpeaking(CCTVWalkieMessage data, bool localSender) { if (data == null) { return false; } if (_seenIds.Contains(data.Id)) { return false; } _seenIds.Add(data.Id); StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || instance.allPlayerScripts == null) { return false; } if (data.PlayerId < 0 || data.PlayerId >= instance.allPlayerScripts.Length) { return false; } PlayerControllerB val = instance.allPlayerScripts[data.PlayerId]; if ((Object)(object)val == (Object)null) { return false; } val.speakingToWalkieTalkie = data.Speaking; if (localSender) { val.activatingItem = data.Speaking; if ((Object)(object)val.playerBodyAnimator != (Object)null) { val.playerBodyAnimator.SetBool("walkieTalkie", data.Speaking); } } if (data.Speaking) { _activeVirtualSpeakers.Add(data.PlayerId); } else { _activeVirtualSpeakers.Remove(data.PlayerId); } SetVirtualSpeakerState(_activeVirtualSpeakers.Count > 0); PlayTransmissionSfx(data.PlayerId, data.Speaking); UpdateVoiceEffects(); return true; } private static void SetVirtualSpeakerState(bool speaking) { if (WalkieTalkie.allWalkieTalkies == null) { return; } if (!speaking) { foreach (KeyValuePair priorSpeakerState in _priorSpeakerStates) { if ((Object)(object)priorSpeakerState.Key != (Object)null) { priorSpeakerState.Key.clientIsHoldingAndSpeakingIntoThis = priorSpeakerState.Value; } } _priorSpeakerStates.Clear(); return; } for (int i = 0; i < WalkieTalkie.allWalkieTalkies.Count; i++) { WalkieTalkie val = WalkieTalkie.allWalkieTalkies[i]; if (!((Object)(object)val == (Object)null) && ((GrabbableObject)val).isBeingUsed) { if (!_priorSpeakerStates.ContainsKey(val)) { _priorSpeakerStates[val] = val.clientIsHoldingAndSpeakingIntoThis; } val.clientIsHoldingAndSpeakingIntoThis = speaking; } } } private static void PlayTransmissionSfx(int playerId, bool speaking) { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || WalkieTalkie.allWalkieTalkies == null) { return; } PlayerControllerB val = ((playerId >= 0 && playerId < instance.allPlayerScripts.Length) ? instance.allPlayerScripts[playerId] : null); for (int i = 0; i < WalkieTalkie.allWalkieTalkies.Count; i++) { WalkieTalkie val2 = WalkieTalkie.allWalkieTalkies[i]; if (!((Object)(object)val2 == (Object)null) && ((GrabbableObject)val2).isBeingUsed && !((Object)(object)val2.thisAudio == (Object)null) && (!((Object)(object)val != (Object)null) || !((Object)(object)((GrabbableObject)val2).playerHeldBy == (Object)(object)val)) && !IsPocketedHeldWalkie(val2)) { AudioClip[] array = (speaking ? val2.startTransmissionSFX : val2.stopTransmissionSFX); if (array != null && array.Length != 0) { RoundManager.PlayRandomClip(val2.thisAudio, array, true, 1f, 0, 1000); } } } } private static void PlayLocalOperatorTransmissionSfx(bool speaking) { AudioSource val = (((Object)(object)HUDManager.Instance != (Object)null) ? HUDManager.Instance.UIAudio : null); if (!((Object)(object)val == (Object)null)) { AudioClip[] array = ResolveTransmissionClips(speaking); if (array != null && array.Length != 0) { val.PlayOneShot(array[Random.Range(0, array.Length)], 0.6f); } } } private static AudioClip[] ResolveTransmissionClips(bool speaking) { if (_startTransmissionClips != null && _stopTransmissionClips != null) { if (!speaking) { return _stopTransmissionClips; } return _startTransmissionClips; } if (WalkieTalkie.allWalkieTalkies != null) { for (int i = 0; i < WalkieTalkie.allWalkieTalkies.Count; i++) { if (TryCacheTransmissionClips(WalkieTalkie.allWalkieTalkies[i])) { if (!speaking) { return _stopTransmissionClips; } return _startTransmissionClips; } } } StartOfRound instance = StartOfRound.Instance; List list = (((Object)(object)instance != (Object)null && (Object)(object)instance.allItemsList != (Object)null) ? instance.allItemsList.itemsList : null); if (list == null) { return null; } for (int j = 0; j < list.Count; j++) { Item val = list[j]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val.spawnPrefab == (Object)null) && TryCacheTransmissionClips(val.spawnPrefab.GetComponent())) { if (!speaking) { return _stopTransmissionClips; } return _startTransmissionClips; } } return null; } private static bool TryCacheTransmissionClips(WalkieTalkie walkie) { if ((Object)(object)walkie == (Object)null) { return false; } AudioClip[] startTransmissionSFX = walkie.startTransmissionSFX; AudioClip[] stopTransmissionSFX = walkie.stopTransmissionSFX; if (startTransmissionSFX == null || startTransmissionSFX.Length == 0 || stopTransmissionSFX == null || stopTransmissionSFX.Length == 0) { return false; } _startTransmissionClips = startTransmissionSFX; _stopTransmissionClips = stopTransmissionSFX; return true; } private static bool IsPocketedHeldWalkie(WalkieTalkie walkie) { if ((Object)(object)walkie == (Object)null || (Object)(object)((GrabbableObject)walkie).playerHeldBy == (Object)null) { return false; } GrabbableObject currentlyHeldObjectServer = ((GrabbableObject)walkie).playerHeldBy.currentlyHeldObjectServer; if ((Object)(object)currentlyHeldObjectServer == (Object)null) { return false; } if ((Object)(object)((Component)currentlyHeldObjectServer).GetComponent() == (Object)null) { return false; } return ((GrabbableObject)walkie).isPocketed; } private static void UpdateVoiceEffects() { if ((Object)(object)StartOfRound.Instance == (Object)null) { return; } try { StartOfRound.Instance.UpdatePlayerVoiceEffects(); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] CCTV walkie voice update skipped: " + ex.Message)); } } } } internal static class ContractObjectiveProvider { internal readonly struct MarkerSnapshot { internal readonly string Label; internal readonly Vector3 Position; internal readonly float Radius; internal readonly int ColorKind; internal readonly bool IsComplete; internal MarkerSnapshot(string label, Vector3 position, float radius, int colorKind, bool isComplete) { //IL_0017: 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) Label = (string.IsNullOrWhiteSpace(label) ? "OBJECTIVE" : label); Position = position; Radius = Mathf.Clamp(radius, 0.35f, 4f); ColorKind = colorKind; IsComplete = isComplete; } } private const string API_TYPE_NAME = "Y4NGZCompany.Contracts._Shared.MoonContractObjectiveMarkerApi"; private const float REFRESH_INTERVAL = 0.25f; private static Type _apiType; private static MethodInfo _getMarkersMethod; private static bool _resolveAttempted; private static float _nextRefreshTime; private static IReadOnlyList _cachedMarkers = Array.Empty(); internal static IReadOnlyList GetMarkers() { //IL_008d: 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_0097: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime < _nextRefreshTime) { return _cachedMarkers; } _nextRefreshTime = Time.unscaledTime + 0.25f; if (!TryResolveApi()) { _cachedMarkers = Array.Empty(); return _cachedMarkers; } try { if (!(_getMarkersMethod.Invoke(null, null) is IEnumerable enumerable)) { _cachedMarkers = Array.Empty(); return _cachedMarkers; } List list = new List(8); foreach (object item in enumerable) { if (item != null) { Vector3 val = ReadMember(item, "Position", Vector3.zero); if (!float.IsNaN(val.x) && !float.IsNaN(val.y) && !float.IsNaN(val.z)) { list.Add(new MarkerSnapshot(ReadMember(item, "Label", "OBJECTIVE"), val, ReadMember(item, "Radius", 1f), ReadMember(item, "ColorKind", 0), ReadMember(item, "IsComplete", fallback: false))); } } } _cachedMarkers = list; return _cachedMarkers; } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Contract objective marker read failed: " + ex.Message)); } _cachedMarkers = Array.Empty(); return _cachedMarkers; } } private static bool TryResolveApi() { if (_getMarkersMethod != null) { return true; } if (_resolveAttempted) { return false; } _resolveAttempted = true; _apiType = CompanyAssemblyBridge.ResolveType("Y4NGZCompany.Contracts._Shared.MoonContractObjectiveMarkerApi"); _getMarkersMethod = _apiType?.GetMethod("GetActiveMarkers", BindingFlags.Static | BindingFlags.Public); if (_getMarkersMethod != null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Contract objective marker API connected."); } return true; } return false; } private static T ReadMember(object target, string name, T fallback) { if (target == null) { return fallback; } try { Type type = target.GetType(); PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public); object obj = ((property != null) ? property.GetValue(target) : type.GetField(name, BindingFlags.Instance | BindingFlags.Public)?.GetValue(target)); if (obj == null) { return fallback; } if (obj is T result) { return result; } return (T)Convert.ChangeType(obj, typeof(T)); } catch { return fallback; } } } internal static class CrtDockLayout { internal const float DesignHeight = 356f; internal const float DefaultDesignWidth = 680f; internal const float MinDesignWidth = 400f; internal const float MaxDesignWidth = 1100f; internal const float ContentInset = 22f; internal const float FrameInset = 12f; private const float LowResFaceDilate = 0.12f; private static readonly int FaceDilateId = Shader.PropertyToID("_FaceDilate"); internal static void ApplyLowResFaceThickening(Material clonedFontMaterial) { if (!((Object)(object)clonedFontMaterial == (Object)null) && clonedFontMaterial.HasProperty(FaceDilateId) && clonedFontMaterial.GetFloat(FaceDilateId) < 0.12f) { clonedFontMaterial.SetFloat(FaceDilateId, 0.12f); } } internal static bool TryResolveDock(RectTransform rootRect, Vector2 anchoredPosition, Vector2 dockSize, float currentDesignWidth, out float designWidth, out float scale) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) designWidth = currentDesignWidth; scale = 1f; if ((Object)(object)rootRect == (Object)null) { return false; } rootRect.anchorMin = new Vector2(0.5f, 0.5f); rootRect.anchorMax = new Vector2(0.5f, 0.5f); rootRect.pivot = new Vector2(0.5f, 0.5f); rootRect.anchoredPosition = anchoredPosition; float num = Mathf.Max(1f, dockSize.x); float num2 = Mathf.Max(1f, dockSize.y); float num3 = Mathf.Clamp(356f * (num / num2), 400f, 1100f); bool num4 = Mathf.Abs(num3 - currentDesignWidth) > 0.5f; if (num4) { designWidth = num3; } scale = Mathf.Min(num2 / 356f, num / designWidth); return num4; } internal static void ResizeFrame(float designWidth, RectTransform top, RectTransform bottom, RectTransform left, RectTransform right) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) Vector2 sizeDelta = default(Vector2); ((Vector2)(ref sizeDelta))..ctor(designWidth - 24f, 2f); Vector2 sizeDelta2 = default(Vector2); ((Vector2)(ref sizeDelta2))..ctor(2f, 332f); if ((Object)(object)top != (Object)null) { top.sizeDelta = sizeDelta; } if ((Object)(object)bottom != (Object)null) { bottom.sizeDelta = sizeDelta; } if ((Object)(object)left != (Object)null) { left.sizeDelta = sizeDelta2; } if ((Object)(object)right != (Object)null) { right.sizeDelta = sizeDelta2; } } } internal static class FocusMouselook { private const string LOOK_ACTION_NAME = "Look"; private const float MAX_ROTATION_DEG_PER_SECOND = 125f; private const float RAW_LOOK_DEADZONE = 0.08f; private const float SCALED_LOOK_DEADZONE_DEG = 0.004f; private static InputAction _lookAction; private static bool _lookActionResolved; internal static void Initialize() { ResolveLookAction(); } internal static void Shutdown() { _lookAction = null; _lookActionResolved = false; } internal static void Tick() { //IL_009f: 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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0153: 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) if (!MonitorFocus.IsFocused || MonitorFocus.IsReviewMenuOpen || (MonitorFocus.IsStationEditMenuOpen && !MonitorFocus.IsStationEditThirdPersonDebugActive) || Y4NGZPlayerAnimationBridge.IsFirstPersonHandEditModeActive || (MonitorFocus.HackingOverlay != null && MonitorFocus.HackingOverlay.IsOpen) || (MonitorFocus.MainframeOverlay != null && MonitorFocus.MainframeOverlay.IsOpen)) { return; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null) { return; } if (val.isPlayerDead) { MonitorFocus.ForceExit("player-death"); } else { if (CCTVOperatorStation.IsDebugPlacementActive) { return; } if (MonitorFocus.IsStationThirdPersonDebugViewActive) { if (TryReadLookDelta(out var delta)) { MonitorFocus.ApplyStationThirdPersonOrbitDelta(delta); MonitorFocus.NotifyCameraRotated(((Vector2)(ref delta)).magnitude); } } else { if (!MonitorFocus.IsStationCameraControlActive) { return; } if (MonitorFocus.IsTurretPageActive) { if (TryReadRawLook(out var raw)) { ShipTurretController.ApplyLookDelta(raw); } } else { if (OpenBodyCamsCompat.IsFocusSlot(MonitorFocus.ActiveSlot) && OpenBodyCamsCompat.ShouldShowFocusSlot()) { return; } CCTVCamera boundCamera = QuadCameraAssignment.GetBoundCamera(MonitorFocus.ActiveSlot); if (!((Object)(object)boundCamera == (Object)null) && !((Object)(object)boundCamera.Cam == (Object)null) && boundCamera.AllowsOperatorRotation && (CctvSupportApi.IsMainframeHacked || !boundCamera.IsSecurityActive) && TryReadLookDelta(out var delta2)) { MonitorFocus.NotifyCameraRotated(((Vector2)(ref delta2)).magnitude); boundCamera.PitchOffsetDeg -= delta2.y; boundCamera.YawOffsetDeg += delta2.x; float value = SurveillanceBootstrap.Config.YawClampDeg.Value; boundCamera.YawOffsetDeg = Mathf.Clamp(boundCamera.YawOffsetDeg, 0f - value, value); boundCamera.ApplyOffsets(); if (MonitorFocus.IsStationCameraControlActive) { CCTVStationEvents.RaiseJoystickMoved(delta2); } } } } } } private static bool TryReadRawLook(out Vector2 raw) { //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_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) raw = Vector2.zero; if (_lookAction == null && !_lookActionResolved) { ResolveLookAction(); } if (_lookAction == null) { return false; } raw = _lookAction.ReadValue(); return ((Vector2)(ref raw)).sqrMagnitude >= 0.0064f; } private static bool TryReadLookDelta(out Vector2 delta) { //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_00c5: 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_00d1: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_008b: Unknown result type (might be due to invalid IL or missing references) delta = Vector2.zero; if (!TryReadRawLook(out var raw)) { return false; } float num = 1f; if ((Object)(object)IngamePlayerSettings.Instance != (Object)null && IngamePlayerSettings.Instance.settings != null) { num = IngamePlayerSettings.Instance.settings.lookSensitivity; } float num2 = ((SurveillanceBootstrap.Config?.MouselookSensitivityMul != null) ? SurveillanceBootstrap.Config.MouselookSensitivityMul.Value : 1f); if ((Object)(object)IngamePlayerSettings.Instance != (Object)null) { if (IngamePlayerSettings.Instance.flipCamera) { raw.x = 0f - raw.x; } if (IngamePlayerSettings.Instance.settings != null && IngamePlayerSettings.Instance.settings.invertYAxis) { raw.y *= -1f; } } delta = raw * num * 0.008f * num2; float num3 = 125f * Mathf.Max(Time.unscaledDeltaTime, 1f / 120f); if (((Vector2)(ref delta)).magnitude > num3) { delta = ((Vector2)(ref delta)).normalized * num3; } return ((Vector2)(ref delta)).sqrMagnitude >= 1.6000002E-05f; } private static void ResolveLookAction() { _lookActionResolved = true; try { _lookAction = (((Object)(object)InputSystem.actions != (Object)null) ? InputSystem.actions.FindAction("Look", false) : null); } catch { _lookAction = null; } if (_lookAction == null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] FocusMouselook: vanilla 'Look' InputAction not resolvable — focus-mode mouselook will be inert until next session. Fallback to Mouse.current.delta not yet wired (PLAN verify-on-first-run path)."); } } else { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)"[LethalCCTV] FocusMouselook: 'Look' action resolved."); } } } } internal static class FocusPerfProbe { private sealed class StepStat { public long TotalTicks; public long MaxTicks; public int Calls; } private const float SummaryIntervalSeconds = 5f; private static readonly Dictionary _steps = new Dictionary(24); private static readonly StringBuilder _builder = new StringBuilder(1024); private static float _windowStartedAt = -1f; private static int _frames; private static float _frameTimeSum; internal static void RecordStep(string stepName, long elapsedTicks) { if (!_steps.TryGetValue(stepName, out var value)) { value = new StepStat(); _steps[stepName] = value; } value.TotalTicks += elapsedTicks; value.Calls++; if (elapsedTicks > value.MaxTicks) { value.MaxTicks = elapsedTicks; } } internal static void OnFocusedFrame() { float unscaledTime = Time.unscaledTime; if (_windowStartedAt < 0f) { _windowStartedAt = unscaledTime; } _frames++; _frameTimeSum += Time.unscaledDeltaTime; if (!(unscaledTime - _windowStartedAt < 5f)) { LogSummary(unscaledTime - _windowStartedAt); Reset(); _windowStartedAt = unscaledTime; } } internal static void OnFocusEnded() { Reset(); _windowStartedAt = -1f; } private static void Reset() { _steps.Clear(); _frames = 0; _frameTimeSum = 0f; } private static void LogSummary(float windowSeconds) { if (_frames == 0) { return; } double num = 1000.0 / (double)Stopwatch.Frequency; float num2 = ((_frameTimeSum > 0f) ? ((float)_frames / _frameTimeSum) : 0f); _builder.Length = 0; _builder.Append("[LethalCCTV][FocusPerf] ").Append(_frames).Append(" frames / ") .Append(windowSeconds.ToString("F1")) .Append("s, avg ") .Append(num2.ToString("F1")) .Append(" fps (") .Append((_frameTimeSum * 1000f / (float)_frames).ToString("F1")) .Append(" ms/frame). Mod LateUpdate steps (avg ms/frame | worst single call ms):"); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)_builder.ToString()); } foreach (KeyValuePair step in _steps) { StepStat value = step.Value; double num3 = (double)value.TotalTicks * num / (double)_frames; double num4 = (double)value.MaxTicks * num; if (!(num3 < 0.01) || !(num4 < 0.5)) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV][FocusPerf] {step.Key}: {num3:F3} | {num4:F2} ({value.Calls} calls)"); } } } LogRenderCensus(); } private static void LogRenderCensus() { try { Camera[] allCameras = Camera.allCameras; int num = 0; for (int i = 0; i < allCameras.Length; i++) { if ((Object)(object)allCameras[i] != (Object)null && (Object)(object)allCameras[i].targetTexture != (Object)null) { num++; } } int num2 = 0; int num3 = 0; for (int j = 0; j < 4; j++) { CCTVCamera boundCamera = QuadCameraAssignment.GetBoundCamera(j); if (!((Object)(object)boundCamera == (Object)null) && !((Object)(object)boundCamera.Cam == (Object)null)) { num3++; if (((Behaviour)boundCamera.Cam).enabled) { num2++; } } } ManualCameraRenderer[] array = Object.FindObjectsOfType(); int num4 = 0; int num5 = 0; for (int k = 0; k < array.Length; k++) { if (!((Object)(object)array[k] == (Object)null)) { if (((Behaviour)array[k]).enabled) { num4++; } if ((Object)(object)array[k].cam != (Object)null && ((Behaviour)array[k].cam).enabled) { num5++; } } } _builder.Length = 0; _builder.Append("[LethalCCTV][FocusPerf] render census: enabledCams=").Append(allCameras.Length).Append(" (toRT=") .Append(num) .Append("), cctvBound=") .Append(num3) .Append(" cctvEnabledNow=") .Append(num2) .Append(", MCRs=") .Append(array.Length) .Append(" enabled=") .Append(num4) .Append(" mcrCamsEnabled=") .Append(num5); for (int l = 0; l < allCameras.Length; l++) { if (!((Object)(object)allCameras[l] == (Object)null)) { _builder.Append(" | ").Append(((Object)allCameras[l]).name); if ((Object)(object)allCameras[l].targetTexture != (Object)null) { _builder.Append("->").Append(((Texture)allCameras[l].targetTexture).width).Append('x') .Append(((Texture)allCameras[l].targetTexture).height); } } } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)_builder.ToString()); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogDebug((object)("[LethalCCTV][FocusPerf] render census failed: " + ex.Message)); } } } } internal sealed class HackingOverlay { private sealed class EdgeView { private readonly RectTransform _rect; private readonly Image _image; private bool _visible; internal EdgeView(Transform parent, int index) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0072: 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_00a6: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"Edge_{index:D2}", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent(parent, false); _rect = val.GetComponent(); _rect.anchorMin = new Vector2(0.5f, 0.5f); _rect.anchorMax = new Vector2(0.5f, 0.5f); _rect.pivot = new Vector2(0f, 0.5f); _image = val.GetComponent(); ((Graphic)_image).raycastTarget = false; val.SetActive(false); } internal void Render(Vector2 start, Vector2 end, Color color, float thickness, float alpha) { //IL_0018: 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_001f: 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_0047: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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) _visible = true; ((Component)_rect).gameObject.SetActive(true); Vector2 val = end - start; float num = Mathf.Max(1f, ((Vector2)(ref val)).magnitude); _rect.anchoredPosition = start; _rect.sizeDelta = new Vector2(num, thickness); ((Transform)_rect).localRotation = Quaternion.Euler(0f, 0f, Mathf.Atan2(val.y, val.x) * 57.29578f); ((Graphic)_image).color = new Color(color.r, color.g, color.b, alpha); } internal void Hide() { if (_visible) { ((Component)_rect).gameObject.SetActive(false); _visible = false; } } } private sealed class RouteArrowView { private const float SweepBlendFraction = 0.2f; private readonly RectTransform _rect; private readonly TextMeshProUGUI _text; private bool _visible; internal RouteArrowView(Transform parent, int index, Action registerText) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0072: 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_00a6: 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) GameObject val = new GameObject($"RouteArrow_{index:D2}", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val.transform.SetParent(parent, false); _rect = val.GetComponent(); _rect.anchorMin = new Vector2(0.5f, 0.5f); _rect.anchorMax = new Vector2(0.5f, 0.5f); _rect.pivot = new Vector2(0.5f, 0.5f); _rect.sizeDelta = new Vector2(34f, 26f); _text = val.GetComponent(); ((TMP_Text)_text).text = ">"; ((TMP_Text)_text).alignment = (TextAlignmentOptions)514; ((TMP_Text)_text).fontSize = 16f; ((TMP_Text)_text).fontStyle = (FontStyles)1; ((TMP_Text)_text).enableWordWrapping = false; ((TMP_Text)_text).overflowMode = (TextOverflowModes)0; ((Graphic)_text).raycastTarget = false; registerText?.Invoke(_text); val.SetActive(false); } internal void Render(Vector2 start, Vector2 end, Color color, float alpha, float fontSize, int phaseIndex, float sweep01) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_0037: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) Vector2 val = end - start; float magnitude = ((Vector2)(ref val)).magnitude; if (magnitude <= 0.1f) { Hide(); return; } _visible = true; ((Component)_rect).gameObject.SetActive(true); Vector2 val2 = val / magnitude; float num = Mathf.Min(magnitude * 0.3f, 22f); float num2 = Mathf.Min(magnitude * 0.06f, 5f); float num3 = Mathf.Sin(Time.unscaledTime * 2.6f + (float)phaseIndex * 0.7f) * num2; float num4 = num3; if (sweep01 > 0f) { float num5 = 1f - sweep01; float num6 = Mathf.Lerp(0f - num, num, num5); float num7 = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01(Mathf.Min(num5, 1f - num5) / 0.2f)); num4 = Mathf.Lerp(num3, num6, num7); alpha = Mathf.Lerp(alpha, 1f, num7); fontSize += 3f * num7; } _rect.anchoredPosition = Vector2.Lerp(start, end, 0.5f) + val2 * num4; ((Transform)_rect).localRotation = Quaternion.Euler(0f, 0f, Mathf.Atan2(val.y, val.x) * 57.29578f); ((TMP_Text)_text).fontSize = fontSize; ((Graphic)_text).color = new Color(color.r, color.g, color.b, alpha); } internal void Hide() { if (_visible) { ((Component)_rect).gameObject.SetActive(false); _visible = false; } } } private sealed class NodeView { private const float OriginSize = 30f; private const float TargetSize = 30f; private const float RelaySize = 27f; private const float SelectedGrow = 7f; private const float OriginShapeScale = 0.74f; private const float SelectedBorderWidth = 3.2f; private const float MaxBorderWidth = 5f; private const float RotatePopScale = 0.26f; private readonly RectTransform _rect; private readonly RectTransform _shapeRect; private readonly Image _shapeImage; private readonly Outline _outline; private readonly TextMeshProUGUI _label; private readonly Sprite _discSprite; private bool _visible; internal static float MaxEdgeExtent() { float num = Mathf.Max(30f, Mathf.Max(30f, 27f)) + 7f; float num2 = num * 0.74f * 0.5f * Mathf.Sqrt(2f); float num3 = num * 0.5f; return (Mathf.Max(num2, num3) + 5f) * 1.26f; } internal NodeView(Transform parent, int index, Action registerText, Sprite discSprite) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00e3: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) _discSprite = discSprite; GameObject val = new GameObject($"Node_{index:D2}", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); _rect = val.GetComponent(); _rect.anchorMin = new Vector2(0.5f, 0.5f); _rect.anchorMax = new Vector2(0.5f, 0.5f); _rect.pivot = new Vector2(0.5f, 0.5f); GameObject val2 = new GameObject("Shape", new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Outline) }); val2.transform.SetParent(val.transform, false); _shapeRect = val2.GetComponent(); _shapeRect.anchorMin = new Vector2(0.5f, 0.5f); _shapeRect.anchorMax = new Vector2(0.5f, 0.5f); _shapeRect.pivot = new Vector2(0.5f, 0.5f); _shapeImage = val2.GetComponent(); ((Graphic)_shapeImage).raycastTarget = false; _outline = val2.GetComponent(); ((Shadow)_outline).effectDistance = new Vector2(1.5f, -1.5f); GameObject val3 = new GameObject("Label", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val3.transform.SetParent(val.transform, false); RectTransform component = val3.GetComponent(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; _label = val3.GetComponent(); ((TMP_Text)_label).fontSize = 13.5f; ((TMP_Text)_label).alignment = (TextAlignmentOptions)514; ((Graphic)_label).raycastTarget = false; ((TMP_Text)_label).enableWordWrapping = false; ((TMP_Text)_label).richText = false; ((TMP_Text)_label).fontStyle = (FontStyles)1; registerText?.Invoke(_label); val.SetActive(false); } internal void Render(CctvHackingGame.SignalNode node, Vector2 position, bool selected, bool current, bool completed, bool canRotate, float rotatePop, bool originAlert, Color accent, Color dim) { //IL_0022: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0148: 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_0113: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: 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_01ff: 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_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) if (node != null) { _visible = true; ((Component)_rect).gameObject.SetActive(true); _rect.anchoredPosition = position; float num = (node.IsOrigin ? 30f : (node.IsTarget ? 30f : 27f)); if (selected) { num += 7f; } _rect.sizeDelta = new Vector2(num, num); float num2 = 1f + 0.26f * Mathf.Clamp01(rotatePop); ((Transform)_rect).localScale = new Vector3(num2, num2, 1f); if (node.IsOrigin) { _shapeImage.sprite = null; _shapeRect.sizeDelta = new Vector2(num * 0.74f, num * 0.74f); ((Transform)_shapeRect).localRotation = Quaternion.Euler(0f, 0f, 45f); } else if (node.IsTarget) { _shapeImage.sprite = null; _shapeRect.sizeDelta = new Vector2(num, num); ((Transform)_shapeRect).localRotation = Quaternion.identity; } else { _shapeImage.sprite = _discSprite; _shapeRect.sizeDelta = new Vector2(num, num); ((Transform)_shapeRect).localRotation = Quaternion.identity; } float num3 = 1.8f; float num4 = -1f; Color color = default(Color); Color color2; Color val; string text; if (node.IsOrigin) { color = (current ? ScreenWhiteGreen : accent); color2 = ScreenInk; val = (current ? ScreenWhiteGreen : accent); text = "O"; } else if (node.IsTarget && completed) { ((Color)(ref color))..ctor(ScreenInk.r, ScreenInk.g, ScreenInk.b, 0.88f); color2 = accent; val = dim; num3 = 2.4f; text = "OK"; } else if (node.IsTarget) { color = ScreenCyan; color2 = ScreenInk; val = ScreenCyan; num3 = 3f; text = "T" + node.TargetSlot; } else if (current) { color = ScreenWhiteGreen; color2 = ScreenInk; val = ScreenWhiteGreen; text = "R" + node.Id.ToString("00"); } else { color = ScreenGreenFaint; color2 = (canRotate ? accent : dim); val = (canRotate ? accent : dim); num4 = (canRotate ? 0.75f : 0.55f); text = "R" + node.Id.ToString("00"); } if (selected) { color = ScreenAmber; color2 = ScreenInk; val = ScreenAmber; num3 = 3.2f; num4 = -1f; } float num5 = ((num4 >= 0f) ? num4 : (selected ? 1f : (node.IsTarget ? 0.95f : 0.8f))); if (originAlert) { float num6 = 0.5f + 0.5f * Mathf.Sin(Time.unscaledTime * 6.5f); val = ScreenWhiteGreen; num5 = 1f; num3 = Mathf.Lerp(2.2f, 5f, num6); } ((Graphic)_shapeImage).color = color; ((Shadow)_outline).effectDistance = new Vector2(num3, 0f - num3); ((Shadow)_outline).effectColor = new Color(val.r, val.g, val.b, num5); ((TMP_Text)_label).text = text; ((Graphic)_label).color = color2; } } internal void Hide() { if (_visible) { ((Component)_rect).gameObject.SetActive(false); _visible = false; } } } private readonly struct TerminalStyleRefs { internal readonly TMP_FontAsset Font; internal readonly Material FontMaterial; internal readonly Color Accent; internal readonly Color Dim; internal readonly string SourceDescription; private TerminalStyleRefs(TMP_FontAsset font, Material fontMaterial, Color accent, Color dim, string sourceDescription) { //IL_000f: 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_0016: 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) Font = font; FontMaterial = fontMaterial; Accent = accent; Dim = dim; SourceDescription = sourceDescription; } internal static TerminalStyleRefs Resolve() { //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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: 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) TMP_Text val = null; Terminal val2 = FindShipTerminal(); if ((Object)(object)val2 != (Object)null) { object obj = ReadMember(val2, "inputFieldText"); val = (TMP_Text)(((obj is TMP_Text) ? obj : null) ?? ((object)/*isinst with value type is only supported in some contexts*/)); if ((Object)(object)val == (Object)null) { object obj2 = ReadMember(val2, "screenText"); TMP_InputField val3 = (TMP_InputField)((obj2 is TMP_InputField) ? obj2 : null); if (val3 != null) { val = val3.textComponent; } } } if ((Object)(object)val == (Object)null) { try { HUDManager instance = HUDManager.Instance; if ((Object)(object)instance != (Object)null && instance.controlTipLines != null && instance.controlTipLines.Length != 0) { val = (TMP_Text)(object)instance.controlTipLines[0]; } } catch { val = null; } } if ((Object)(object)val == (Object)null) { try { TMP_FontAsset defaultFontAsset = TMP_Settings.defaultFontAsset; if ((Object)(object)defaultFontAsset != (Object)null) { return new TerminalStyleRefs(defaultFontAsset, null, ScreenGreen, ScreenGreenDim, "fallback TMP_Settings.defaultFontAsset='" + ((Object)defaultFontAsset).name + "'"); } } catch { } return new TerminalStyleRefs(null, null, ScreenGreen, ScreenGreenDim, "fallback built-in TMP style"); } Color val4 = ChooseGreenTerminalColor(((Graphic)val).color); Color dim = default(Color); ((Color)(ref dim))..ctor(val4.r * 0.78f, val4.g * 0.78f, val4.b * 0.78f, 1f); string text = ((Object)val).name ?? ((object)val).GetType().Name; string text2 = (((Object)(object)val.font != (Object)null) ? ((Object)val.font).name : ""); string text3 = (((Object)(object)val.fontSharedMaterial != (Object)null) ? ((Object)val.fontSharedMaterial).name : ""); return new TerminalStyleRefs(val.font, val.fontSharedMaterial, val4, dim, $"source='{text}' font='{text2}' material='{text3}' terminalFound={(Object)(object)val2 != (Object)null}"); } private static Color ChooseGreenTerminalColor(Color sampled) { //IL_0000: 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_0064: 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_0014: 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_0029: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (sampled.g >= sampled.r && sampled.g >= sampled.b && sampled.g > 0.2f) { return new Color(Mathf.Max(sampled.r, 0.08f), Mathf.Max(sampled.g, 0.82f), Mathf.Max(sampled.b, 0.12f), 1f); } return ScreenGreen; } } private readonly struct TerminalStateSnapshot { private readonly bool _exists; private readonly int _instanceId; private readonly string _name; private readonly string _currentNode; private readonly int _groupCredits; private readonly bool _terminalInUse; private readonly int _screenHash; private readonly int _inputHash; private readonly int _topRightHash; private TerminalStateSnapshot(bool exists, int instanceId, string name, string currentNode, int groupCredits, bool terminalInUse, int screenHash, int inputHash, int topRightHash) { _exists = exists; _instanceId = instanceId; _name = name; _currentNode = currentNode; _groupCredits = groupCredits; _terminalInUse = terminalInUse; _screenHash = screenHash; _inputHash = inputHash; _topRightHash = topRightHash; } internal static TerminalStateSnapshot Capture() { Terminal val = FindShipTerminal(); if ((Object)(object)val == (Object)null) { return new TerminalStateSnapshot(exists: false, 0, "", "", 0, terminalInUse: false, 0, 0, 0); } object target = ReadMember(val, "screenText"); object target2 = ReadMember(val, "inputFieldText"); object target3 = ReadMember(val, "topRightText"); object target4 = ReadMember(val, "currentNode"); return new TerminalStateSnapshot(exists: true, ((Object)val).GetInstanceID(), ((Object)val).name ?? "", DescribeObject(target4), ReadInt(ReadMember(val, "groupCredits")), ReadBool(ReadMember(val, "terminalInUse")), StableHash(ReadText(target)), StableHash(ReadText(target2)), StableHash(ReadText(target3))); } internal bool HasChangedFrom(TerminalStateSnapshot other) { if (_exists == other._exists && _instanceId == other._instanceId && string.Equals(_name, other._name, StringComparison.Ordinal) && string.Equals(_currentNode, other._currentNode, StringComparison.Ordinal) && _groupCredits == other._groupCredits && _terminalInUse == other._terminalInUse && _screenHash == other._screenHash && _inputHash == other._inputHash) { return _topRightHash != other._topRightHash; } return true; } internal string Describe() { if (!_exists) { return "{terminal=}"; } return "{terminal='" + _name + "' id=" + _instanceId + " node='" + _currentNode + "' credits=" + _groupCredits + " inUse=" + _terminalInUse + " textHashes=" + _screenHash + "/" + _inputHash + "/" + _topRightHash + "}"; } private static string ReadText(object target) { if (target == null) { return string.Empty; } TMP_InputField val = (TMP_InputField)((target is TMP_InputField) ? target : null); if (val != null) { return val.text ?? string.Empty; } TMP_Text val2 = (TMP_Text)((target is TMP_Text) ? target : null); if (val2 != null) { return val2.text ?? string.Empty; } return (ReadMember(target, "text") as string) ?? string.Empty; } private static int ReadInt(object value) { if (value is int) { return (int)value; } if (value is short) { return (short)value; } if (value is long num) { return (int)num; } return 0; } private static bool ReadBool(object value) { bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private static string DescribeObject(object target) { if (target == null) { return ""; } Object val = (Object)((target is Object) ? target : null); if (val != null) { return (val.name ?? ((object)val).GetType().Name) + "#" + val.GetInstanceID(); } return target.GetType().Name + "#" + target.GetHashCode(); } private static int StableHash(string text) { int num = 17; if (text != null) { for (int i = 0; i < text.Length; i++) { num = num * 31 + text[i]; } } return num; } } private const float DesignHeight = 356f; private const float ContentInset = 22f; private const float StatusColumnFraction = 0.566f; private const float TargetColumnFraction = 0.509f; private const float LogColumnFraction = 0.308f; private const float LogColumnMinWidth = 168f; private const float LogColumnMaxWidth = 260f; private const float LogColumnTextInset = 20f; private const float GraphLeft = 30f; private const float GraphHeight = 208f; private const float GraphTop = -102f; private const float BootDurationSeconds = 1.45f; private const float BootSkipArmSeconds = 0.16f; private const int MaxLogLines = 4; private const int MaxNodeViews = 12; private const int MaxEdgeViews = 18; private const float GraphSourceFallbackMinX = 0.07f; private const float GraphSourceFallbackMaxX = 0.91f; private const float GraphSourceFallbackMinY = 0.18f; private const float GraphSourceFallbackMaxY = 0.82f; private const float MinGraphSourceSpan = 0.05f; private static readonly float NodeEdgePadding = NodeView.MaxEdgeExtent(); private const float RotateFeedbackSeconds = 0.34f; private const string ObjectiveLine = "ROUTE THE PULSE FROM ORIGIN TO ALL TARGETS"; private static readonly Color ScreenBlack = new Color(0.003f, 0.012f, 0.006f, 0.92f); private static readonly Color ScreenGreen = new Color(0.16f, 1f, 0.34f, 1f); private static readonly Color ScreenGreenDim = new Color(0.16f, 0.78f, 0.34f, 1f); private static readonly Color ScreenGreenFaint = new Color(0.04f, 0.22f, 0.1f, 1f); private static readonly Color ScreenAmber = new Color(0.92f, 0.82f, 0.3f, 1f); private static readonly Color ScreenCyan = new Color(0.18f, 0.86f, 1f, 1f); private static readonly Color ScreenRed = new Color(1f, 0.28f, 0.2f, 1f); private static readonly Color ScreenWhiteGreen = new Color(0.72f, 1f, 0.72f, 1f); private static readonly Color ScreenInk = new Color(0.012f, 0.045f, 0.02f, 1f); private static readonly string[] BootLines = new string[5] { "> run splice --target mainframe", "> carrier: cctv monitor feed", "> handshake: relay map", "> trace guard: armed", "> input: arrows/enter" }; private Transform _parent; private readonly List _textElements = new List(24); private readonly List _resultLog = new List(4); private GameObject _root; private RectTransform _rootRect; private RectTransform _panelRect; private RectTransform _graphRect; private RectTransform _frameTopRect; private RectTransform _frameBottomRect; private RectTransform _frameLeftRect; private RectTransform _frameRightRect; private RectTransform _logFrameRect; private GameObject _graphRoot; private RectTransform _traceBarBackRect; private RectTransform _traceBarFillRect; private Image _traceBarFillImage; private TextMeshProUGUI _objectiveText; private TextMeshProUGUI _titleText; private TextMeshProUGUI _traceText; private TextMeshProUGUI _targetText; private TextMeshProUGUI _statusText; private TextMeshProUGUI _actionText; private TextMeshProUGUI _logText; private TextMeshProUGUI _helpText; private TextMeshProUGUI _bootText; private EdgeView[] _edgeViews; private RouteArrowView[] _routeArrowViews; private NodeView[] _nodeViews; private Image _pulseImage; private Texture2D _scanlineTexture; private Texture2D _vignetteTexture; private Sprite _scanlineSprite; private Sprite _vignetteSprite; private Material _terminalFontMaterial; private Color _accentColor = ScreenGreen; private Color _dimColor = ScreenGreenDim; private float _designWidth = 680f; private int _sessionSeed; private string _targetDisplayName = "MAINFRAME"; private string _lastStashCodeLine; private bool _failureNotified; private int _openedFrame; private float _inputArmedAt; private bool _inputArmedLogSent; private int _lastActionInputFrame = -1; private int _lastRotatedNodeId = -1; private float _rotateFlashUntil; private float _solvedAt; private bool _solvedConsumed; private float _bootStartedAt; private float _bootUntil; private bool _gameViewShown; private TerminalStateSnapshot _terminalBeforeOpen; private CctvHackingGame _game; private Component _mainframeComponent; private bool _isOpen; private Vector2 _graphSourceMin = new Vector2(0.07f, 0.18f); private Vector2 _graphSourceMax = new Vector2(0.91f, 0.82f); private static Texture2D s_discTexture; private static Sprite s_discSprite; private static Sprite DiscSprite { get { //IL_0044: 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) if ((Object)(object)s_discSprite != (Object)null) { return s_discSprite; } s_discTexture = BuildDiscTexture(64); s_discSprite = Sprite.Create(s_discTexture, new Rect(0f, 0f, (float)((Texture)s_discTexture).width, (float)((Texture)s_discTexture).height), new Vector2(0.5f, 0.5f)); return s_discSprite; } } internal Action KeystrokeRequested { get; set; } internal bool IsOpen => _isOpen; internal Component ActiveMainframe => _mainframeComponent; internal GameObject RootObject { get { EnsureBuilt(); return _root; } } internal bool ConsumeSolved() { if (!_isOpen || _game == null || !_game.Solved || _solvedConsumed) { return false; } if (_solvedAt <= 0f || Time.unscaledTime < _solvedAt + 1.15f) { return false; } _solvedConsumed = true; return true; } internal HackingOverlay(Transform parent) { //IL_001a: 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) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) _parent = parent; } internal void EnsureBuilt() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root != (Object)null)) { _root = new GameObject("LethalCCTV_CCTVFocusSignalSplice"); _root.transform.SetParent(_parent, false); CanvasGroup obj = _root.AddComponent(); obj.blocksRaycasts = true; obj.interactable = true; _rootRect = _root.AddComponent(); _rootRect.anchorMin = new Vector2(0.5f, 0.5f); _rootRect.anchorMax = new Vector2(0.5f, 0.5f); _rootRect.pivot = new Vector2(0.5f, 0.5f); _rootRect.anchoredPosition = Vector2.zero; _rootRect.sizeDelta = new Vector2(_designWidth, 356f); Image obj2 = ((Component)CreateRect(_root.transform, "CRTBackdrop", Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f))).gameObject.AddComponent(); ((Graphic)obj2).color = new Color(0f, 0f, 0f, 0.5f); ((Graphic)obj2).raycastTarget = false; _panelRect = CreateRect(_root.transform, "TerminalPanel", Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f)); Image obj3 = ((Component)_panelRect).gameObject.AddComponent(); ((Graphic)obj3).color = ScreenBlack; ((Graphic)obj3).raycastTarget = false; CreateCrtFrame(_panelRect); CreateHeader(_panelRect); CreateGraph(_panelRect); CreateLog(_panelRect); CreateCrtOverlays(_root.transform); ApplyLayout(); _root.SetActive(false); } } internal void SetDock(Vector2 anchoredPosition, Vector2 sizeDelta) { //IL_001b: 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_0048: Unknown result type (might be due to invalid IL or missing references) EnsureBuilt(); if (!((Object)(object)_rootRect == (Object)null)) { if (CrtDockLayout.TryResolveDock(_rootRect, anchoredPosition, sizeDelta, _designWidth, out var designWidth, out var scale)) { _designWidth = designWidth; ApplyLayout(); } ((Transform)_rootRect).localScale = new Vector3(scale, scale, 1f); } } private void ApplyLayout() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_016e: 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_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_rootRect == (Object)null)) { float designWidth = _designWidth; float num = 22f; float num2 = designWidth - 22f; float num3 = Mathf.Max(120f, num2 - num); _rootRect.sizeDelta = new Vector2(designWidth, 356f); CrtDockLayout.ResizeFrame(designWidth, _frameTopRect, _frameBottomRect, _frameLeftRect, _frameRightRect); float num4 = num + num3 * 0.566f; float num5 = num + num3 * 0.509f; if ((Object)(object)_titleText != (Object)null) { ((TMP_Text)_titleText).rectTransform.sizeDelta = new Vector2(Mathf.Max(120f, num4 - num), 44f); } if ((Object)(object)_traceText != (Object)null) { ((TMP_Text)_traceText).rectTransform.sizeDelta = new Vector2(Mathf.Max(90f, num5 - num), 23f); } if ((Object)(object)_statusText != (Object)null) { ((TMP_Text)_statusText).rectTransform.anchoredPosition = new Vector2(num4, -20f); ((TMP_Text)_statusText).rectTransform.sizeDelta = new Vector2(num2 - num4, 25f); } if ((Object)(object)_targetText != (Object)null) { ((TMP_Text)_targetText).rectTransform.anchoredPosition = new Vector2(num5, -56f); ((TMP_Text)_targetText).rectTransform.sizeDelta = new Vector2(num2 - num5, 23f); } float num6 = Mathf.Max(90f, num5 - num - 10f); if ((Object)(object)_traceBarBackRect != (Object)null) { _traceBarBackRect.anchoredPosition = new Vector2(num, -76f); _traceBarBackRect.sizeDelta = new Vector2(num6, 6f); } if ((Object)(object)_traceBarFillRect != (Object)null) { _traceBarFillRect.sizeDelta = new Vector2(num6 * CurrentTraceNormalized(), 6f); } if ((Object)(object)_objectiveText != (Object)null) { ((TMP_Text)_objectiveText).rectTransform.sizeDelta = new Vector2(num3, 17f); } float num7 = Mathf.Clamp(num3 * 0.308f, 168f, 260f); num7 = Mathf.Min(num7, num3 - 140f); float num8 = num2 - num7; if ((Object)(object)_logFrameRect != (Object)null) { _logFrameRect.anchoredPosition = new Vector2(num8, -102f); _logFrameRect.sizeDelta = new Vector2(num7, 208f); } if ((Object)(object)_actionText != (Object)null) { ((TMP_Text)_actionText).rectTransform.sizeDelta = new Vector2(num7 - 20f, 82f); } if ((Object)(object)_logText != (Object)null) { ((TMP_Text)_logText).rectTransform.sizeDelta = new Vector2(num7 - 20f, 118f); } float num9 = num8 - 2f; float num10 = Mathf.Max(120f, num9 - 30f); if ((Object)(object)_graphRect != (Object)null) { _graphRect.anchoredPosition = new Vector2(30f + num10 * 0.5f, -206f); _graphRect.sizeDelta = new Vector2(num10, 208f); } if ((Object)(object)_bootText != (Object)null) { ((TMP_Text)_bootText).rectTransform.sizeDelta = new Vector2(Mathf.Max(160f, num9 - 50f), 190f); } if ((Object)(object)_helpText != (Object)null) { ((TMP_Text)_helpText).rectTransform.sizeDelta = new Vector2(num3, 20f); } } } internal void SetParent(Transform parent) { if (!((Object)(object)parent == (Object)null)) { EnsureBuilt(); _parent = parent; if ((Object)(object)_root.transform.parent != (Object)(object)parent) { _root.transform.SetParent(parent, false); } _root.transform.SetAsLastSibling(); } } internal void Open(Component mainframeComponent) { EnsureBuilt(); if (!((Object)(object)mainframeComponent == (Object)null)) { _terminalBeforeOpen = TerminalStateSnapshot.Capture(); ApplyTerminalStyleRefs(TerminalStyleRefs.Resolve()); _mainframeComponent = mainframeComponent; _targetDisplayName = ResolveTargetDisplayName(mainframeComponent); _sessionSeed = Time.frameCount ^ (((Object)mainframeComponent).GetInstanceID() * 397); _game = new CctvHackingGame(_sessionSeed); ResolveGraphSourceBounds(); _failureNotified = false; _solvedAt = 0f; _solvedConsumed = false; _lastStashCodeLine = null; _openedFrame = Time.frameCount; _bootStartedAt = Time.unscaledTime; _bootUntil = _bootStartedAt + 1.45f; _inputArmedAt = _bootUntil + 0.05f; _inputArmedLogSent = false; _lastActionInputFrame = -1; _lastRotatedNodeId = -1; _rotateFlashUntil = 0f; _gameViewShown = false; ResetResultLog(); _isOpen = true; _root.SetActive(true); SetGameViewVisible(visible: false); Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; RefreshHeader(); RefreshBootText(); TerminalStateSnapshot terminalStateSnapshot = TerminalStateSnapshot.Capture(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][SignalSplice] Opened CCTV-focus signal splice " + $"target='{_targetDisplayName}' component='{((object)mainframeComponent).GetType().FullName}' instance={((Object)mainframeComponent).GetInstanceID()} " + $"seed={_sessionSeed} difficulty={_game.DifficultyLabel} risk='{_game.MoonRiskLabel}' targets={_game.RequiredTargetCount} " + $"inputArmedAt={_inputArmedAt:0.000} shipTerminalChanged={terminalStateSnapshot.HasChangedFrom(_terminalBeforeOpen)} " + "before=" + _terminalBeforeOpen.Describe() + " after=" + terminalStateSnapshot.Describe() + ".")); } } } internal void Close() { Close("unspecified"); } internal void Close(string reason) { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } if (_isOpen) { TerminalStateSnapshot terminalStateSnapshot = TerminalStateSnapshot.Capture(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][SignalSplice] Closed CCTV-focus signal splice " + string.Format("target='{0}' reason='{1}' shipTerminalChangedSinceOpen={2} ", _targetDisplayName, reason ?? "unspecified", terminalStateSnapshot.HasChangedFrom(_terminalBeforeOpen)) + "terminalNow=" + terminalStateSnapshot.Describe() + ".")); } } _isOpen = false; _game = null; _mainframeComponent = null; _targetDisplayName = "MAINFRAME"; _resultLog.Clear(); _inputArmedLogSent = false; _lastActionInputFrame = -1; _lastRotatedNodeId = -1; _rotateFlashUntil = 0f; _gameViewShown = false; Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; } internal void Tick() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (!_isOpen) { return; } if (IsBooting()) { HandleBootSkipInput(); RefreshBootText(); RefreshHeader(); return; } if (!_gameViewShown) { _gameViewShown = true; SetGameViewVisible(visible: true); SetStatus("PICK A RELAY", _accentColor); AppendLog(">Splice ready."); } if (IsInputArmed()) { HandleKeyboardPollingFallback(); } if (_game != null && !_game.Solved && !_game.Locked) { HandleGameResult(_game.Update(Time.unscaledDeltaTime)); } RefreshHeader(); RefreshGraph(); } internal bool ConsumeEscapeIfOpen() { if (!_isOpen) { return false; } Keyboard current = Keyboard.current; if (current != null && ((ButtonControl)current.escapeKey).wasPressedThisFrame) { NotifyKeystroke(0, 0.75f, "keyboard-escape"); Close("escape"); return true; } return false; } internal bool NavigateUp(string source) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return TryNavigate(Vector2.up, source ?? "unknown"); } internal bool NavigateDown(string source) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return TryNavigate(Vector2.down, source ?? "unknown"); } internal bool NavigateLeft(string source) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return TryNavigate(Vector2.left, source ?? "unknown"); } internal bool NavigateRight(string source) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return TryNavigate(Vector2.right, source ?? "unknown"); } internal bool Submit(string source) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) if (!_isOpen) { return false; } if (IsBooting()) { return RequestBootSkip(source ?? "submit"); } if (!IsInputArmed()) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][SignalSplice] Ignored submit before input armed source='" + source + "' target='" + _targetDisplayName + "'.")); } return false; } if (_game == null || _game.Solved || _game.Locked) { SetStatus((_game != null && _game.Solved) ? "ACCESS GRANTED" : "TRACE LOCK", (_game != null && _game.Solved) ? _accentColor : ScreenRed); return false; } _lastActionInputFrame = Time.frameCount; NotifyKeystroke(5, 1f, source ?? "submit"); bool flag = _game.RotateSelectedRelay(); if (flag) { CctvHackingGame.SignalNode node = _game.GetNode(_game.SelectedNodeId); int num = node?.GetActiveNeighbor() ?? (-1); _lastRotatedNodeId = _game.SelectedNodeId; _rotateFlashUntil = Time.unscaledTime + 0.34f; SetStatus(FormatNodeShort(_game.SelectedNodeId) + " NOW AIMS " + FormatNodeShort(num), _accentColor); AppendLog(">" + FormatNodeLabel(node) + " now aims " + FormatNodeLabel(_game.GetNode(num)) + "."); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV][SignalSplice] Rotate source='{source}' target='{_targetDisplayName}' node={_game.SelectedNodeId} active={num}."); } } else { SetStatus("FIXED - CANNOT AIM", ScreenRed); AppendLog(">Selected node is fixed."); } RefreshActionText(); RefreshGraph(); RefreshHeader(); return flag; } private void CreateCrtFrame(RectTransform parent) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) _frameTopRect = CreateLine((Transform)(object)parent, "FrameTop", new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0.5f, 1f)); _frameTopRect.anchoredPosition = new Vector2(0f, -8f); _frameBottomRect = CreateLine((Transform)(object)parent, "FrameBottom", new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f)); _frameBottomRect.anchoredPosition = new Vector2(0f, 8f); _frameLeftRect = CreateLine((Transform)(object)parent, "FrameLeft", new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(0f, 0.5f)); _frameLeftRect.anchoredPosition = new Vector2(10f, 0f); _frameRightRect = CreateLine((Transform)(object)parent, "FrameRight", new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(1f, 0.5f)); _frameRightRect.anchoredPosition = new Vector2(-10f, 0f); } private void CreateHeader(RectTransform parent) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_0146: 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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: 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_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) _titleText = CreateTerminalText((Transform)(object)parent, "Header", "CCTV MAINFRAME SPLICE\nUPLINK BOOT", 16.5f, (TextAlignmentOptions)257, ScreenGreen, new Vector2(22f, -12f), Vector2.zero); _statusText = CreateTerminalText((Transform)(object)parent, "Status", "LINKING", 15f, (TextAlignmentOptions)260, ScreenGreen, Vector2.zero, Vector2.zero); _traceText = CreateTerminalText((Transform)(object)parent, "Trace", "TRACE 00%", 15f, (TextAlignmentOptions)257, ScreenGreen, new Vector2(22f, -56f), Vector2.zero); _targetText = CreateTerminalText((Transform)(object)parent, "Targets", "", 14f, (TextAlignmentOptions)260, ScreenGreen, Vector2.zero, Vector2.zero); _traceBarBackRect = CreateRect((Transform)(object)parent, "TraceBarBack", new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(0f, 1f)); Image obj = ((Component)_traceBarBackRect).gameObject.AddComponent(); ((Graphic)obj).color = new Color(ScreenGreen.r, ScreenGreen.g, ScreenGreen.b, 0.16f); ((Graphic)obj).raycastTarget = false; _traceBarFillRect = CreateRect((Transform)(object)_traceBarBackRect, "TraceBarFill", new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(0f, 0.5f)); _traceBarFillRect.anchoredPosition = Vector2.zero; _traceBarFillImage = ((Component)_traceBarFillRect).gameObject.AddComponent(); ((Graphic)_traceBarFillImage).color = ScreenGreen; ((Graphic)_traceBarFillImage).raycastTarget = false; _objectiveText = CreateTerminalText((Transform)(object)parent, "Objective", "ROUTE THE PULSE FROM ORIGIN TO ALL TARGETS", 12.5f, (TextAlignmentOptions)257, ScreenGreenDim, new Vector2(22f, -87f), Vector2.zero); ((TMP_Text)_objectiveText).enableAutoSizing = true; ((TMP_Text)_objectiveText).fontSizeMin = 10.5f; ((TMP_Text)_objectiveText).fontSizeMax = 12.5f; } private void CreateGraph(RectTransform parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0043: 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_0077: 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_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Expected O, but got Unknown //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_020b: 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_0260: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) _graphRoot = new GameObject("SignalGraph"); _graphRoot.transform.SetParent((Transform)(object)parent, false); _graphRect = _graphRoot.AddComponent(); _graphRect.anchorMin = new Vector2(0f, 1f); _graphRect.anchorMax = new Vector2(0f, 1f); _graphRect.pivot = new Vector2(0.5f, 0.5f); Image obj = _graphRoot.AddComponent(); ((Graphic)obj).color = new Color(0f, 0.08f, 0.025f, 0.16f); ((Graphic)obj).raycastTarget = false; _edgeViews = new EdgeView[18]; for (int i = 0; i < _edgeViews.Length; i++) { _edgeViews[i] = new EdgeView((Transform)(object)_graphRect, i); } _routeArrowViews = new RouteArrowView[12]; for (int j = 0; j < _routeArrowViews.Length; j++) { _routeArrowViews[j] = new RouteArrowView((Transform)(object)_graphRect, j, RegisterText); } Sprite discSprite = DiscSprite; _nodeViews = new NodeView[12]; for (int k = 0; k < _nodeViews.Length; k++) { _nodeViews[k] = new NodeView((Transform)(object)_graphRect, k, RegisterText, discSprite); } GameObject val = new GameObject("Pulse", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)_graphRect, false); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(13f, 13f); _pulseImage = val.GetComponent(); _pulseImage.sprite = discSprite; ((Graphic)_pulseImage).color = ScreenWhiteGreen; ((Graphic)_pulseImage).raycastTarget = false; _bootText = CreateTerminalText((Transform)(object)parent, "BootText", "", 15.5f, (TextAlignmentOptions)257, ScreenGreen, new Vector2(44f, -112f), Vector2.zero); ((TMP_Text)_bootText).lineSpacing = 5f; } private void CreateLog(RectTransform parent) { //IL_0010: 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) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (_logFrameRect = CreateRect((Transform)(object)parent, "SignalLogFrame", new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(0f, 1f))); Image obj = ((Component)val).gameObject.AddComponent(); ((Graphic)obj).color = new Color(0.005f, 0.035f, 0.012f, 0.5f); ((Graphic)obj).raycastTarget = false; _actionText = CreateTerminalText((Transform)(object)val, "SelectedRelay", "", 14f, (TextAlignmentOptions)257, ScreenAmber, new Vector2(10f, -8f), Vector2.zero); ((TMP_Text)_actionText).lineSpacing = 3f; _logText = CreateTerminalText((Transform)(object)val, "SignalLog", "", 12f, (TextAlignmentOptions)257, ScreenGreen, new Vector2(10f, -96f), Vector2.zero); ((TMP_Text)_logText).lineSpacing = 1.5f; ((TMP_Text)_logText).enableWordWrapping = true; ((TMP_Text)_logText).overflowMode = (TextOverflowModes)3; _helpText = CreateTerminalText((Transform)(object)parent, "Help", "LINKING...", 13f, (TextAlignmentOptions)514, ScreenGreenDim, new Vector2(22f, -330f), Vector2.zero); } private void CreateCrtOverlays(Transform parent) { //IL_0006: 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_001a: 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_0087: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00e7: 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_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_016a: 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) Image obj = ((Component)CreateRect(parent, "PhosphorGlow", Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f))).gameObject.AddComponent(); ((Graphic)obj).color = new Color(0f, 0.55f, 0.18f, 0.045f); ((Graphic)obj).raycastTarget = false; _scanlineTexture = BuildScanlineTexture(); _scanlineSprite = Sprite.Create(_scanlineTexture, new Rect(0f, 0f, (float)((Texture)_scanlineTexture).width, (float)((Texture)_scanlineTexture).height), new Vector2(0.5f, 0.5f)); Image obj2 = ((Component)CreateRect(parent, "Scanlines", Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f))).gameObject.AddComponent(); obj2.sprite = _scanlineSprite; obj2.type = (Type)2; ((Graphic)obj2).color = Color.white; ((Graphic)obj2).raycastTarget = false; _vignetteTexture = BuildVignetteTexture(128, 72); _vignetteSprite = Sprite.Create(_vignetteTexture, new Rect(0f, 0f, (float)((Texture)_vignetteTexture).width, (float)((Texture)_vignetteTexture).height), new Vector2(0.5f, 0.5f)); Image obj3 = ((Component)CreateRect(parent, "Vignette", Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f))).gameObject.AddComponent(); obj3.sprite = _vignetteSprite; ((Graphic)obj3).color = Color.white; ((Graphic)obj3).raycastTarget = false; } private void HandleKeyboardPollingFallback() { if (Time.frameCount == _lastActionInputFrame) { return; } Keyboard current = Keyboard.current; if (current != null) { if (((ButtonControl)current.upArrowKey).wasPressedThisFrame) { NavigateUp("keyboard-up"); } else if (((ButtonControl)current.downArrowKey).wasPressedThisFrame) { NavigateDown("keyboard-down"); } else if (((ButtonControl)current.leftArrowKey).wasPressedThisFrame) { NavigateLeft("keyboard-left"); } else if (((ButtonControl)current.rightArrowKey).wasPressedThisFrame) { NavigateRight("keyboard-right"); } else if (((ButtonControl)current.enterKey).wasPressedThisFrame || ((ButtonControl)current.numpadEnterKey).wasPressedThisFrame) { Submit("keyboard-enter"); } } } private bool TryNavigate(Vector2 direction, string source) { //IL_00cd: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_018a: 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 (!_isOpen) { return false; } if (!IsInputArmed()) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][SignalSplice] Ignored navigate before input armed source='" + source + "' target='" + _targetDisplayName + "'.")); } return false; } if (_game == null || _game.Solved || _game.Locked) { SetStatus((_game != null && _game.Solved) ? "ACCESS GRANTED" : "TRACE LOCK", (_game != null && _game.Solved) ? _accentColor : ScreenRed); return false; } _lastActionInputFrame = Time.frameCount; NotifyKeystroke(FingerForDirection(direction), 0.82f, source ?? "navigate"); bool num = _game.MoveSelection(direction); if (num) { SetStatus(string.Concat(str3: FormatNodeShort(GetNextNeighborId(_game.GetNode(_game.SelectedNodeId))), str0: "ENTER AIMS ", str1: FormatNodeShort(_game.SelectedNodeId), str2: ">"), ScreenAmber); RefreshActionText(); RefreshGraph(); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV][SignalSplice] Navigate source='{source}' target='{_targetDisplayName}' selected={_game.SelectedNodeId}."); return num; } return num; } SetStatus("NO RELAY THAT WAY", ScreenRed); return num; } private void NotifyKeystroke(int fingerIndex, float strength, string source) { try { KeystrokeRequested?.Invoke(fingerIndex, Mathf.Clamp01(strength), source ?? "unknown"); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV][SignalSplice] Keystroke callback failed: " + ex.Message)); } } } private static int FingerForDirection(Vector2 direction) { //IL_0000: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (direction.x < -0.5f) { return 1; } if (direction.x > 0.5f) { return 4; } if (direction.y > 0.5f) { return 2; } if (direction.y < -0.5f) { return 3; } return 0; } private void HandleGameResult(SignalSpliceUpdateResult result) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_013b: Unknown result type (might be due to invalid IL or missing references) if (_game == null) { return; } switch (result) { case SignalSpliceUpdateResult.TargetHit: MainframeAudio.Current?.PlayHackProgress(); SetStatus(_game.MustReturnToOrigin ? "RETURN TO ORIGIN" : "TARGET LINKED", _game.MustReturnToOrigin ? ScreenWhiteGreen : _accentColor); AppendLog($">Target {_game.CompletedTargetCount}/{_game.RequiredTargetCount} ack."); if (_game.MustReturnToOrigin) { AppendLog(">Return to origin."); } break; case SignalSpliceUpdateResult.ReturnedToOrigin: SetStatus("ORIGIN LIVE", _accentColor); break; case SignalSpliceUpdateResult.TraceLocked: MainframeAudio.Current?.PlayHackFail(); TryNotifyMainframeFailure(); SetStatus("TRACE LOCK", ScreenRed); AppendLog(">Trace locked."); AppendLog(">Mainframe alarmed."); break; case SignalSpliceUpdateResult.Solved: if (_solvedAt <= 0f) { MainframeAudio.Current?.PlayHackSuccess(); TryMarkMainframeHacked(); _solvedAt = Time.unscaledTime; SetStatus("ACCESS GRANTED", _accentColor); AppendLog(">Origin handshake."); AppendLog(">Access granted."); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][SignalSplice] Solved target='" + _targetDisplayName + "' difficulty=" + _game.DifficultyLabel + ".")); } } break; } } private void TryMarkMainframeHacked() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_mainframeComponent == (Object)null) { return; } bool flag = false; try { if (_mainframeComponent is MainframeSupport mainframeSupport) { mainframeSupport.MarkHackedServerRpc(); flag = true; } else { MethodInfo method = ((object)_mainframeComponent).GetType().GetMethod("MarkHackedServerRpc", BindingFlags.Instance | BindingFlags.Public); if (method != null) { method.Invoke(_mainframeComponent, new object[1] { (object)default(ServerRpcParams) }); flag = true; } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][SignalSplice] Hack success RPC failed for target='" + _targetDisplayName + "': " + ex.Message)); } } ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV][SignalSplice] Hack success path target='{_targetDisplayName}' invoked={flag}."); } } private void TryNotifyMainframeFailure() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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) if (_failureNotified || (Object)(object)_mainframeComponent == (Object)null) { return; } _failureNotified = true; bool flag = false; try { if (_mainframeComponent is MainframeSupport mainframeSupport) { mainframeSupport.MarkLockoutServerRpc(); flag = true; } else { MethodInfo method = ((object)_mainframeComponent).GetType().GetMethod("MarkLockoutServerRpc", BindingFlags.Instance | BindingFlags.Public); if (method != null) { method.Invoke(_mainframeComponent, new object[2] { 60f, (object)default(ServerRpcParams) }); flag = true; } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][SignalSplice] Hack failure RPC failed for target='" + _targetDisplayName + "': " + ex.Message)); } } ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV][SignalSplice] Hack failure/lockout path target='{_targetDisplayName}' invoked={flag}."); } } private void RefreshHeader() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0074: 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_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) if (_game == null) { return; } bool flag = IsBooting(); if ((Object)(object)_titleText != (Object)null) { ((TMP_Text)_titleText).text = (flag ? "CCTV MAINFRAME SPLICE\nUPLINK BOOT" : ("CCTV MAINFRAME SPLICE\n" + _targetDisplayName)); } float traceNormalized = _game.TraceNormalized; Color color = ((traceNormalized >= 0.82f) ? ScreenRed : Color.Lerp(_accentColor, ScreenRed, Mathf.Clamp01(traceNormalized / 0.82f) * 0.85f)); if ((Object)(object)_traceText != (Object)null) { int num = Mathf.RoundToInt(traceNormalized * 100f); ((TMP_Text)_traceText).text = ((traceNormalized >= 0.82f) ? $"TRACE {num:00}% !" : $"TRACE {num:00}%"); ((Graphic)_traceText).color = color; } if ((Object)(object)_traceBarFillRect != (Object)null && (Object)(object)_traceBarBackRect != (Object)null) { _traceBarFillRect.sizeDelta = new Vector2(_traceBarBackRect.sizeDelta.x * Mathf.Clamp01(traceNormalized), 6f); if ((Object)(object)_traceBarFillImage != (Object)null) { ((Graphic)_traceBarFillImage).color = color; } } if ((Object)(object)_targetText != (Object)null) { ((TMP_Text)_targetText).text = BuildGoalSummary() + " " + _game.DifficultyLabel; ((Graphic)_targetText).color = _accentColor; } if ((Object)(object)_objectiveText != (Object)null) { bool flag2 = IsReturnPhase(); ((TMP_Text)_objectiveText).text = (flag2 ? "ALL TARGETS LINKED - RETURN THE PULSE TO ORIGIN (O)" : "ROUTE THE PULSE FROM ORIGIN TO ALL TARGETS"); ((Graphic)_objectiveText).color = (flag2 ? ScreenWhiteGreen : _dimColor); } if (_game.Solved) { SetStatus("ACCESS GRANTED", _accentColor); } else if (_game.Locked) { SetStatus("TRACE LOCK", ScreenRed); } if (CctvSupportApi.IsMainframeHacked) { string text = BuildStashCodeLogLine(); if (!string.IsNullOrEmpty(text) && !string.Equals(text, _lastStashCodeLine, StringComparison.Ordinal)) { _lastStashCodeLine = text; AppendLog(text); } } RefreshActionText(); } private void RefreshActionText() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_actionText == (Object)null) { return; } if (_game == null || !_gameViewShown) { ((TMP_Text)_actionText).text = "BOOTING\nWAIT FOR LINK"; ((Graphic)_actionText).color = _dimColor; return; } if (_game.Solved) { ((TMP_Text)_actionText).text = "ACCESS GRANTED\nOPENING CONTROL"; ((Graphic)_actionText).color = _accentColor; return; } if (_game.Locked) { ((TMP_Text)_actionText).text = "TRACE LOCKED\nLINK FAILED"; ((Graphic)_actionText).color = ScreenRed; return; } CctvHackingGame.SignalNode node = _game.GetNode(_game.SelectedNodeId); if (node == null) { ((TMP_Text)_actionText).text = "NO RELAY\nARROWS SELECT"; ((Graphic)_actionText).color = ScreenRed; return; } int activeNeighbor = node.GetActiveNeighbor(); int nextNeighborId = GetNextNeighborId(node); if (!_game.CanRotateNode(node.Id)) { ((TMP_Text)_actionText).text = "SELECTED " + FormatNodeLabel(node) + "\nFIXED - CANNOT AIM\n" + BuildGoalSummary(); ((Graphic)_actionText).color = ScreenRed; return; } ((TMP_Text)_actionText).text = "SELECTED " + FormatNodeLabel(node) + "\nAIMS AT " + FormatNodeLabel(_game.GetNode(activeNeighbor)) + "\nENTER AIMS " + FormatNodeLabel(_game.GetNode(nextNeighborId)); ((Graphic)_actionText).color = ScreenAmber; } private void RefreshGraph() { //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_010e: 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_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_0339: 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_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) if (_game == null || (Object)(object)_graphRect == (Object)null || !_gameViewShown) { return; } int num = ((_game.Edges != null) ? _game.Edges.Count : 0); for (int i = 0; i < _edgeViews.Length; i++) { if (i >= num) { _edgeViews[i].Hide(); continue; } SignalEdge signalEdge = _game.Edges[i]; CctvHackingGame.SignalNode node = _game.GetNode(signalEdge.From); CctvHackingGame.SignalNode node2 = _game.GetNode(signalEdge.To); if (node == null || node2 == null) { _edgeViews[i].Hide(); continue; } bool flag = _game.IsCurrentSegment(signalEdge.From, signalEdge.To); bool flag2 = IsSelectedActiveEdge(signalEdge.From, signalEdge.To); _edgeViews[i].Render(ToGraphLocal(node.Position), ToGraphLocal(node2.Position), flag2 ? ScreenAmber : (flag ? ScreenWhiteGreen : _accentColor), flag2 ? 6.2f : (flag ? 5f : 3.5f), flag2 ? 1f : (flag ? 0.96f : 0.65f)); } RefreshRouteArrows(); int num2 = ((_game.Nodes != null) ? _game.Nodes.Count : 0); for (int j = 0; j < _nodeViews.Length; j++) { if (j >= num2 || _game.Nodes[j] == null) { _nodeViews[j].Hide(); continue; } CctvHackingGame.SignalNode signalNode = _game.Nodes[j]; bool selected = signalNode.Id == _game.SelectedNodeId; bool current = signalNode.Id == _game.FromNodeId || signalNode.Id == _game.ToNodeId; bool completed = _game.IsTargetCompleted(signalNode.Id); float rotatePop = ((signalNode.Id == _lastRotatedNodeId) ? RotateFeedback01() : 0f); bool originAlert = signalNode.IsOrigin && IsReturnPhase(); _nodeViews[j].Render(signalNode, ToGraphLocal(signalNode.Position), selected, current, completed, _game.CanRotateNode(signalNode.Id), rotatePop, originAlert, _accentColor, _dimColor); } if ((Object)(object)_pulseImage != (Object)null) { ((Component)_pulseImage).gameObject.SetActive(!_game.Locked); RectTransform rectTransform = ((Graphic)_pulseImage).rectTransform; rectTransform.anchoredPosition = ToGraphLocal(_game.GetPulsePosition()); float num3 = 13f + Mathf.Sin(Time.unscaledTime * 18f) * 2f; rectTransform.sizeDelta = new Vector2(num3, num3); ((Graphic)_pulseImage).color = ScreenWhiteGreen; } } private bool IsReturnPhase() { if (_game != null && _game.MustReturnToOrigin && !_game.Solved) { return !_game.Locked; } return false; } private float RotateFeedback01() { if (_lastRotatedNodeId < 0 || _rotateFlashUntil <= 0f) { return 0f; } float num = _rotateFlashUntil - Time.unscaledTime; if (num <= 0f) { return 0f; } return Mathf.Clamp01(num / 0.34f); } private void RefreshRouteArrows() { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) if (_routeArrowViews == null) { return; } int num = 0; int num2 = ((_game.Nodes != null) ? _game.Nodes.Count : 0); for (int i = 0; i < num2; i++) { if (num >= _routeArrowViews.Length) { break; } CctvHackingGame.SignalNode signalNode = _game.Nodes[i]; if (signalNode != null && !signalNode.IsTarget && signalNode.NeighborCount > 0) { int activeNeighbor = signalNode.GetActiveNeighbor(); CctvHackingGame.SignalNode node = _game.GetNode(activeNeighbor); if (node != null && node.Id != signalNode.Id) { bool num3 = signalNode.Id == _game.SelectedNodeId; bool flag = signalNode.Id == _game.FromNodeId && activeNeighbor == _game.ToNodeId; bool flag2 = signalNode.Id == _game.ToNodeId && !_game.IsRequiredTarget(signalNode.Id); Color color = (num3 ? ScreenAmber : (flag ? ScreenWhiteGreen : _accentColor)); float alpha = ((num3 || flag) ? 1f : (flag2 ? 0.95f : 0.72f)); float fontSize = (num3 ? 21f : (flag ? 20f : (flag2 ? 18f : 16f))); float sweep = ((signalNode.Id == _lastRotatedNodeId) ? RotateFeedback01() : 0f); int num4 = num++; _routeArrowViews[num4].Render(ToGraphLocal(signalNode.Position), ToGraphLocal(node.Position), color, alpha, fontSize, num4, sweep); } } } for (int j = num; j < _routeArrowViews.Length; j++) { _routeArrowViews[j].Hide(); } } private void SetGameViewVisible(bool visible) { if ((Object)(object)_graphRoot != (Object)null) { _graphRoot.SetActive(visible); } if ((Object)(object)_bootText != (Object)null) { ((Component)_bootText).gameObject.SetActive(!visible); } if ((Object)(object)_objectiveText != (Object)null) { ((Component)_objectiveText).gameObject.SetActive(visible); } if ((Object)(object)_traceBarBackRect != (Object)null) { ((Component)_traceBarBackRect).gameObject.SetActive(visible); } if ((Object)(object)_helpText != (Object)null) { ((TMP_Text)_helpText).text = (visible ? "ARROWS PICK RELAY ENTER AIMS IT ESC EXIT" : "LINKING..."); } RefreshActionText(); if (visible) { RefreshGraph(); } } private bool IsBooting() { if (_isOpen) { return Time.unscaledTime < _bootUntil; } return false; } private void HandleBootSkipInput() { Keyboard current = Keyboard.current; if (current != null && (((ButtonControl)current.enterKey).wasPressedThisFrame || ((ButtonControl)current.numpadEnterKey).wasPressedThisFrame)) { RequestBootSkip("keyboard-enter"); } } internal bool RequestBootSkip(string source) { if (!IsBooting()) { return false; } if (Time.frameCount <= _openedFrame + 1) { return false; } float unscaledTime = Time.unscaledTime; if (unscaledTime - _bootStartedAt < 0.16f) { return false; } _bootUntil = unscaledTime; _inputArmedAt = unscaledTime; _lastActionInputFrame = Time.frameCount; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)string.Format("[LethalCCTV][SignalSplice] Boot skipped source='{0}' target='{1}' after {2:0.00}s.", source ?? "unknown", _targetDisplayName, unscaledTime - _bootStartedAt)); } return true; } private void RefreshBootText() { if ((Object)(object)_bootText == (Object)null) { return; } float num = Mathf.Max(0f, Time.unscaledTime - _bootStartedAt); int num2 = Mathf.Clamp(Mathf.FloorToInt(num / 0.23f) + 1, 1, BootLines.Length); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < num2; i++) { if (i > 0) { stringBuilder.Append('\n'); } stringBuilder.Append(BootLines[i]); } if (num2 >= BootLines.Length && Mathf.FloorToInt(Time.unscaledTime * 4f) % 2 == 0) { stringBuilder.Append("\n> _"); } if (num >= 0.16f) { stringBuilder.Append("\n\n> [ENTER] skip"); } ((TMP_Text)_bootText).text = stringBuilder.ToString(); } private bool IsInputArmed() { if (Time.frameCount <= _openedFrame || Time.unscaledTime < _inputArmedAt) { return false; } if (!_inputArmedLogSent) { _inputArmedLogSent = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV][SignalSplice] Input armed target='{_targetDisplayName}' frame={Time.frameCount} selected={_game?.SelectedNodeId}."); } } return true; } private void ResetResultLog() { _resultLog.Clear(); AppendLog(">Carrier found."); if (_game != null) { AppendLog(">Risk " + _game.MoonRiskLabel + "."); AppendLog($">Targets {_game.RequiredTargetCount}."); } } private void AppendLog(string line) { if (!string.IsNullOrWhiteSpace(line)) { while (_resultLog.Count >= 4) { _resultLog.RemoveAt(0); } _resultLog.Add(line); RefreshLogText(); } } private void RefreshLogText() { if ((Object)(object)_logText == (Object)null) { return; } StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < _resultLog.Count; i++) { if (i > 0) { stringBuilder.Append('\n'); } stringBuilder.Append(_resultLog[i]); } ((TMP_Text)_logText).text = stringBuilder.ToString(); } private void SetStatus(string text, Color color) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_statusText == (Object)null)) { ((TMP_Text)_statusText).text = text ?? string.Empty; ((Graphic)_statusText).color = color; } } private string BuildStashCodeLogLine() { IReadOnlyList revealedStashCodes = CctvSupportApi.RevealedStashCodes; if (revealedStashCodes == null || revealedStashCodes.Count == 0) { return null; } StringBuilder stringBuilder = new StringBuilder(">Stash codes "); for (int i = 0; i < revealedStashCodes.Count; i++) { if (i > 0) { stringBuilder.Append(' '); } stringBuilder.Append(CctvSupportApi.FormatStashCode(revealedStashCodes[i])); } return stringBuilder.ToString(); } private string BuildGoalSummary() { if (_game == null) { return "GOAL --"; } if (_game.MustReturnToOrigin) { return "GOAL RETURN O"; } StringBuilder stringBuilder = new StringBuilder("GOAL"); int num = 0; for (int i = 0; i < _game.Nodes.Count; i++) { CctvHackingGame.SignalNode signalNode = _game.Nodes[i]; if (signalNode != null && signalNode.IsTarget && !_game.IsTargetCompleted(signalNode.Id)) { num++; if (num <= 3) { stringBuilder.Append(' ').Append(FormatNodeLabel(signalNode)); } } } if (num <= 0) { return "GOAL RETURN O"; } if (num > 3) { return "GOAL " + num + " TARGETS"; } return stringBuilder.ToString(); } private float CurrentTraceNormalized() { if (_game == null) { return 0f; } return Mathf.Clamp01(_game.TraceNormalized); } private void ResolveGraphSourceBounds() { //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_0020: 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_0078: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) _graphSourceMin = new Vector2(0.07f, 0.18f); _graphSourceMax = new Vector2(0.91f, 0.82f); IReadOnlyList readOnlyList = _game?.Nodes; if (readOnlyList == null) { return; } Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(float.MaxValue, float.MaxValue); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(float.MinValue, float.MinValue); int num = 0; for (int i = 0; i < readOnlyList.Count; i++) { CctvHackingGame.SignalNode signalNode = readOnlyList[i]; if (signalNode != null) { val = Vector2.Min(val, signalNode.Position); val2 = Vector2.Max(val2, signalNode.Position); num++; } } if (num > 0) { ExpandToMinimumSpan(ref val.x, ref val2.x); ExpandToMinimumSpan(ref val.y, ref val2.y); _graphSourceMin = val; _graphSourceMax = val2; } } private static void ExpandToMinimumSpan(ref float min, ref float max) { if (!(max - min >= 0.05f)) { float num = (min + max) * 0.5f; min = num - 0.025f; max = num + 0.025f; } } private Vector2 ToGraphLocal(Vector2 normalized) { //IL_001a: 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) //IL_0023: 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_0029: 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_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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00dd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_graphRect == (Object)null) { return Vector2.zero; } Rect rect = _graphRect.rect; Vector2 val = ((Rect)(ref rect)).size; if (val.x <= 0.01f || val.y <= 0.01f) { val = _graphRect.sizeDelta; } float num = Mathf.Max(16f, val.x - NodeEdgePadding * 2f); float num2 = Mathf.Max(16f, val.y - NodeEdgePadding * 2f); float num3 = Mathf.InverseLerp(_graphSourceMin.x, _graphSourceMax.x, normalized.x); float num4 = Mathf.InverseLerp(_graphSourceMin.y, _graphSourceMax.y, normalized.y); return new Vector2((num3 - 0.5f) * num, (num4 - 0.5f) * num2); } private bool IsSelectedActiveEdge(int first, int second) { if (_game == null) { return false; } CctvHackingGame.SignalNode node = _game.GetNode(_game.SelectedNodeId); if (node == null) { return false; } int activeNeighbor = node.GetActiveNeighbor(); if (node.Id != first || activeNeighbor != second) { if (node.Id == second) { return activeNeighbor == first; } return false; } return true; } private static int GetNextNeighborId(CctvHackingGame.SignalNode node) { if (node == null || node.NeighborCount <= 0) { return -1; } int index = PositiveModulo(node.ActiveNeighborIndex + 1, node.NeighborCount); return node.Neighbors[index]; } private static int PositiveModulo(int value, int modulus) { if (modulus <= 0) { return 0; } int num = value % modulus; if (num >= 0) { return num; } return num + modulus; } private string FormatNodeShort(int nodeId) { return FormatNodeLabel((_game != null) ? _game.GetNode(nodeId) : null); } private static string FormatNodeLabel(CctvHackingGame.SignalNode node) { if (node == null) { return "--"; } if (node.IsOrigin) { return "O"; } if (node.IsTarget) { return "T" + node.TargetSlot; } return "R" + node.Id.ToString("00"); } private void ApplyTerminalStyleRefs(TerminalStyleRefs refs) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_010f: 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_014d: 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_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) _accentColor = refs.Accent; _dimColor = refs.Dim; if ((Object)(object)refs.FontMaterial != (Object)null && (Object)(object)_terminalFontMaterial != (Object)null) { Object.Destroy((Object)(object)_terminalFontMaterial); _terminalFontMaterial = null; } if ((Object)(object)refs.FontMaterial != (Object)null) { _terminalFontMaterial = new Material(refs.FontMaterial) { name = "LethalCCTV_SignalSplice_FontMat" }; CrtDockLayout.ApplyLowResFaceThickening(_terminalFontMaterial); } for (int i = 0; i < _textElements.Count; i++) { TextMeshProUGUI val = _textElements[i]; if (!((Object)(object)val == (Object)null)) { if ((Object)(object)refs.Font != (Object)null) { ((TMP_Text)val).font = refs.Font; } if ((Object)(object)_terminalFontMaterial != (Object)null) { ((TMP_Text)val).fontSharedMaterial = _terminalFontMaterial; } } } if ((Object)(object)_titleText != (Object)null) { ((Graphic)_titleText).color = _accentColor; } if ((Object)(object)_traceText != (Object)null) { ((Graphic)_traceText).color = _accentColor; } if ((Object)(object)_targetText != (Object)null) { ((Graphic)_targetText).color = _accentColor; } if ((Object)(object)_statusText != (Object)null) { ((Graphic)_statusText).color = _accentColor; } if ((Object)(object)_actionText != (Object)null) { ((Graphic)_actionText).color = ScreenAmber; } if ((Object)(object)_logText != (Object)null) { ((Graphic)_logText).color = _accentColor; } if ((Object)(object)_helpText != (Object)null) { ((Graphic)_helpText).color = _dimColor; } if ((Object)(object)_bootText != (Object)null) { ((Graphic)_bootText).color = _accentColor; } if ((Object)(object)_objectiveText != (Object)null) { ((Graphic)_objectiveText).color = _dimColor; } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][SignalSplice] Read-only terminal style refs: " + refs.SourceDescription + ".")); } } private TextMeshProUGUI CreateTerminalText(Transform parent, string name, string text, float size, TextAlignmentOptions alignment, Color color, Vector2 anchoredPosition, Vector2 sizeDelta) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0f, 1f); obj.anchorMax = new Vector2(0f, 1f); obj.pivot = new Vector2(0f, 1f); obj.anchoredPosition = anchoredPosition; obj.sizeDelta = sizeDelta; TextMeshProUGUI val2 = val.AddComponent(); ((TMP_Text)val2).text = text; ((TMP_Text)val2).fontSize = size; ((TMP_Text)val2).alignment = alignment; ((Graphic)val2).color = color; ((TMP_Text)val2).richText = true; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).characterSpacing = 0f; ((TMP_Text)val2).fontStyle = (FontStyles)1; RegisterText(val2); return val2; } private void RegisterText(TextMeshProUGUI text) { if (!((Object)(object)text == (Object)null)) { ((TMP_Text)text).enableWordWrapping = false; ((TMP_Text)text).overflowMode = (TextOverflowModes)0; ((TMP_Text)text).characterSpacing = 0f; if (!_textElements.Contains(text)) { _textElements.Add(text); } } } private static RectTransform CreateRect(Transform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot) { //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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_003a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = anchorMin; obj.anchorMax = anchorMax; obj.pivot = pivot; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; return obj; } private static RectTransform CreateLine(Transform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) RectTransform obj = CreateRect(parent, name, anchorMin, anchorMax, pivot); Image obj2 = ((Component)obj).gameObject.AddComponent(); ((Graphic)obj2).color = new Color(ScreenGreen.r, ScreenGreen.g, ScreenGreen.b, 0.34f); ((Graphic)obj2).raycastTarget = false; return obj; } private static Texture2D BuildScanlineTexture() { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0039: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown Texture2D val = new Texture2D(1, 4, (TextureFormat)4, false) { name = "LethalCCTV_SignalSplice_Scanlines", filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)0 }; val.SetPixel(0, 0, new Color(0f, 0f, 0f, 0f)); val.SetPixel(0, 1, new Color(0f, 0.2f, 0.06f, 0.1f)); val.SetPixel(0, 2, new Color(0f, 0f, 0f, 0.1f)); val.SetPixel(0, 3, new Color(0f, 0.45f, 0.12f, 0.08f)); val.Apply(false, true); return val; } private static Texture2D BuildDiscTexture(int size) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0023: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false) { name = "LethalCCTV_SignalSplice_Disc", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; float num = (float)size * 0.5f; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num2 = (float)j + 0.5f - num; float num3 = (float)i + 0.5f - num; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3) / num; float num5 = Mathf.Clamp01((0.97f - num4) * num * 0.5f); val.SetPixel(j, i, new Color(1f, 1f, 1f, num5)); } } val.Apply(false, true); return val; } private static Texture2D BuildVignetteTexture(int width, int height) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0023: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(width, height, (TextureFormat)4, false) { name = "LethalCCTV_SignalSplice_Vignette", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { float num = (float)j / (float)(width - 1) * 2f - 1f; float num2 = (float)i / (float)(height - 1) * 2f - 1f; float num3 = Mathf.Clamp01((Mathf.Sqrt(num * num * 0.78f + num2 * num2 * 1.22f) - 0.42f) / 0.72f) * 0.58f; val.SetPixel(j, i, new Color(0f, 0f, 0f, num3)); } } val.Apply(false, true); return val; } private static string ResolveTargetDisplayName(Component component) { if ((Object)(object)component == (Object)null) { return "MAINFRAME"; } if (CctvCommandTargetBridge.TryDescribeTarget(component, out var info) && !string.IsNullOrWhiteSpace(info.DisplayName)) { return info.DisplayName; } if (!string.IsNullOrWhiteSpace(((Object)component).name)) { return ((Object)component).name; } return ((object)component).GetType().Name; } private static Terminal FindShipTerminal() { try { return Object.FindObjectOfType(); } catch { return null; } } private static object ReadMember(object target, string memberName) { if (target == null || string.IsNullOrEmpty(memberName)) { return null; } Type type = target.GetType(); PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { try { return property.GetValue(target); } catch { return null; } } FieldInfo field = type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { return null; } try { return field.GetValue(target); } catch { return null; } } } public class LethalCCTVConfig : SyncedConfig2 { [SyncedEntryField] public SyncedEntry ExcludeEntranceTiles; [SyncedEntryField] public SyncedEntry ExcludeFireExitTiles; [SyncedEntryField] public SyncedEntry ExcludeMineshaftTunnels; [SyncedEntryField] public SyncedEntry ExcludeTinyTiles; [SyncedEntryField] public SyncedEntry TinyTileMaxFloorAreaM2; [SyncedEntryField] public SyncedEntry TileNameExclusionPatterns; [SyncedEntryField] public SyncedEntry CctvTerminalPrice; [SyncedEntryField] public SyncedEntry CycleSeconds; [SyncedEntryField] public SyncedEntry ExcludeCorridors; [SyncedEntryField] public SyncedEntry CorridorMaxConnectedDoorways; [SyncedEntryField] public SyncedEntry MinHorizontalDimensionM; [SyncedEntryField] public SyncedEntry MinFloorAreaM2; [SyncedEntryField] public SyncedEntry JunctionMinDegree; [SyncedEntryField] public SyncedEntry CameraBudgetCap; [SyncedEntryField] public SyncedEntry CameraBudgetPriority; [SyncedEntryField] public SyncedEntry LinearChainCoverage; [SyncedEntryField] public SyncedEntry LeafCameraMinAreaM2; [SyncedEntryField] public SyncedEntry OneCameraPerTile; private const string RadarSection = "90 - CCTV - Radar"; private const string LegacyRadarSection = "CCTV Radar"; public Vector3 MonitorPosition => new Vector3(11f, 3f, -13f); public Quaternion MonitorRotation => Quaternion.Euler(0f, 90f, 0f); public ConfigEntry ReconLoggingEnabled { get; private set; } public ConfigEntry PlacementDebugLoggingEnabled { get; private set; } public float PlacementHeightFraction => 0.85f; public float PlacementHorizontalFraction => 0.35f; public ConfigEntry GeneralImprovementsFeedScreenIndex { get; private set; } public ConfigEntry GeneralImprovementsRadarScreenIndex { get; private set; } public ConfigEntry RenderHzPerMonitor { get; private set; } public ConfigEntry BodycamRenderHz { get; private set; } public ConfigEntry DynamicActiveRendererEnabled { get; private set; } public ConfigEntry InactivePaneRenderHz { get; private set; } public ConfigEntry UnmannedIdleRenderHz { get; private set; } public ConfigEntry RenderRTWidth { get; private set; } public ConfigEntry FarClipPlane { get; private set; } public ConfigEntry FieldOfView { get; private set; } public ConfigEntry CCTVShadowMapsEnabled { get; private set; } public ConfigEntry UseVanillaRadarFeed { get; private set; } public ConfigEntry ShowRadarItemBlips { get; private set; } public ConfigEntry RadarBlipScale { get; private set; } public ConfigEntry UseInteractionsApiOperatorSession { get; private set; } public ConfigEntry LocalAuthoredOperatorAnimationsEnabled { get; private set; } public float WallMountMinRoomHeightM => 8f; public float WallMountHeightM => 3f; public ConfigEntry P20ProbeEnabled { get; private set; } public ConfigEntry NightVisionEnabled { get; private set; } public ConfigEntry NightVisionGain { get; private set; } public ConfigEntry NightVisionAutoGain { get; private set; } public ConfigEntry NightVisionFlipY { get; private set; } public ConfigEntry FeedColorRetention { get; private set; } public ConfigEntry FeedScanlineStrength { get; private set; } public ConfigEntry FeedNoiseStrength { get; private set; } public ConfigEntry FeedVignetteStrength { get; private set; } public ConfigEntry FeedChromaAberration { get; private set; } public ConfigEntry FeedRollBarStrength { get; private set; } public ConfigEntry FeedRollBarSpeed { get; private set; } public ConfigEntry FeedCurvatureStrength { get; private set; } public ConfigEntry FeedInterlaceStrength { get; private set; } public ConfigEntry FeedDropoutStrength { get; private set; } public ConfigEntry CCTVFillLightEnabled { get; private set; } public ConfigEntry CCTVRenderFillLightEnabled { get; private set; } public ConfigEntry CCTVFillLightIntensity { get; private set; } public ConfigEntry CCTVFillLightRange { get; private set; } public ConfigEntry PhysicalCameraVisualsEnabled { get; private set; } public ConfigEntry PhysicalCameraVisualScale { get; private set; } public float PhysicalCameraVisualMaxSnapOffsetM => 0.9f; public ConfigEntry SecuritySweepEnabled { get; private set; } public ConfigEntry SecuritySweepYawDegrees { get; private set; } public ConfigEntry SecuritySweepSeconds { get; private set; } public ConfigEntry SecurityTrackDegreesPerSecond { get; private set; } public ConfigEntry SecurityDetectionIndicatorIntensity { get; private set; } public ConfigEntry SecurityIdleConeIntensity { get; private set; } public ConfigEntry SecurityLensDotGlow { get; private set; } public ConfigEntry ShowOperatorControlsOverlay { get; private set; } public ConfigEntry EnableOperatorDebugTools { get; private set; } public ConfigEntry PitchClampDeg { get; private set; } public ConfigEntry YawClampDeg { get; private set; } public ConfigEntry MouselookSensitivityMul { get; private set; } public event Action NightVisionParamsChanged; private void BindCameraSelection(ConfigFile cfg) { //IL_000c: 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_0027: Expected O, but got Unknown //IL_0027: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0053: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_007f: Expected O, but got Unknown //IL_0090: 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_00ab: Expected O, but got Unknown //IL_00ab: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00db: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_010b: Expected O, but got Unknown ExcludeEntranceTiles = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Exclude Entrance Tiles"), false, new ConfigDescription("If true, tiles holding an EntranceTeleport with isEntranceToBuilding == true get no CCTV camera. Default is false: entrance tiles get cameras (Overwatch can see the main entrance).", (AcceptableValueBase)null, Array.Empty())); ExcludeFireExitTiles = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Exclude Fire Exit Tiles"), false, new ConfigDescription("If true, tiles holding an EntranceTeleport with isEntranceToBuilding == false get no CCTV camera. Default is false: fire-exit tiles get cameras.", (AcceptableValueBase)null, Array.Empty())); ExcludeMineshaftTunnels = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Exclude Mineshaft Tunnels"), true, new ConfigDescription("If true, tiles tagged with RoundManager.MineshaftTunnelTag are excluded. Mineshaft tunnels are long and visually uninteresting; default excludes them.", (AcceptableValueBase)null, Array.Empty())); ExcludeTinyTiles = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Exclude Tiny Tiles"), true, new ConfigDescription("If true, tiles with one or zero used doorways AND floor area below TinyTileMaxFloorAreaM2 are excluded.", (AcceptableValueBase)null, Array.Empty())); TinyTileMaxFloorAreaM2 = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Tiny Tile Max Floor Area"), 25f, new ConfigDescription("Floor area (x * z) threshold in square meters. Tiles below this are considered tiny when Exclude Tiny Tiles is true.", (AcceptableValueBase)null, Array.Empty())); TileNameExclusionPatterns = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Tile Name Exclusion Patterns"), string.Empty, new ConfigDescription("Comma-separated list of substrings. If a tile's GameObject name contains any of them (case-insensitive), it's excluded. Empty by default.", (AcceptableValueBase)null, Array.Empty())); } private void BindRoomAwarePlacement(ConfigFile cfg) { //IL_000c: 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_0027: Expected O, but got Unknown //IL_0027: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0053: Expected O, but got Unknown //IL_0064: 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_0083: Expected O, but got Unknown //IL_0083: Expected O, but got Unknown //IL_0094: 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_00b3: Expected O, but got Unknown //IL_00b3: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_00df: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_010c: Expected O, but got Unknown //IL_011d: 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_013c: Expected O, but got Unknown //IL_013c: Expected O, but got Unknown //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_016c: Expected O, but got Unknown //IL_017d: 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_019c: Expected O, but got Unknown //IL_019c: Expected O, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown //IL_01c8: Expected O, but got Unknown ExcludeCorridors = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Exclude Corridors"), true, new ConfigDescription("If true, narrow / small-footprint tiles classified as corridors by the room-aware heuristic get no CCTV camera. Default true: corridors are typically long sparse passageways that produce wall-and-skybox feeds. Synced — host's choice propagates to clients so cameras spawn on the same tiles for everyone.", (AcceptableValueBase)null, Array.Empty())); CorridorMaxConnectedDoorways = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Corridor Max Connected Doorways"), 2, new ConfigDescription("Upper bound on connected-doorway degree (Tile.UsedDoorways.Count) for a tile to be ELIGIBLE for corridor classification. A tile with more connected doorways than this is a junction/room and is never classified as a corridor regardless of size. Default 2 (standard pass-through). The size guards (Min Horizontal Dimension / Min Floor Area) still have to fail for the tile to actually be a corridor — degree is necessary, not sufficient. Synced.", (AcceptableValueBase)null, Array.Empty())); MinHorizontalDimensionM = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Min Horizontal Dimension"), 8.5f, new ConfigDescription("Lower bound on min(Bounds.size.x, Bounds.size.z), in metres, for a tile to be classified as a room. Reference data: RAV_Tallway corridor is 6m on its narrow axis; RAV_Ballroom is 18m. Default bumped 8.0 → 8.5 after the Gate A close-out (2026-05): 8m clovers were sitting exactly on the 8.0 boundary and float-noise from placement put their measured minDim at 7.999x on some runs (→ corridor) and ≥8.0 on others (→ room), making clover classification placement-dependent. 8.5 gives 8m tiles a stable ~0.5m margin below the line; smallest real manor rooms are 11m+ so no real room is threatened. Tiles failing this AND the floor-area floor are classified as corridors. Synced.", (AcceptableValueBase)null, Array.Empty())); MinFloorAreaM2 = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Min Floor Area"), 80f, new ConfigDescription("Floor-area floor in square metres (Bounds.size.x * Bounds.size.z). OR'd with the min-horizontal-dimension test so a small-but-boxy room (low min-dim, but enough total floor to be interesting) still classifies as a room. Reference: RAV_Tallway is ~36m², RAV_Ballroom is ~324m². Synced.", (AcceptableValueBase)null, Array.Empty())); JunctionMinDegree = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Junction Min Degree"), 3, new ConfigDescription("In a multi-tile room-component (a connected group of ROOM tiles linked directly to each other through doorways with no corridor between), a tile is treated as a 'junction' iff its UsedDoorways.Count is >= this value. Each junction tile gets its own camera. Default 3 = first non-pass-through degree (degree-2 cells are pass-throughs even when the cell itself is a room; degree-3+ is a decision point — the natural CCTV vantage). Independent of dungeon-roll size by construction. Synced.", (AcceptableValueBase)null, Array.Empty())); CameraBudgetCap = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Camera Budget Cap"), 24, new ConfigDescription("Maximum total cameras placed per dungeon. If clustering + per-component selection proposes more than this, the lowest-priority spaces are dropped per Camera Budget Priority. PROVISIONAL DEFAULT: 24 is half the ~45-camera baseline that tanked FPS in Phase 1, i.e. 'half of bad,' NOT 'known good.' The REVIEW gate must FPS-profile at or near this cap before the value is considered validated; if a heavy roll near the cap is still a slideshow, lower it. Divisible by the 4-quad wall, a useful property for any future cycling logic. Synced.", (AcceptableValueBase)null, Array.Empty())); CameraBudgetPriority = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Camera Budget Priority"), "MainPathThenDegreeThenArea", new ConfigDescription("Sort order used to decide which proposed cameras to keep when the count exceeds Camera Budget Cap. Values: 'MainPathThenDegreeThenArea' (default; main-path tiles first, then connected-degree desc, then footprint desc), 'LargestAreaFirst', 'HighestDegreeFirst'. The tile's source index in AllTiles is ALWAYS the final tiebreaker so the same proposed-pick set truncates identically on host and client. Unknown values fall back to default with a one-shot warning. Synced (so host's preference propagates).", (AcceptableValueBase)null, Array.Empty())); LinearChainCoverage = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Linear Chain Coverage"), "DegreeOneEndpoints", new ConfigDescription("How to place cameras in a multi-tile component that has NO junction tiles (every tile is degree <= 2 — a linear chain of rooms, uncommon). Values: 'DegreeOneEndpoints' (default; one camera at each degree-1 endpoint tile so a chain is covered at both ends — threats enter from endpoints), 'LargestTileOnly' (one camera at the largest-footprint tile, ties broken by lowest source index). A ring (no junctions AND no degree-1 endpoints) always falls back to the largest-tile rule regardless of this setting. Unknown values fall back to default with a one-shot warning. Synced.", (AcceptableValueBase)null, Array.Empty())); LeafCameraMinAreaM2 = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "Leaf Camera Min Area"), 80f, new ConfigDescription("In a multi-tile room-component that already has junction tiles, every NON-JUNCTION room (subgraph degree <= 2 in the component — i.e. a degree-1 leaf OR a degree-2 through-room; subgraph degree, NOT raw doorway count, so corridor-side doorways do not count) whose floor area in m² is at least this value receives its own camera IN ADDITION to the component's junction cameras. Applies ONLY inside the junction branch — the linear-chain branch already covers degree-1 endpoints, the ring branch has no leaves, the single-tile branch has no leaves. Set to 0 to disable the rule entirely (no-op; output is byte-identical to pre-D1 behaviour). Default 80.0 m², matching the Min Floor Area room floor. NAME NOTE: the entry is still called 'Leaf Camera Min Area' for .cfg compatibility with installs that already have the D1-era line; the rule's behaviour is wider than just leaves as of D4. NOTE: CHANGING THE CODE DEFAULT DOES NOT MIGRATE STALE CONFIG FILES — if you installed an earlier build the entry is already pinned in LethalCCTV.cfg at its prior value; delete the line (or the whole file) and let it regenerate to pick up the current default. Synced (host's choice propagates).", (AcceptableValueBase)null, Array.Empty())); OneCameraPerTile = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("81 - CCTV - Camera Selection", "One Camera Per Tile"), true, new ConfigDescription("When true (default), the room-aware selector places one camera in every non-excluded room tile rather than only at junction / large-leaf tiles. The strict junction-only selection yielded 3-4 cameras on typical Facility rolls, which the operator reported as too low for a multi-room role. The surface-mount pass in the spawner still filters tiles that can't physically host a camera, so this rule still respects mount-feasibility. Set to false to revert to the old junction-only selection. Synced.", (AcceptableValueBase)null, Array.Empty())); } public LethalCCTVConfig(ConfigFile cfg) : base("com.y4ngz.company.lethalcctv") { BindDiagnostics(cfg); BindCameraSelection(cfg); BindShipTerminalStore(cfg); BindShipMonitorHijack(cfg); BindRendering(cfg); BindOperatorControls(cfg); BindRoomAwarePlacement(cfg); BindLegibilityProbe(cfg); BindDisplay(cfg); BindPhysicalCameras(cfg); BindFocusMouselook(cfg); ConfigManager.Register((SyncedConfig2)this); } private void BindDiagnostics(ConfigFile cfg) { ReconLoggingEnabled = cfg.Bind("89 - CCTV - Diagnostics", "Recon Logging Enabled", false, "Enables the once-per-session BepInEx log dump of MonitorWall materials, mapScreen prefab values, ship camera prefabs, diageticMixer groups, and the OpenBodyCams slot index. Also gates per-camera, per-tile, and per-monitor debug logs added by later phases. Local entry; not synced."); PlacementDebugLoggingEnabled = cfg.Bind("89 - CCTV - Diagnostics", "Placement Debug Logging Enabled", false, "Enables verbose CCTV placement/classification reports during dungeon generation. Dev-only; leave false for normal play. Purely a logging switch — it never changes what gets spawned."); } private void BindLegibilityProbe(ConfigFile cfg) { P20ProbeEnabled = cfg.Bind("89 - CCTV - Diagnostics", "Enable Placement Probe", false, "Diagnostic. When true, after the cluster→select→cap pipeline picks tiles, a per-tile sightline probe runs: for each picked tile it emits 4 corners × 2 height tiers × N doorways = 8N CAND lines per tile, plus a fail-loud Room-layer assertion at the start and a unified-rule entrance-pick preview at the end. Linecasts run on the 'Room' layer. Pure read — does not alter placement. Per-client, not synced. Default false (dev-only)."); } private void BindDisplay(ConfigFile cfg) { NightVisionEnabled = cfg.Bind("85 - CCTV - Display and Lighting", "Night Vision Enabled", true, "If true, CCTV feeds are rendered grayscale (Rec.601 luminance) with the configured brightness gain — the security-camera 'night vision' aesthetic, and the practical fix for dim dungeon interiors that would otherwise display as near-black. If false, only the gain multiplier applies (colour preserved). Per-client; not synced. Hot-reloadable."); NightVisionGain = cfg.Bind("85 - CCTV - Display and Lighting", "Night Vision Gain", 2f, "Brightness multiplier applied after the (optional) grayscale step, saturated to [0,1] after multiply. Default 2.0 brightens dim interiors without crushing the highlights of already-lit feeds. Range: 0.5–8.0. Per-client; not synced. Hot-reloadable."); NightVisionAutoGain = cfg.Bind("85 - CCTV - Display and Lighting", "Night Vision Auto Gain", true, "If true, each CCTV feed measures its own average brightness and scales the night-vision gain like a real camera's AGC: dim interiors are boosted up to the configured Night Vision Gain ceiling, while brightly lit interiors are attenuated so they no longer clip to solid white (the fixed 2.0x gain white-out on lit vanilla interiors, #569). If false, the configured gain applies unconditionally (the pre-1.0 behavior). Per-client; not synced. Hot-reloadable."); NightVisionFlipY = cfg.Bind("85 - CCTV - Display and Lighting", "Night Vision Flip Y", true, "If true, vertically flips the baked CCTV feed before it reaches the monitor. Direct3D/HDRP camera target textures can arrive upside-down through the Graphics.Blit bake path; leave enabled unless the feed appears vertically inverted. Per-client; not synced. Hot-reloadable."); FeedColorRetention = cfg.Bind("85 - CCTV - Display and Lighting", "Feed Color Retention", 0.35f, "How much of the original colour survives the grayscale step, 0 = fully monochrome, 1 = untouched colour. Only applies when Night Vision Enabled is true. Also sets the ceiling on the chromatic-aberration fringe: the RGB split is composed from three independently desaturated taps, so at 0 retention the fringe comes purely from the three taps' differing luminance and at higher retention it also carries real hue. Range: 0.0–1.0. Per-client; not synced. Hot-reloadable."); FeedScanlineStrength = cfg.Bind("85 - CCTV - Display and Lighting", "Feed Scanline Strength", 0.055f, "Depth of the CRT scanline darkening — a fine sine ripple plus slow-crawling coarse bands. 0 disables scanlines. Raise carefully: scanlines and Feed Interlace Strength both key off the 432 px feed height and can moiré against each other. Range: 0.0–1.0. Per-client; not synced. Hot-reloadable."); FeedNoiseStrength = cfg.Bind("85 - CCTV - Display and Lighting", "Feed Noise Strength", 0.018f, "Amplitude of the per-pixel analog grain, re-rolled 24 times a second. 0 disables grain. Range: 0.0–1.0. Per-client; not synced. Hot-reloadable."); FeedVignetteStrength = cfg.Bind("85 - CCTV - Display and Lighting", "Feed Vignette Strength", 0.12f, "Radial darkening toward the edges of the feed. 0 disables the vignette. Range: 0.0–1.0. Per-client; not synced. Hot-reloadable."); FeedChromaAberration = cfg.Bind("85 - CCTV - Display and Lighting", "Feed Chromatic Aberration", 0.25f, "Radial RGB split, scaling with distance from the centre of the feed. At the default 0.25 the split at the frame corner is about 1.5 px on a 768x432 feed — a fringe on high-contrast edges rather than an obvious colour ghost. 0 disables it. Range: 0.0–4.0. Per-client; not synced. Hot-reloadable."); FeedRollBarStrength = cfg.Bind("85 - CCTV - Display and Lighting", "Feed Roll Bar Strength", 0.1f, "Brightness of the soft band that drifts through the frame, the way an unsynced analog capture rolls. 0 disables the band. Range: 0.0–1.0. Per-client; not synced. Hot-reloadable."); FeedRollBarSpeed = cfg.Bind("85 - CCTV - Display and Lighting", "Feed Roll Bar Speed", 0.12f, "How fast the roll bar drifts, in frame-heights per second — the default 0.12 takes roughly 8 seconds to cross the feed. Has no effect when Feed Roll Bar Strength is 0. Range: 0.0–2.0. Per-client; not synced. Hot-reloadable."); FeedCurvatureStrength = cfg.Bind("85 - CCTV - Display and Lighting", "Feed Curvature Strength", 0.12f, "CRT barrel warp. The image bulges outward and the corners fall off the tube, so they render black instead of smearing. 0 disables the warp and restores a flat, full-bleed frame. Lower this if the overlay text stack ends up sitting over blacked-out corners. Range: 0.0–1.0. Per-client; not synced. Hot-reloadable."); FeedInterlaceStrength = cfg.Bind("85 - CCTV - Display and Lighting", "Feed Interlace Strength", 0.06f, "Depth of the odd/even field flicker — alternating single-pixel rows dim, and which field is dimmed toggles about 12 times a second. 0 disables the flicker. Range: 0.0–1.0. Per-client; not synced. Hot-reloadable."); FeedDropoutStrength = cfg.Bind("85 - CCTV - Display and Lighting", "Feed Dropout Strength", 0.04f, "Density of sparse dead/hot pixel specks, re-rolled 8 times a second. At the default 0.04 roughly 25 four-pixel specks are on screen at any moment. 0 disables them. Range: 0.0–1.0. Per-client; not synced. Hot-reloadable."); CCTVFillLightEnabled = cfg.Bind("85 - CCTV - Display and Lighting", "CCTV Fill Light Enabled", true, "If true, enables a scoped night-vision spot light only while an individual CCTV camera is rendering. This brightens geometry for the CCTV feed without leaving a persistent light in the dungeon for the player camera. Per-client; not synced. Hot-reloadable."); CCTVRenderFillLightEnabled = cfg.Bind("85 - CCTV - Display and Lighting", "CCTV Render Fill Light Enabled", false, "Second-stage opt-in for the real scoped CCTV spot light. Default false keeps CCTV renders shader/exposure-only for performance; set true together with CCTV Fill Light Enabled if feeds are too dark and the extra lighting cost is acceptable. Per-client; not synced. Hot-reloadable."); CCTVFillLightIntensity = cfg.Bind("85 - CCTV - Display and Lighting", "CCTV Fill Light Intensity", 367f, "Intensity for the scoped CCTV fill light. Default mirrors the OpenBodyCams night-vision light baseline. Lower if feeds clip white; raise if they remain too dark. Per-client; not synced. Hot-reloadable."); CCTVFillLightRange = cfg.Bind("85 - CCTV - Display and Lighting", "CCTV Fill Light Range", 12f, "Range in meters for the scoped CCTV fill light. Default mirrors the OpenBodyCams night-vision range baseline and matches the existing short indoor CCTV far-clip target. Per-client; not synced. Hot-reloadable."); NightVisionEnabled.SettingChanged += RaiseNightVisionChanged; NightVisionGain.SettingChanged += RaiseNightVisionChanged; NightVisionFlipY.SettingChanged += RaiseNightVisionChanged; FeedColorRetention.SettingChanged += RaiseNightVisionChanged; FeedScanlineStrength.SettingChanged += RaiseNightVisionChanged; FeedNoiseStrength.SettingChanged += RaiseNightVisionChanged; FeedVignetteStrength.SettingChanged += RaiseNightVisionChanged; FeedChromaAberration.SettingChanged += RaiseNightVisionChanged; FeedRollBarStrength.SettingChanged += RaiseNightVisionChanged; FeedRollBarSpeed.SettingChanged += RaiseNightVisionChanged; FeedCurvatureStrength.SettingChanged += RaiseNightVisionChanged; FeedInterlaceStrength.SettingChanged += RaiseNightVisionChanged; FeedDropoutStrength.SettingChanged += RaiseNightVisionChanged; CCTVFillLightEnabled.SettingChanged += RaiseNightVisionChanged; CCTVRenderFillLightEnabled.SettingChanged += RaiseNightVisionChanged; CCTVFillLightIntensity.SettingChanged += RaiseNightVisionChanged; CCTVFillLightRange.SettingChanged += RaiseNightVisionChanged; void RaiseNightVisionChanged(object _, EventArgs __) { this.NightVisionParamsChanged?.Invoke(); } } private void BindPhysicalCameras(ConfigFile cfg) { PhysicalCameraVisualsEnabled = cfg.Bind("86 - CCTV - Physical Cameras", "Physical Camera Visuals Enabled", true, "If true, spawns a visible wall/ceiling security-camera prop near each interior CCTV render camera. The prop is visual-only; the actual CCTV feed camera stays at its existing view position. Per-client; not synced."); PhysicalCameraVisualScale = cfg.Bind("86 - CCTV - Physical Cameras", "Physical Camera Visual Scale", 1f, "Scale multiplier for the visible security-camera prop. Applies to the optional bundled prefab and the generated fallback visual. Per-client; not synced."); SecuritySweepEnabled = cfg.Bind("86 - CCTV - Physical Cameras", "Security Sweep Enabled", true, "If true, unbroken CCTV cameras slowly sweep left-to-right when not under manual player control. Per-client visual; server owns detection state."); SecuritySweepYawDegrees = cfg.Bind("86 - CCTV - Physical Cameras", "Security Sweep Yaw Degrees", 42f, "Maximum yaw offset in either direction for automatic camera sweeps. Per-client visual; server owns detection state."); SecuritySweepSeconds = cfg.Bind("86 - CCTV - Physical Cameras", "Security Sweep Seconds", 12f, "Seconds for one full left-to-right-to-left camera sweep cycle. Per-client visual; server owns detection state."); SecurityTrackDegreesPerSecond = cfg.Bind("86 - CCTV - Physical Cameras", "Security Track Degrees Per Second", 38f, "Maximum degrees per second a security-active camera can turn while following a visible player. Per-client visual; server owns detection state."); SecurityDetectionIndicatorIntensity = cfg.Bind("86 - CCTV - Physical Cameras", "Security Detection Indicator Intensity", 1f, "Intensity multiplier for suspicion-only camera detection indicators. Per-client visual."); SecurityIdleConeIntensity = cfg.Bind("86 - CCTV - Physical Cameras", "Security Idle Cone Intensity", 1f, "Intensity multiplier for the faint always-on visibility cone a security-active camera casts before it has spotted anyone, so you can read what it is looking at. 0 disables the idle cone and leaves only the detection beam. Separate from Security Detection Indicator Intensity so 'subtle' can be dialled without touching the detection beam. Per-client visual."); SecurityLensDotGlow = cfg.Bind("86 - CCTV - Physical Cameras", "Security Lens Dot Glow", 1f, "Multiplier for how brightly the camera's lens dot itself glows, across every state (inactive red, active amber, detection strobe, alarm). Scales the whole ladder at once, so the relative brightness between states is preserved. 0 leaves the dot unlit. Per-client visual."); } private void BindOperatorControls(ConfigFile cfg) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown UseVanillaRadarFeed = cfg.Bind("90 - CCTV - Radar", "Use Vanilla Radar Feed", true, "When true, the CCTV focus radar inset uses a cloned vanilla MapCamera/ManualCameraRenderer feed centered on the active CCTV camera instead of the legacy CPU-drawn DunGen tile schematic. If the vanilla feed cannot be constructed, the old schematic is used as a fallback. Per-client; local entry, not synced."); ShowRadarItemBlips = cfg.Bind("90 - CCTV - Radar", "Show Item Blips", true, "When true, loose scrap inside the facility on the radar's active floor is drawn as its own blip class. A heavily looted interior can put forty blips on the map at once, so turn this off to de-clutter without losing the camera, player, monster and objective markers. Per-client; local entry, not synced."); RadarBlipScale = cfg.Bind("90 - CCTV - Radar", "Radar Blip Scale", 1f, new ConfigDescription("Multiplies the on-screen size of every radar marker — cameras, crew, monsters, objectives and item blips alike. 1.0 is the authored size. The per-class size hierarchy is a set of fixed ratios underneath this, so raising or lowering it can never make one class read as another. Per-client; local entry, not synced.", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 2.5f), Array.Empty())); MigrateLegacyRadarSection(cfg); ShowOperatorControlsOverlay = cfg.Bind("87 - CCTV - Operator Controls", "Show Operator Controls Overlay", false, "Retired in favour of the CCTV controls sticky note that spawns in the ship (#579); false is the default and the shipped experience. True brings the old top-left tooltip panel back as a fallback for anyone who has lost or stowed the note. This value governs the panel in every mode. The H keybind that flips it mid-session is live only while Enable Operator Debug Tools is on and is inert otherwise; the F1/F2 debug edit menus draw into this same panel, so with debug tools on and this off, H is what brings them back on screen. If the sticky note fails to register at startup the panel is forced on regardless of this setting, so a controls reference is never unavailable. Per-client; local entry, not synced."); EnableOperatorDebugTools = cfg.Bind("87 - CCTV - Operator Controls", "Enable Operator Debug Tools", false, "When true, the operator station's developer hotkeys are live: F1 station edit menu, F2 camera placement edit and its F4/F5/F6/Delete actions, F8 first-person arms toggle, and the Alt arms-offset nudge. False (the default) makes all of them inert and hides their panels. Gameplay controls (mouse aim, arrows, SPACE radar, wheel zoom, LMB ping, RMB target, V walkie, E/ESC exit) are unaffected either way. Per-client; local entry, not synced."); UseInteractionsApiOperatorSession = cfg.Bind("87 - CCTV - Operator Controls", "Use Interactions API Operator Session", true, "When true, CCTV operator enter/hold/exit animation runs through the Y4NGZInteractions live-body API. If the API or pack is unavailable, CCTV logs the reason and uses the existing legacy path. Per-client; local entry, not synced."); LocalAuthoredOperatorAnimationsEnabled = cfg.Bind("87 - CCTV - Operator Controls", "Enable Local Authored Operator Animations", false, "Legacy-path opt-in for the case where Use Interactions API Operator Session is turned OFF: it brings the legacy local first-person controller back for that deliberate kill-switch-off run, and when false only remote third-person sync remains. Since #593 it no longer gates the API's runtime fallback - an API session that was requested but could not start (Interactions missing, pack gate rejected) presents the authored legacy operator on its own rather than an armless, frozen one."); } private void MigrateLegacyRadarSection(ConfigFile cfg) { try { if (!(typeof(ConfigFile).GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(cfg) is Dictionary { Count: not 0 } dictionary)) { return; } int num = 0; num += MigrateOrphanedRadarBool(dictionary, "Use Vanilla Radar Feed", UseVanillaRadarFeed); num += MigrateOrphanedRadarBool(dictionary, "Show Item Blips", ShowRadarItemBlips); if (num > 0) { cfg.Save(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV] Migrated {num} radar setting(s) from the legacy " + "[CCTV Radar] section to [90 - CCTV - Radar].")); } } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Could not migrate the legacy [CCTV Radar] section to [90 - CCTV - Radar] (" + ex.GetType().Name + ": " + ex.Message + "). Any customized values under [CCTV Radar] must be re-set under [90 - CCTV - Radar].")); } } } private static int MigrateOrphanedRadarBool(Dictionary orphans, string key, ConfigEntry entry) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown ConfigDefinition key2 = new ConfigDefinition("CCTV Radar", key); if (entry == null || !orphans.TryGetValue(key2, out var value)) { return 0; } orphans.Remove(key2); if (bool.TryParse(value?.Trim(), out var result) && entry.Value != result) { entry.Value = result; } return 1; } private void BindFocusMouselook(ConfigFile cfg) { PitchClampDeg = cfg.Bind("87 - CCTV - Operator Controls", "Pitch Clamp Degrees", 75f, "Maximum absolute pitch (up or down) from spawn baseline applied to the active pane while focused. 75° hits the edge of comfortable viewing without flipping over the pole. Per-client; not synced."); YawClampDeg = cfg.Bind("87 - CCTV - Operator Controls", "Yaw Clamp Degrees", 90f, "Maximum absolute yaw from spawn baseline applied to the active pane. Every spawned camera is a mounted interior camera, so this arc is always enforced. Per-client; not synced."); MouselookSensitivityMul = cfg.Bind("87 - CCTV - Operator Controls", "Mouselook Sensitivity Multiplier", 1f, "Multiplier applied to vanilla look sensitivity for the focused CCTV pan. 1.0 matches the player look; lower for finer aim, higher for snappier sweeps. Per-client; not synced."); } private void BindRendering(ConfigFile cfg) { RenderHzPerMonitor = cfg.Bind("84 - CCTV - Rendering", "Render Hz Per Monitor", 24, "Per-monitor render frequency in Hz. Default 24. Tunable 5–30; above 30 risks visible FPS dip on lower-end hardware. Per-client; local entry, not synced."); BodycamRenderHz = cfg.Bind("84 - CCTV - Rendering", "Bodycam Render Hz", 15, "Render frequency for the purchased OpenBodyCams feed while its CCTV focus slot is selected. The camera stays disabled outside that slot. Tunable 5–30; lower values reduce the extra scene-render cost. Per-client; local entry, not synced."); DynamicActiveRendererEnabled = cfg.Bind("84 - CCTV - Rendering", "Dynamic Active Renderer Enabled", true, "When true, only the focused active CCTV pane renders at full Hz. Other bound panes render at Inactive Pane Render Hz. Disable to restore the previous all-four-bound-cameras-at-full-rate behavior. Per-client; local entry, not synced."); InactivePaneRenderHz = cfg.Bind("84 - CCTV - Rendering", "Inactive Pane Render Hz", 3, "Render frequency for non-active panes while CCTV focus is open and Dynamic Active Renderer is enabled. Set 0 to freeze inactive panes except for one-shot wake/page renders. Per-client; local entry, not synced."); UnmannedIdleRenderHz = cfg.Bind("84 - CCTV - Rendering", "Unmanned Idle Render Hz", 3, "Render frequency for the one camera left on the ship monitor wall while nobody is operating the station. Only that single feed renders; every other camera stays off. Tunable 0-10; 0 freezes the wall on the last rendered frame (the pre-0.0.x behaviour). Per-client; local entry, not synced."); RenderRTWidth = cfg.Bind("84 - CCTV - Rendering", "Render RT Width", 512, "RenderTexture width in pixels. Height is derived 4:3. Default 512 (so 512x384). Lower values reduce GPU cost but blur CCTV feeds. Per-client; local entry, not synced."); FarClipPlane = cfg.Bind("84 - CCTV - Rendering", "Far Clip Plane", 40f, "Camera far clip plane in meters. Default 40 m restores the pre-0.0.29 CCTV view distance. Lower values reduce overdraw but can make feeds too short-ranged. Per-client aesthetic; local entry, not synced."); FieldOfView = cfg.Bind("84 - CCTV - Rendering", "Field Of View", 75f, "Camera field-of-view in degrees. Default 75. Per-client aesthetic; local entry, not synced."); CCTVShadowMapsEnabled = cfg.Bind("84 - CCTV - Rendering", "CCTV Shadow Maps Enabled", false, "If true, CCTV cameras render HDRP shadow maps. Default false keeps security feeds cheap; the night-vision shader and exposure volume provide legibility without asking every CCTV render to rebuild dungeon shadows. Per-client; local entry, not synced."); } private void BindShipTerminalStore(ConfigFile cfg) { //IL_000c: 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_002b: Expected O, but got Unknown //IL_002b: Expected O, but got Unknown CctvTerminalPrice = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("80 - CCTV - Ship Terminal", "CCTV Terminal Price"), 200, new ConfigDescription("Credit cost of the CCTV Terminal upgrade in the vanilla ship store. Host-authoritative. Only used on a standalone LethalCCTV install; when the Y4NGZ Contracted plugin is present the terminal is sold through its requisition shop instead and this value is ignored. The store node is built once at plugin load, so a changed price applies from the next game launch.", (AcceptableValueBase)null, Array.Empty())); } private void BindShipMonitorHijack(ConfigFile cfg) { //IL_000c: 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_002b: Expected O, but got Unknown //IL_002b: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown CycleSeconds = SyncedBindingExtensions.BindSyncedEntry(cfg, new ConfigDefinition("83 - CCTV - Ship Monitor", "Cycle Seconds"), 8f, new ConfigDescription("Seconds before the ship monitor advances to the next CCTV camera. Synced across clients so all players see the same camera at the same time.", (AcceptableValueBase)null, Array.Empty())); GeneralImprovementsFeedScreenIndex = cfg.Bind("83 - CCTV - Ship Monitor", "GeneralImprovements Feed Screen Index", -1, new ConfigDescription("Which GI screen shows the CCTV camera feed (the screen the vanilla lower-LEFT map monitor would have shown). Automatic (-1) is GI's MAP screen — the big MIDDLE monitor — which is vanilla parity: CCTV takes over the map monitor, and that is the screen the operator chair actually faces. Screen index on GeneralImprovements' replacement monitor wall, used only when GI is installed with UseBetterMonitors=true (otherwise ignored entirely and the vanilla Cube.001 slots are used as before). -1 = automatic (see the per-entry note above). -2 = GI's MAP screen, the big MIDDLE monitor (MonitorGroup/Monitors/BigMiddle/MScreen) the operator chair faces. That screen is not part of GI's numbered set, which is why it has its own value; CCTV takes it over the same way it takes over the vanilla map monitor, and while it does so the red bezel button stays the CCTV control instead of GI's monitor-power toggle. GI's screen order with AddMoreBetterMonitors=true is 0-1 top-left pair, 2-5 top middle/right, 6-7 second-row left pair, 8-11 second-row middle/right, 12 = big LEFT screen, 13 = big RIGHT screen (14 total). With AddMoreBetterMonitors=false the whole left cluster is gone and there are 9: 0-3 top middle/right, 4-7 second-row middle/right, 8 = big RIGHT screen. These are zero-based; GI's own config keys are one-based, so index 12 is GI's ShipMonitor13. An explicit index that does not exist in this client's GI layout leaves that feed unbound rather than falling back to a screen you did not ask for. Per-client; not synced. Read on every bind pass, so a change applies without a restart.", (AcceptableValueBase)(object)new AcceptableValueRange(-2, 13), Array.Empty())); GeneralImprovementsRadarScreenIndex = cfg.Bind("83 - CCTV - Ship Monitor", "GeneralImprovements Radar Screen Index", -1, new ConfigDescription("Which GI screen shows the CCTV radar (the screen the vanilla lower-RIGHT monitor would have shown). Automatic (-1) prefers the big LEFT screen (index 12), then the big RIGHT screen (13, or 8 without AddMoreBetterMonitors), then the top rows in reading order, and within that prefers screens GI has nothing assigned to. A big screen next to the middle one is what keeps the radar inside the operator station's aim cone; a tiny top-row screen is rejected by it. Set to the same value as the feed screen index to leave the radar unbound and show only the camera feed. Screen index on GeneralImprovements' replacement monitor wall, used only when GI is installed with UseBetterMonitors=true (otherwise ignored entirely and the vanilla Cube.001 slots are used as before). -1 = automatic (see the per-entry note above). -2 = GI's MAP screen, the big MIDDLE monitor (MonitorGroup/Monitors/BigMiddle/MScreen) the operator chair faces. That screen is not part of GI's numbered set, which is why it has its own value; CCTV takes it over the same way it takes over the vanilla map monitor, and while it does so the red bezel button stays the CCTV control instead of GI's monitor-power toggle. GI's screen order with AddMoreBetterMonitors=true is 0-1 top-left pair, 2-5 top middle/right, 6-7 second-row left pair, 8-11 second-row middle/right, 12 = big LEFT screen, 13 = big RIGHT screen (14 total). With AddMoreBetterMonitors=false the whole left cluster is gone and there are 9: 0-3 top middle/right, 4-7 second-row middle/right, 8 = big RIGHT screen. These are zero-based; GI's own config keys are one-based, so index 12 is GI's ShipMonitor13. An explicit index that does not exist in this client's GI layout leaves that feed unbound rather than falling back to a screen you did not ask for. Per-client; not synced. Read on every bind pass, so a change applies without a restart.", (AcceptableValueBase)(object)new AcceptableValueRange(-2, 13), Array.Empty())); } } internal class LethalCCTVInputActions : LcInputActions { [InputAction(/*Could not decode attribute arguments.*/)] public InputAction ExitFocusKeyE { get; set; } [InputAction(/*Could not decode attribute arguments.*/)] public InputAction ExitFocusKeyEscape { get; set; } [InputAction(/*Could not decode attribute arguments.*/)] public InputAction CycleActivePrev { get; set; } [InputAction(/*Could not decode attribute arguments.*/)] public InputAction CycleActiveNext { get; set; } [InputAction(/*Could not decode attribute arguments.*/)] public InputAction PagePrev { get; set; } [InputAction(/*Could not decode attribute arguments.*/)] public InputAction PageNext { get; set; } [InputAction(/*Could not decode attribute arguments.*/)] public InputAction HackSubmitEnter { get; set; } [InputAction(/*Could not decode attribute arguments.*/)] public InputAction HackSubmitNumpadEnter { get; set; } [InputAction("/leftButton", Name = "CCTV Ping")] public InputAction PingMarker { get; set; } [InputAction(/*Could not decode attribute arguments.*/)] public InputAction WalkiePushToTalk { get; set; } [InputAction("/h", Name = "CCTV Toggle Controls Overlay")] public InputAction ToggleControlsOverlayKey { get; set; } } internal sealed class MainframeAudio : MonoBehaviour { private const string AudioSubfolder = "Mainframe"; private static readonly string[] AudioExtensions = new string[3] { ".wav", ".ogg", ".mp3" }; private const float ScreenTransitionVolume = 0.55f; private const float PowerOffVolume = 0.55f; private const float NavigateVolume = 0.35f; private const float SelectVolume = 0.48f; private const float TypingVolume = 0.4f; private const float HackStartVolume = 0.55f; private const float HackProgressVolume = 0.45f; private const float HackSuccessVolume = 0.65f; private const float HackFailVolume = 0.6f; private const float FanLoopVolume = 0.09f; private const float IdleBeepVolume = 0.16f; private const float FanMinDistance = 1.5f; private const float FanMaxDistance = 14f; private const float IdleBeepMinInterval = 6f; private const float IdleBeepMaxInterval = 12f; private AudioSource _oneShot; private AudioSource _fanLoopSource; private AudioClip _screenTransition; private AudioClip _powerOff; private AudioClip _fanLoop; private AudioClip _idleBeep; private AudioClip _hackStart; private AudioClip _hackSuccess; private AudioClip _beepIncorrect; private readonly AudioClip[] _beeps = (AudioClip[])(object)new AudioClip[3]; private readonly AudioClip[] _typeClips = (AudioClip[])(object)new AudioClip[3]; private AudioClip _vanillaTypeClip; private int _typeRoundRobin; private int _lastBeepIndex = -1; private bool _idleActive; private float _nextIdleBeepAt; internal static MainframeAudio Current { get; private set; } internal static MainframeAudio Ensure(Transform parent) { //IL_0023: 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) if ((Object)(object)parent == (Object)null) { return null; } MainframeAudio componentInChildren = ((Component)parent).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { return componentInChildren; } GameObject val = new GameObject("MainframeAudioHub"); val.transform.SetParent(parent, false); return val.AddComponent(); } private void Awake() { Current = this; _oneShot = ((Component)this).gameObject.AddComponent(); ConfigureSource(_oneShot, loop: false, 0f); _fanLoopSource = ((Component)this).gameObject.AddComponent(); ConfigureSource(_fanLoopSource, loop: true, 1f); _fanLoopSource.volume = 0.09f; _fanLoopSource.minDistance = 1.5f; _fanLoopSource.maxDistance = 14f; TryResolveVanillaTypingClip(); ((MonoBehaviour)this).StartCoroutine(LoadAllClips()); } private void OnEnable() { StartFanLoop(); } private void OnDisable() { StopIdle(); if ((Object)(object)_fanLoopSource != (Object)null && _fanLoopSource.isPlaying) { _fanLoopSource.Stop(); } } private void OnDestroy() { if (Current == this) { Current = null; } } private void Update() { if (_idleActive && !((Object)(object)_idleBeep == (Object)null) && Time.unscaledTime >= _nextIdleBeepAt) { PlayOneShot(_idleBeep, 0.16f); ScheduleNextIdleBeep(); } } internal void PlayScreenTransition() { PlayOneShot(_screenTransition, 0.55f); } internal void PlayPowerOff() { PlayOneShot(_powerOff, 0.55f); } internal void PlayNavigate() { PlayOneShot(NextBeep(), 0.35f); } internal void PlaySelect() { PlayOneShot(NextBeep(), 0.48f); } internal void PlayHackStart() { PlayOneShot(_hackStart, 0.55f); } internal void PlayHackSuccess() { PlayOneShot(_hackSuccess, 0.65f); } internal void PlayHackFail() { PlayOneShot(_beepIncorrect, 0.6f); } internal void PlayHackProgress() { PlayOneShot(((Object)(object)_beeps[2] != (Object)null) ? _beeps[2] : NextBeep(), 0.45f); } internal void PlayLockedOut() { PlayOneShot(_beepIncorrect, 0.6f); } internal void PlayTyping() { if ((Object)(object)_vanillaTypeClip != (Object)null) { PlayOneShot(_vanillaTypeClip, 0.4f); return; } AudioClip clip = null; for (int i = 0; i < _typeClips.Length; i++) { int num = (_typeRoundRobin + i) % _typeClips.Length; if ((Object)(object)_typeClips[num] != (Object)null) { clip = _typeClips[num]; _typeRoundRobin = (num + 1) % _typeClips.Length; break; } } PlayOneShot(clip, 0.4f); } internal void StartIdle() { Current = this; _idleActive = true; ScheduleNextIdleBeep(); StartFanLoop(); } internal void StopIdle() { _idleActive = false; } private AudioClip NextBeep() { int num = 0; for (int i = 0; i < _beeps.Length; i++) { if ((Object)(object)_beeps[i] != (Object)null) { num++; } } if (num == 0) { return null; } for (int j = 0; j < 8; j++) { int num2 = Random.Range(0, _beeps.Length); if (!((Object)(object)_beeps[num2] == (Object)null) && (num2 != _lastBeepIndex || num <= 1)) { _lastBeepIndex = num2; return _beeps[num2]; } } for (int k = 0; k < _beeps.Length; k++) { if ((Object)(object)_beeps[k] != (Object)null) { _lastBeepIndex = k; return _beeps[k]; } } return null; } private void StartFanLoop() { if (!((Object)(object)_fanLoopSource == (Object)null) && !((Object)(object)_fanLoop == (Object)null) && !_fanLoopSource.isPlaying) { _fanLoopSource.clip = _fanLoop; _fanLoopSource.volume = 0.09f; _fanLoopSource.Play(); } } private void PlayOneShot(AudioClip clip, float volumeScale) { if ((Object)(object)clip == (Object)null || (Object)(object)_oneShot == (Object)null) { return; } try { _oneShot.PlayOneShot(clip, Mathf.Clamp01(volumeScale)); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV][MainframeAudio] PlayOneShot failed for '" + ((Object)clip).name + "': " + ex.Message)); } } } private void ScheduleNextIdleBeep() { _nextIdleBeepAt = Time.unscaledTime + Random.Range(6f, 12f); } private static void ConfigureSource(AudioSource source, bool loop, float spatialBlend) { source.playOnAwake = false; source.loop = loop; source.spatialBlend = spatialBlend; source.volume = 1f; source.dopplerLevel = 0f; source.rolloffMode = (AudioRolloffMode)1; } private void TryResolveVanillaTypingClip() { try { Terminal val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null) { return; } FieldInfo[] fields = ((object)val).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { string text = fieldInfo.Name.ToLowerInvariant(); bool flag = text.Contains("key") || text.Contains("type") || text.Contains("click"); if (fieldInfo.FieldType == typeof(AudioClip) && flag) { object? value = fieldInfo.GetValue(val); AudioClip val2 = (AudioClip)((value is AudioClip) ? value : null); if (val2 != null) { _vanillaTypeClip = val2; break; } } else if (fieldInfo.FieldType == typeof(AudioClip[]) && flag && fieldInfo.GetValue(val) is AudioClip[] array && array.Length != 0 && (Object)(object)array[0] != (Object)null) { _vanillaTypeClip = array[0]; break; } } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][MainframeAudio] Vanilla typing clip " + (((Object)(object)_vanillaTypeClip != (Object)null) ? ("resolved '" + ((Object)_vanillaTypeClip).name + "'.") : "not found; using generated keystroke clicks."))); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogDebug((object)("[LethalCCTV][MainframeAudio] Vanilla typing clip scan failed: " + ex.Message)); } } } private IEnumerator LoadAllClips() { yield return LoadClip("Idle_FanLoop", delegate(AudioClip c) { _fanLoop = c; }); StartFanLoop(); yield return LoadClip("Screen_Transition", delegate(AudioClip c) { _screenTransition = c; }); yield return LoadClip("Menu_PowerOff", delegate(AudioClip c) { _powerOff = c; }); yield return LoadClip("Beep_01", delegate(AudioClip c) { _beeps[0] = c; }); yield return LoadClip("Beep_02", delegate(AudioClip c) { _beeps[1] = c; }); yield return LoadClip("Beep_03", delegate(AudioClip c) { _beeps[2] = c; }); yield return LoadClip("Beep_Incorrect", delegate(AudioClip c) { _beepIncorrect = c; }); yield return LoadClip("Idle_Beep", delegate(AudioClip c) { _idleBeep = c; }); yield return LoadClip("Hack_Start", delegate(AudioClip c) { _hackStart = c; }); yield return LoadClip("Hack_Success", delegate(AudioClip c) { _hackSuccess = c; }); yield return LoadClip("Type_01", delegate(AudioClip c) { _typeClips[0] = c; }); yield return LoadClip("Type_02", delegate(AudioClip c) { _typeClips[1] = c; }); yield return LoadClip("Type_03", delegate(AudioClip c) { _typeClips[2] = c; }); } private IEnumerator LoadClip(string baseName, Action assign) { string path = ResolveAudioPath(baseName); if (string.IsNullOrEmpty(path)) { yield break; } UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(new Uri(path).AbsoluteUri, AudioTypeFor(path)); try { yield return request.SendWebRequest(); if ((int)request.result != 1) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeAudio] Failed loading '" + path + "': " + request.error)); } yield break; } AudioClip content = DownloadHandlerAudioClip.GetContent(request); if ((Object)(object)content != (Object)null) { ((Object)content).name = "Mainframe_" + baseName; assign?.Invoke(content); yield break; } ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][MainframeAudio] Loaded '" + path + "' returned a null AudioClip.")); } } finally { ((IDisposable)request)?.Dispose(); } } private static AudioType AudioTypeFor(string path) { string extension = Path.GetExtension(path); if (!string.Equals(extension, ".wav", StringComparison.OrdinalIgnoreCase)) { if (!string.Equals(extension, ".ogg", StringComparison.OrdinalIgnoreCase)) { return (AudioType)13; } return (AudioType)14; } return (AudioType)20; } private static string ResolveAudioPath(string baseName) { string directoryName = Path.GetDirectoryName(typeof(MainframeAudio).Assembly.Location); string path = ResolveLoadedAssemblyDirectory("Y4NGZCompany") ?? Path.Combine(Paths.PluginPath, "Contracted"); string[] array = new string[7] { Path.Combine(path, "ContractAudio", "Mainframe"), Path.Combine(Paths.PluginPath, "Contracted", "ContractAudio", "Mainframe"), Path.Combine(directoryName ?? string.Empty, "ContractAudio", "Mainframe"), Path.Combine(Paths.PluginPath, "y4ngz-Y4NGZCompany", "ContractAudio", "Mainframe"), Path.Combine(Paths.PluginPath, "y4ngz-Y4NGZUpgrades", "ContractAudio", "Mainframe"), Path.Combine(Paths.PluginPath, "ContractAudio", "Mainframe"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ContractAudio", "Mainframe") }; for (int i = 0; i < array.Length; i++) { for (int j = 0; j < AudioExtensions.Length; j++) { string text = Path.Combine(array[i], baseName + AudioExtensions[j]); if (File.Exists(text)) { return text; } } } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeAudio] Audio missing: ContractAudio/Mainframe/" + baseName + ".*")); } return null; } private static string ResolveLoadedAssemblyDirectory(string simpleName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { if (string.Equals(assembly.GetName().Name, simpleName, StringComparison.OrdinalIgnoreCase)) { string location = assembly.Location; if (!string.IsNullOrEmpty(location)) { return Path.GetDirectoryName(location); } } } catch (Exception) { } } return null; } } internal sealed class MainframeControlOverlay { private enum View { Menu, Storage, StashCodes, ScrapCheck, SystemChecks, CctvSecurity, ProtocolLockdown, Intercom } private const float DesignHeight = 356f; private const float ContentInset = 22f; private const float StatusColumnFraction = 0.533f; private const float MenuColumnFraction = 0.47f; private const float ColumnGap = 8f; private const string IdleTransmitLabel = "[ TRANSMIT - HOLD ]"; private const string HeldTransmitLabel = "[ TRANSMITTING ]"; private static readonly Color ScreenBlack = new Color(0.003f, 0.012f, 0.006f, 0.98f); private static readonly Color ScreenGreen = new Color(0.16f, 1f, 0.34f, 1f); private static readonly Color ScreenGreenDim = new Color(0.16f, 0.78f, 0.34f, 1f); private static readonly Color ScreenAmber = new Color(0.92f, 0.82f, 0.3f, 1f); private static readonly Color ScreenRed = new Color(1f, 0.28f, 0.2f, 1f); private static readonly Color ScreenAmberFill = new Color(0.36f, 0.3f, 0.06f, 1f); private Transform _parent; private readonly List _textElements = new List(16); private GameObject _root; private RectTransform _rootRect; private RectTransform _frameTopRect; private RectTransform _frameBottomRect; private RectTransform _frameLeftRect; private RectTransform _frameRightRect; private TextMeshProUGUI _titleText; private TextMeshProUGUI _menuText; private TextMeshProUGUI _bodyText; private TextMeshProUGUI _statusText; private TextMeshProUGUI _helpText; private RectTransform _intercomButtonRect; private Image _intercomButtonBorder; private Image _intercomButtonFill; private TextMeshProUGUI _intercomButtonLabel; private MainframeIntercomPushButton _intercomButtonInput; private Texture2D _scanlineTexture; private Sprite _scanlineSprite; private Material _terminalFontMaterial; private Color _accentColor = ScreenGreen; private Color _dimColor = ScreenGreenDim; private float _designWidth = 680f; private Component _mainframeComponent; private MainframeSupport _mainframe; private View _view; private int _selectedIndex; private bool _isOpen; private bool _pttKeyHeld; private bool _pttPointerHeld; private bool _intercomSpeaking; private int _openedFrame; private float _inputArmedAt; private string _terminalBeforeOpen; internal bool IsOpen => _isOpen; internal int ViewToken => (int)_view; internal bool IsIntercomActive { get { if (_isOpen) { return _view == View.Intercom; } return false; } } internal GameObject RootObject { get { EnsureBuilt(); return _root; } } internal MainframeControlOverlay(Transform parent) { //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_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) _parent = parent; } internal void EnsureBuilt() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_019e: 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_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_0208: 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_021c: 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_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root != (Object)null)) { _root = new GameObject("LethalCCTV_MainframeControlTerminal"); _root.transform.SetParent(_parent, false); CanvasGroup obj = _root.AddComponent(); obj.blocksRaycasts = true; obj.interactable = true; _rootRect = _root.AddComponent(); _rootRect.anchorMin = new Vector2(0.5f, 0.5f); _rootRect.anchorMax = new Vector2(0.5f, 0.5f); _rootRect.pivot = new Vector2(0.5f, 0.5f); _rootRect.anchoredPosition = Vector2.zero; _rootRect.sizeDelta = new Vector2(_designWidth, 356f); Image obj2 = ((Component)CreateRect(_root.transform, "CRTBackdrop", Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f))).gameObject.AddComponent(); ((Graphic)obj2).color = new Color(0f, 0f, 0f, 0.64f); ((Graphic)obj2).raycastTarget = false; RectTransform val = CreateRect(_root.transform, "TerminalPanel", Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f)); Image obj3 = ((Component)val).gameObject.AddComponent(); ((Graphic)obj3).color = ScreenBlack; ((Graphic)obj3).raycastTarget = false; CreateFrame(val); _titleText = CreateText((Transform)(object)val, "Title", "Y4NGZ MAINFRAME OS\nACCESS GRANTED", 19f, (TextAlignmentOptions)257, ScreenGreen, new Vector2(22f, -14f), Vector2.zero); _statusText = CreateText((Transform)(object)val, "Status", "SELECT FUNCTION", 16f, (TextAlignmentOptions)260, ScreenGreen, Vector2.zero, Vector2.zero); _menuText = CreateText((Transform)(object)val, "Menu", "", 18f, (TextAlignmentOptions)257, ScreenGreen, new Vector2(22f, -96f), Vector2.zero); ((TMP_Text)_menuText).lineSpacing = 7f; _bodyText = CreateText((Transform)(object)val, "Body", "", 15.5f, (TextAlignmentOptions)257, ScreenGreenDim, Vector2.zero, Vector2.zero); ((TMP_Text)_bodyText).lineSpacing = 5f; ((TMP_Text)_bodyText).enableWordWrapping = true; _helpText = CreateText((Transform)(object)val, "Help", "ARROWS ENTER ESC", 12.5f, (TextAlignmentOptions)514, ScreenGreenDim, new Vector2(22f, -331f), Vector2.zero); CreateIntercomButton(val); CreateScanlines(_root.transform); ApplyLayout(); _root.SetActive(false); } } internal void SetDock(Vector2 anchoredPosition, Vector2 sizeDelta) { //IL_001b: 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_0048: Unknown result type (might be due to invalid IL or missing references) EnsureBuilt(); if (!((Object)(object)_rootRect == (Object)null)) { if (CrtDockLayout.TryResolveDock(_rootRect, anchoredPosition, sizeDelta, _designWidth, out var designWidth, out var scale)) { _designWidth = designWidth; ApplyLayout(); } ((Transform)_rootRect).localScale = new Vector3(scale, scale, 1f); } } private void ApplyLayout() { //IL_003e: 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_00ba: 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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_rootRect == (Object)null)) { float designWidth = _designWidth; float num = 22f; float num2 = designWidth - 22f; float num3 = Mathf.Max(120f, num2 - num); _rootRect.sizeDelta = new Vector2(designWidth, 356f); CrtDockLayout.ResizeFrame(designWidth, _frameTopRect, _frameBottomRect, _frameLeftRect, _frameRightRect); if ((Object)(object)_titleText != (Object)null) { ((TMP_Text)_titleText).rectTransform.sizeDelta = new Vector2(num3, 52f); } if ((Object)(object)_statusText != (Object)null) { float num4 = num + num3 * 0.533f; ((TMP_Text)_statusText).rectTransform.anchoredPosition = new Vector2(num4, -62f); ((TMP_Text)_statusText).rectTransform.sizeDelta = new Vector2(num2 - num4, 26f); } float num5 = num3 * 0.47f; if ((Object)(object)_menuText != (Object)null) { ((TMP_Text)_menuText).rectTransform.sizeDelta = new Vector2(num5, 214f); } if ((Object)(object)_bodyText != (Object)null) { float num6 = num + num5 + 8f; ((TMP_Text)_bodyText).rectTransform.anchoredPosition = new Vector2(num6, -96f); ((TMP_Text)_bodyText).rectTransform.sizeDelta = new Vector2(Mathf.Max(120f, num2 - num6), 214f); } if ((Object)(object)_helpText != (Object)null) { ((TMP_Text)_helpText).rectTransform.sizeDelta = new Vector2(num3, 17f); } if ((Object)(object)_intercomButtonRect != (Object)null) { _intercomButtonRect.anchoredPosition = new Vector2(num, -134f); _intercomButtonRect.sizeDelta = new Vector2(num5, 42f); } } } internal void SetParent(Transform parent) { if (!((Object)(object)parent == (Object)null)) { EnsureBuilt(); _parent = parent; if ((Object)(object)_root.transform.parent != (Object)(object)parent) { _root.transform.SetParent(parent, false); } _root.transform.SetAsLastSibling(); } } internal void Open(Component mainframeComponent) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) EnsureBuilt(); if (!((Object)(object)mainframeComponent == (Object)null)) { _terminalBeforeOpen = DescribeShipTerminal(); ApplyTerminalStyle(); _mainframeComponent = mainframeComponent; _mainframe = (mainframeComponent as MainframeSupport) ?? mainframeComponent.GetComponent() ?? MainframeSupport.Active; _view = View.Menu; _selectedIndex = 0; ClearPushToTalkSources(); _openedFrame = Time.frameCount; _inputArmedAt = Time.unscaledTime + 0.18f; _isOpen = true; _root.SetActive(true); Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; SetStatus("SELECT FUNCTION", _accentColor); Refresh(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][MainframeControl] OPENED " + $"component='{((object)mainframeComponent).GetType().FullName}' instance={((Object)mainframeComponent).GetInstanceID()} " + "shipTerminalBefore=" + _terminalBeforeOpen + ".")); } } } internal void Close() { Close("unspecified"); } internal void Close(string reason) { if (!_isOpen) { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } return; } ClearPushToTalkSources(); if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } string text = DescribeShipTerminal(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][MainframeControl] CLOSED reason='" + (reason ?? "unspecified") + "' " + $"shipTerminalUnchanged={string.Equals(text, _terminalBeforeOpen, StringComparison.Ordinal)} terminalNow={text}.")); } _isOpen = false; _mainframeComponent = null; _mainframe = null; _view = View.Menu; _selectedIndex = 0; RefreshIntercomButton(); Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; } internal void Tick() { if (_isOpen && (_view == View.Menu || _view == View.SystemChecks)) { RefreshMenu(); } } internal bool ConsumeEscapeIfOpen() { if (!_isOpen) { return false; } if (_view == View.Menu) { Close("escape"); return true; } BackOneLevel(); Refresh(); return true; } internal bool NavigateUp(string source) { return Move(-1, source); } internal bool NavigateDown(string source) { return Move(1, source); } internal bool NavigateLeft(string source) { return false; } internal bool NavigateRight(string source) { return false; } internal bool Submit(string source) { if (!IsInputArmed()) { return false; } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV][MainframeControl] ACTIVATE view={_view} item={_selectedIndex} source='{source}'."); } switch (_view) { case View.Menu: return ActivateRoot(); case View.Storage: return ActivateStorage(); case View.SystemChecks: return ActivateSystemChecks(); case View.ProtocolLockdown: return ActivateProtocol("LockdownDrill", "LOCKDOWN DRILL"); case View.StashCodes: case View.ScrapCheck: case View.CctvSecurity: case View.Intercom: BackOneLevel(); Refresh(); return true; default: return false; } } internal void SetPushToTalk(bool held) { if (_pttKeyHeld != held) { _pttKeyHeld = held; RecomputeIntercomSpeaking(); } } internal void SetPointerPushToTalk(bool held) { if (_pttPointerHeld != held) { _pttPointerHeld = held; RecomputeIntercomSpeaking(); } } private void ClearPushToTalkSources() { _pttKeyHeld = false; _pttPointerHeld = false; RecomputeIntercomSpeaking(); } private void RecomputeIntercomSpeaking() { SetIntercomSpeaking(IsIntercomActive && (_pttKeyHeld || _pttPointerHeld)); } private bool ActivateRoot() { switch (_selectedIndex) { case 0: EnterView(View.Storage, "STORAGE"); return true; case 1: EnterView(View.SystemChecks, "SYSTEM CHECKS"); return true; case 2: EnterView(View.Intercom, "INTERCOM"); return true; case 3: Close("exit-item"); return true; default: return false; } } private bool ActivateStorage() { switch (_selectedIndex) { case 0: EnterView(View.StashCodes, "STASH CODES"); return true; case 1: EnterView(View.ScrapCheck, "SCRAP CHECK"); return true; case 2: EnterView(View.Menu, "SELECT FUNCTION"); return true; default: return false; } } private bool ActivateSystemChecks() { switch (_selectedIndex) { case 0: ToggleAlarm(); Refresh(); return true; case 1: EnterView(View.CctvSecurity, "CCTV SECURITY"); return true; case 2: EnterView(View.ProtocolLockdown, "LOCKDOWN"); return true; case 3: EnterView(View.Menu, "SELECT FUNCTION"); return true; default: return false; } } private bool ActivateProtocol(string eventName, string displayName) { //IL_0061: 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 (_selectedIndex == 2) { EnterView(View.SystemChecks, "SYSTEM CHECKS"); return true; } bool flag = InvokeMainframeProtocol((_selectedIndex == 0) ? "BeginManualEvent" : "EndManualEvent", eventName); SetStatus(((!flag) ? "OFFLINE " : ((_selectedIndex == 0) ? "BEGIN " : "END ")) + displayName, flag ? ScreenAmber : ScreenRed); RefreshBody(); return true; } private void EnterView(View view, string status) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) ClearPushToTalkSources(); _view = view; _selectedIndex = 0; SetStatus(status, _accentColor); Refresh(); } private void BackOneLevel() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) ClearPushToTalkSources(); switch (_view) { case View.StashCodes: case View.ScrapCheck: _view = View.Storage; break; case View.CctvSecurity: case View.ProtocolLockdown: _view = View.SystemChecks; break; default: _view = View.Menu; break; } _selectedIndex = 0; SetStatus((_view == View.Menu) ? "SELECT FUNCTION" : HeaderForView(_view), _accentColor); } private bool Move(int delta, string source) { if (!IsInputArmed()) { return false; } int num = CurrentItemCount(); if (num <= 0) { return false; } _selectedIndex = ((_selectedIndex + delta) % num + num) % num; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV][MainframeControl] SELECT view={_view} item={_selectedIndex} source='{source}'."); } Refresh(); return true; } private int CurrentItemCount() { return _view switch { View.Menu => 4, View.Storage => 3, View.SystemChecks => 4, View.ProtocolLockdown => 3, _ => 0, }; } private void ToggleAlarm() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0082: 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_00cc: Unknown result type (might be due to invalid IL or missing references) bool flag = !IsAlarmOn(); bool flag2 = false; try { if ((Object)(object)_mainframe != (Object)null) { _mainframe.SetAlarmServerRpc(flag); flag2 = true; } else if ((Object)(object)_mainframeComponent != (Object)null) { MethodInfo method = ((object)_mainframeComponent).GetType().GetMethod("SetAlarmServerRpc", BindingFlags.Instance | BindingFlags.Public); if (method != null) { method.Invoke(_mainframeComponent, new object[2] { flag, (object)default(ServerRpcParams) }); flag2 = true; } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeControl] Alarm toggle RPC failed: " + ex.Message)); } } SetStatus(flag ? "ALARM ENGAGED" : "ALARM SILENCED", flag ? ScreenAmber : _accentColor); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV][MainframeControl] ALARM_TOGGLE target={flag} invoked={flag2}."); } } private bool IsAlarmOn() { if ((Object)(object)_mainframe != (Object)null) { return _mainframe.IsAlarmOn; } return CctvSupportApi.IsAlarmActive; } private static bool InvokeMainframeProtocol(string methodName, string eventName) { try { Type type = FindLoadedType("Y4NGZCompany.Facility.Security.MainframeProtocolDirector"); Type type2 = FindLoadedType("Y4NGZCompany.Facility.Security.MainframeProtocolEvent"); if (type == null || type2 == null) { return false; } object obj = Enum.Parse(type2, eventName); MethodInfo method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { return false; } object obj2 = method.Invoke(null, new object[1] { obj }); bool flag = default(bool); int num; if (obj2 is bool) { flag = (bool)obj2; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeControl] Protocol reflection failed event='" + eventName + "' method='" + methodName + "': " + ex.Message)); } return false; } } private static Type FindLoadedType(string fullName) { Type type = Type.GetType(fullName, throwOnError: false); if (type != null) { return type; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type2 = assemblies[i].GetType(fullName, throwOnError: false); if (type2 != null) { return type2; } } return null; } private void SetIntercomSpeaking(bool speaking) { if (_intercomSpeaking != speaking) { _intercomSpeaking = speaking; CCTVWalkieTalkieBridge.SetLocalSpeaking(speaking); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV][MainframeControl] INTERCOM speaking={speaking}."); } RefreshIntercomButton(); if (_view == View.Intercom) { RefreshBody(); } } } private void Refresh() { RefreshMenu(); RefreshBody(); RefreshHelp(); RefreshIntercomButton(); } private void RefreshMenu() { //IL_0104: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_menuText == (Object)null)) { StringBuilder stringBuilder = new StringBuilder(); switch (_view) { case View.Menu: AppendMenuLine(stringBuilder, 0, "Storage"); AppendMenuLine(stringBuilder, 1, "System Checks"); AppendMenuLine(stringBuilder, 2, "Intercom"); AppendMenuLine(stringBuilder, 3, "EXIT"); break; case View.Storage: AppendMenuLine(stringBuilder, 0, "Stash Codes"); AppendMenuLine(stringBuilder, 1, "Scrap Check"); AppendMenuLine(stringBuilder, 2, "BACK"); break; case View.SystemChecks: AppendMenuLine(stringBuilder, 0, IsAlarmOn() ? "ALARM: ON" : "ALARM: OFF"); AppendMenuLine(stringBuilder, 1, "CCTV SECURITY"); AppendMenuLine(stringBuilder, 2, "Lockdown"); AppendMenuLine(stringBuilder, 3, "BACK"); break; case View.ProtocolLockdown: AppendProtocolMenu(stringBuilder, "Lockdown Drill"); break; default: stringBuilder.Append("ENTER/ESC BACK"); break; } ((TMP_Text)_menuText).text = stringBuilder.ToString(); } } private void AppendProtocolMenu(StringBuilder sb, string label) { AppendMenuLine(sb, 0, "Begin " + label); AppendMenuLine(sb, 1, "End " + label); AppendMenuLine(sb, 2, "BACK"); } private void AppendMenuLine(StringBuilder sb, int index, string label) { //IL_0035: 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) int num; object obj; if (CurrentItemCount() > 0) { num = ((index == _selectedIndex) ? 1 : 0); if (num != 0) { obj = "> "; goto IL_0024; } } else { num = 0; } obj = " "; goto IL_0024; IL_0024: string value = (string)obj; string value2 = ((num != 0) ? ColorHex(_accentColor) : ColorHex(_dimColor)); sb.Append("') .Append(value) .Append(label) .Append("\n"); } private void RefreshBody() { //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) if (!((Object)(object)_bodyText == (Object)null)) { switch (_view) { case View.Menu: ((TMP_Text)_bodyText).text = BuildRootText(); break; case View.Storage: ((TMP_Text)_bodyText).text = BuildStorageText(); break; case View.StashCodes: ((TMP_Text)_bodyText).text = BuildStashCodesText(); break; case View.ScrapCheck: ((TMP_Text)_bodyText).text = "SCRAP CHECK\n\nTOTAL VALUE: OFFLINE\nITEM COUNT: OFFLINE\n\nINVENTORY INDEX\nNOT MOUNTED."; break; case View.SystemChecks: ((TMP_Text)_bodyText).text = BuildSystemChecksText(); break; case View.CctvSecurity: ((TMP_Text)_bodyText).text = BuildSecurityText(); break; case View.ProtocolLockdown: ((TMP_Text)_bodyText).text = BuildProtocolText("LOCKDOWN DRILL", "Cycles containment gates\nfor a drill window."); break; case View.Intercom: ((TMP_Text)_bodyText).text = BuildIntercomText(); break; } } } private string BuildRootText() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return "MAINFRAME ONLINE\n\nStorage stash records\nChecks alarm + security\nIntercom broadcast\nEXIT leave OS"; } private string BuildStorageText() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) return "STORAGE\n\nStash Codes company codes\nScrap Check offline\n\nENTER SELECT ESC BACK"; } private string BuildSystemChecksText() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) return "SYSTEM CHECKS\n\nALARM: " + (IsAlarmOn() ? "ON" : "OFF") + "\nCCTV SECURITY console\nLockdown drill\n\nENTER SELECT ESC BACK"; } private string BuildProtocolText(string title, string description) { //IL_0012: 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) return "" + title + "\n\n" + description + "\n\nENTER SELECT ESC BACK"; } private string BuildStashCodesText() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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) IReadOnlyList mainframeControlStashCodes = CctvSupportApi.MainframeControlStashCodes; StringBuilder stringBuilder = new StringBuilder("STASH CODES\n\n"); if (mainframeControlStashCodes == null || mainframeControlStashCodes.Count == 0) { stringBuilder.Append("NO CODES ON FILE."); } else { for (int i = 0; i < mainframeControlStashCodes.Count; i++) { stringBuilder.Append(" ") .Append(CctvSupportApi.FormatStashCode(mainframeControlStashCodes[i])) .Append("\n"); } } stringBuilder.Append("\nENTER/ESC BACK"); return stringBuilder.ToString(); } private string BuildSecurityText() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) string text = (CctvSupportApi.IsMainframeHacked ? "OFFLINE" : "ARMED"); string text2 = (CctvSupportApi.IsTimedSecurityAlarmActive ? ("ALARM " + CctvSupportApi.SecurityAlarmRemaining.ToString("0") + "s") : "NO ALARM"); return "CCTV SECURITY\n\nCAMERAS: " + text + "\nSTATUS: " + text2 + "\n\nHACK DISABLES CAMERA\nDETECTION AND EVENTS."; } private string BuildIntercomText() { //IL_0029: 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_004f: 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) string text = (_intercomSpeaking ? (">> TRANSMITTING <<<") : ("IDLE")); return "INTERCOM\n\nHOLD PUSH-TO-TALK TO\nBROADCAST FACILITY-WIDE.\n\nSTATUS: " + text + "\n\nENTER/ESC BACK"; } private void RefreshHelp() { if (!((Object)(object)_helpText == (Object)null)) { ((TMP_Text)_helpText).text = ((_view == View.Menu) ? "ARROWS MOVE ENTER OK ESC EXIT" : "ARROWS MOVE ENTER OK ESC BACK"); } } private static string HeaderForView(View view) { return view switch { View.Storage => "STORAGE", View.SystemChecks => "SYSTEM CHECKS", View.Intercom => "INTERCOM", _ => "SELECT FUNCTION", }; } private void SetStatus(string text, Color color) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_statusText == (Object)null)) { ((TMP_Text)_statusText).text = text ?? string.Empty; ((Graphic)_statusText).color = color; } } private bool IsInputArmed() { if (Time.frameCount > _openedFrame) { return Time.unscaledTime >= _inputArmedAt; } return false; } private void ApplyTerminalStyle() { //IL_00af: 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_00c4: Expected O, but got Unknown TMP_FontAsset val = null; Material val2 = null; try { Terminal val3 = Object.FindObjectOfType(); TMP_Text val4 = (((Object)(object)val3 != (Object)null) ? (ReadTmp(val3, "topRightText") ?? ReadTmp(val3, "inputFieldText")) : null); if ((Object)(object)val4 == (Object)null && HUDManager.Instance?.controlTipLines != null && HUDManager.Instance.controlTipLines.Length != 0) { val4 = (TMP_Text)(object)HUDManager.Instance.controlTipLines[0]; } if ((Object)(object)val4 != (Object)null) { val = val4.font; val2 = val4.fontSharedMaterial; } else { val = TMP_Settings.defaultFontAsset; } } catch { } if ((Object)(object)val2 != (Object)null) { if ((Object)(object)_terminalFontMaterial != (Object)null) { Object.Destroy((Object)(object)_terminalFontMaterial); } _terminalFontMaterial = new Material(val2) { name = "LethalCCTV_MainframeControl_FontMat" }; CrtDockLayout.ApplyLowResFaceThickening(_terminalFontMaterial); } for (int i = 0; i < _textElements.Count; i++) { TextMeshProUGUI val5 = _textElements[i]; if (!((Object)(object)val5 == (Object)null)) { if ((Object)(object)val != (Object)null) { ((TMP_Text)val5).font = val; } if ((Object)(object)_terminalFontMaterial != (Object)null) { ((TMP_Text)val5).fontSharedMaterial = _terminalFontMaterial; } } } } private static TMP_Text ReadTmp(object target, string memberName) { if (target == null) { return null; } object obj = target.GetType().GetField(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(target); TMP_Text val = (TMP_Text)((obj is TMP_Text) ? obj : null); if (val != null) { return val; } TMP_InputField val2 = (TMP_InputField)((obj is TMP_InputField) ? obj : null); if (val2 != null) { return val2.textComponent; } return null; } private static string DescribeShipTerminal() { try { Terminal val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null) { return "{terminal=}"; } return "{id=" + ((Object)val).GetInstanceID() + " inUse=" + val.terminalInUse + " credits=" + val.groupCredits + "}"; } catch { return "{terminal=}"; } } private void CreateIntercomButton(RectTransform parent) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00ba: 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_010d: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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) _intercomButtonRect = CreateRect((Transform)(object)parent, "IntercomPushToTalk", new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(0f, 1f)); GameObject gameObject = ((Component)_intercomButtonRect).gameObject; _intercomButtonBorder = gameObject.AddComponent(); ((Graphic)_intercomButtonBorder).raycastTarget = true; _intercomButtonInput = gameObject.AddComponent(); _intercomButtonInput.HoldChanged = OnIntercomButtonHoldChanged; RectTransform val = CreateRect(gameObject.transform, "Fill", Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f)); val.offsetMin = new Vector2(2f, 2f); val.offsetMax = new Vector2(-2f, -2f); _intercomButtonFill = ((Component)val).gameObject.AddComponent(); ((Graphic)_intercomButtonFill).raycastTarget = false; _intercomButtonLabel = CreateText((Transform)(object)val, "Label", "[ TRANSMIT - HOLD ]", 14f, (TextAlignmentOptions)514, ScreenGreenDim, Vector2.zero, Vector2.zero); RectTransform rectTransform = ((TMP_Text)_intercomButtonLabel).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; gameObject.SetActive(false); RefreshIntercomButton(); } private void OnIntercomButtonHoldChanged(bool held) { SetPointerPushToTalk(held); } private void RefreshIntercomButton() { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_intercomButtonRect == (Object)null) { return; } GameObject gameObject = ((Component)_intercomButtonRect).gameObject; bool isIntercomActive = IsIntercomActive; if (gameObject.activeSelf != isIntercomActive) { gameObject.SetActive(isIntercomActive); } if (isIntercomActive) { if ((Object)(object)_intercomButtonBorder != (Object)null) { ((Graphic)_intercomButtonBorder).color = (Color)(_intercomSpeaking ? ScreenAmber : new Color(_dimColor.r, _dimColor.g, _dimColor.b, 0.75f)); } if ((Object)(object)_intercomButtonFill != (Object)null) { ((Graphic)_intercomButtonFill).color = (_intercomSpeaking ? ScreenAmberFill : ScreenBlack); } if ((Object)(object)_intercomButtonLabel != (Object)null) { ((Graphic)_intercomButtonLabel).color = (_intercomSpeaking ? ScreenAmber : _dimColor); ((TMP_Text)_intercomButtonLabel).text = (_intercomSpeaking ? "[ TRANSMITTING ]" : "[ TRANSMIT - HOLD ]"); ((TMP_Text)_intercomButtonLabel).rectTransform.anchoredPosition = (Vector2)(_intercomSpeaking ? new Vector2(0f, -1f) : Vector2.zero); } } } private void CreateFrame(RectTransform parent) { //IL_0012: 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_0026: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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) _frameTopRect = CreateLine(parent, "FrameTop", new Vector2(0.5f, 1f), new Vector2(0f, -8f), Vector2.zero); _frameBottomRect = CreateLine(parent, "FrameBottom", new Vector2(0.5f, 0f), new Vector2(0f, 8f), Vector2.zero); _frameLeftRect = CreateLine(parent, "FrameLeft", new Vector2(0f, 0.5f), new Vector2(10f, 0f), Vector2.zero); _frameRightRect = CreateLine(parent, "FrameRight", new Vector2(1f, 0.5f), new Vector2(-10f, 0f), Vector2.zero); } private RectTransform CreateLine(RectTransform parent, string name, Vector2 anchor, Vector2 anchoredPos, Vector2 size) { //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_0013: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0068: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent((Transform)(object)parent, false); RectTransform val2 = val.AddComponent(); val2.anchorMin = anchor; val2.anchorMax = anchor; val2.pivot = anchor; val2.anchoredPosition = anchoredPos; val2.sizeDelta = size; Image obj = val.AddComponent(); ((Graphic)obj).color = new Color(ScreenGreen.r, ScreenGreen.g, ScreenGreen.b, 0.34f); ((Graphic)obj).raycastTarget = false; return val2; } private void CreateScanlines(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) _scanlineTexture = new Texture2D(1, 4, (TextureFormat)4, false) { name = "LethalCCTV_MainframeControl_Scanlines", filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)0 }; _scanlineTexture.SetPixel(0, 0, new Color(0f, 0f, 0f, 0f)); _scanlineTexture.SetPixel(0, 1, new Color(0f, 0.2f, 0.06f, 0.1f)); _scanlineTexture.SetPixel(0, 2, new Color(0f, 0f, 0f, 0.1f)); _scanlineTexture.SetPixel(0, 3, new Color(0f, 0.45f, 0.12f, 0.08f)); _scanlineTexture.Apply(false, true); _scanlineSprite = Sprite.Create(_scanlineTexture, new Rect(0f, 0f, 1f, 4f), new Vector2(0.5f, 0.5f)); Image obj = ((Component)CreateRect(parent, "Scanlines", Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f))).gameObject.AddComponent(); obj.sprite = _scanlineSprite; obj.type = (Type)2; ((Graphic)obj).color = Color.white; ((Graphic)obj).raycastTarget = false; } private TextMeshProUGUI CreateText(Transform parent, string name, string text, float size, TextAlignmentOptions alignment, Color color, Vector2 anchoredPosition, Vector2 sizeDelta) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0f, 1f); obj.anchorMax = new Vector2(0f, 1f); obj.pivot = new Vector2(0f, 1f); obj.anchoredPosition = anchoredPosition; obj.sizeDelta = sizeDelta; TextMeshProUGUI val2 = val.AddComponent(); ((TMP_Text)val2).text = text; ((TMP_Text)val2).fontSize = size; ((TMP_Text)val2).alignment = alignment; ((Graphic)val2).color = color; ((TMP_Text)val2).richText = true; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).fontStyle = (FontStyles)1; _textElements.Add(val2); return val2; } private static RectTransform CreateRect(Transform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot) { //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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_003a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = anchorMin; obj.anchorMax = anchorMax; obj.pivot = pivot; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; return obj; } private static string ColorHex(Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ColorUtility.ToHtmlStringRGB(color); } } internal sealed class MainframeInteractionController : MonoBehaviour { private const float InteractRange = 4f; private const float StandRange = 2.45f; private const float AimDot = 0.76f; private const string HackPrompt = "[E] Hack Mainframe"; private const string UsePrompt = "[E] Use Mainframe"; private const string LockoutPrompt = "MAINFRAME LOCKOUT"; private MainframeSupport _mainframe; private MainframeScreenController _screen; private Transform _screenCenter; private Transform _playerRootAnchor; private InputAction _interactAction; private bool _interactActionResolved; private bool _tipActive; private bool _cursorActive; private bool _canUseThisFrame; private string _capturedTipText; private string _activePrompt; private PlayerControllerB _lastPlayer; private MainframeInteractionSession _session; private bool _missingAnchorLogged; private void OnEnable() { ResolveInteractAction(); EnsureInitialized(); } private void Update() { if (_session != null && _session.IsActive) { ClearPromptState(); _session.Tick(); _canUseThisFrame = false; return; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null) { ClearPromptState(); return; } _lastPlayer = val; if (_canUseThisFrame = EnsureInitialized() && IsLookingAtMainframe(val)) { string prompt = CurrentPrompt(); ShowHoverTip(prompt); if (IsInteractPressed()) { HideHoverTip(); HideHoverCursor(val); Activate(val); _canUseThisFrame = false; } } else { ClearPromptState(); } } private void LateUpdate() { if (_session != null && _session.IsActive) { _session.LateTick(); _canUseThisFrame = false; return; } if (_canUseThisFrame && (Object)(object)_lastPlayer != (Object)null) { ShowHoverCursor(_lastPlayer, CurrentPrompt()); } _canUseThisFrame = false; } private bool EnsureInitialized() { if ((Object)(object)_mainframe == (Object)null) { _mainframe = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } if ((Object)(object)_screen == (Object)null) { _screen = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInChildren(true); } if ((Object)(object)_screenCenter == (Object)null) { _screenCenter = FindDeepChild(((Component)this).transform, "MainframeScreenCenter"); } if ((Object)(object)_playerRootAnchor == (Object)null) { _playerRootAnchor = FindDeepChild(((Component)this).transform, "MainframePlayerRootAnchor"); } if (_session == null && (Object)(object)_mainframe != (Object)null && (Object)(object)_screen != (Object)null) { _session = new MainframeInteractionSession((MonoBehaviour)(object)this, ((Component)this).transform, _mainframe, _screen); } int num; if ((Object)(object)_mainframe != (Object)null && (Object)(object)_screen != (Object)null && (Object)(object)_screenCenter != (Object)null) { num = (((Object)(object)_playerRootAnchor != (Object)null) ? 1 : 0); if (num != 0) { goto IL_0132; } } else { num = 0; } if (!_missingAnchorLogged) { _missingAnchorLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log == null) { return (byte)num != 0; } log.LogWarning((object)"[LethalCCTV][MainframeInteract] Missing MainframeSupport, MainframeScreenController, MainframeScreenCenter, or MainframePlayerRootAnchor; physical mainframe interaction disabled."); } goto IL_0132; IL_0132: return (byte)num != 0; } private bool IsLookingAtMainframe(PlayerControllerB player) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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) //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_00c0: Unknown result type (might be due to invalid IL or missing references) Camera val = (((Object)(object)player != (Object)null) ? player.gameplayCamera : null); if ((Object)(object)val == (Object)null || (Object)(object)_screenCenter == (Object)null || (Object)(object)_playerRootAnchor == (Object)null) { return false; } if (!IsPlayerOnInteractionSide(player)) { return false; } Vector3 val2 = ((Component)player).transform.position - _playerRootAnchor.position; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude > 6.0025f) { return false; } Vector3 val3 = _screenCenter.position - ((Component)val).transform.position; float magnitude = ((Vector3)(ref val3)).magnitude; if (magnitude <= 0.05f || magnitude > 4f) { return false; } return Vector3.Dot(((Component)val).transform.forward, val3 / magnitude) >= 0.76f; } private bool IsPlayerOnInteractionSide(PlayerControllerB player) { //IL_0011: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } Vector3 val = ((Component)player).transform.position - ((Component)this).transform.position; val.y = 0f; Vector3 val2 = -((Component)this).transform.forward; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude <= 0.0001f) { return true; } return Vector3.Dot(val, ((Vector3)(ref val2)).normalized) >= -0.15f; } private string CurrentPrompt() { if ((Object)(object)_mainframe != (Object)null && _mainframe.IsLockedOut) { return "MAINFRAME LOCKOUT"; } if (!((Object)(object)_mainframe != (Object)null) || !_mainframe.IsHacked) { return "[E] Hack Mainframe"; } return "[E] Use Mainframe"; } private void Activate(PlayerControllerB player) { if ((Object)(object)_mainframe == (Object)null || (Object)(object)_screen == (Object)null || !IsPlayerOnInteractionSide(player)) { return; } LogInteractionDiagnosticBurst(player, "session-start"); if (_mainframe.IsLockedOut) { HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip("MAINFRAME", $"Trace lockout {_mainframe.LockoutRemaining:0}s.", true, false, "LC_Tip1"); } MainframeAudio.Current?.PlayLockedOut(); } else if ((_session == null || !_session.IsActive) && EnsureInitialized() && _session != null && !_session.Begin(player)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV][MainframeInteract] Mainframe interaction session refused to start."); } } } private void ResolveInteractAction() { if (_interactActionResolved) { return; } _interactActionResolved = true; try { _interactAction = (((Object)(object)InputSystem.actions != (Object)null) ? InputSystem.actions.FindAction("Interact", false) : null); } catch { _interactAction = null; } if (_interactAction == null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV][MainframeInteract] Vanilla 'Interact' InputAction not resolvable; falling back to Keyboard.current.eKey."); } } } private bool IsInteractPressed() { bool flag = false; if (_interactAction != null) { try { flag = _interactAction.WasPressedThisFrame(); } catch { flag = false; } } if (!flag) { if (Keyboard.current != null) { return ((ButtonControl)Keyboard.current.eKey).wasPressedThisFrame; } return false; } return true; } private void StopActiveSession(string reason) { if (_session != null && _session.IsActive) { _session.Stop(reason, returnScreenToIdle: true); } } private short ResolveMainframeYaw() { //IL_0026: 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) return (short)Mathf.RoundToInt(Mathf.Repeat(((Object)(object)_playerRootAnchor != (Object)null) ? _playerRootAnchor.eulerAngles.y : ((Component)this).transform.eulerAngles.y, 360f)); } private void LogInteractionDiagnosticBurst(PlayerControllerB player, string phase) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_019f: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) Camera val = (((Object)(object)player != (Object)null) ? player.gameplayCamera : null); Transform val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform : null); Vector3 vector = Vector3.zero; Vector3 val3 = Vector3.zero; float num = -1f; float num2 = -1f; float num3 = -1f; if ((Object)(object)player != (Object)null && (Object)(object)_playerRootAnchor != (Object)null) { vector = ((Component)player).transform.position - _playerRootAnchor.position; vector.y = 0f; num = ((Vector3)(ref vector)).magnitude; } if ((Object)(object)val2 != (Object)null && (Object)(object)_screenCenter != (Object)null) { val3 = _screenCenter.position - val2.position; num2 = ((Vector3)(ref val3)).magnitude; if (num2 > 0.05f) { num3 = Vector3.Dot(val2.forward, val3 / num2); } } short num4 = ResolveMainframeYaw(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[MainframeDiag.Interact] phase=" + phase + " root='" + GetHierarchyPath(((Component)this).transform) + "' prompt='" + CurrentPrompt() + "' " + $"hacked={(Object)(object)_mainframe != (Object)null && _mainframe.IsHacked} lockedOut={(Object)(object)_mainframe != (Object)null && _mainframe.IsLockedOut} " + $"resolvedYaw={num4} rootYaw={((Component)this).transform.eulerAngles.y:0.0} anchorYaw={(((Object)(object)_playerRootAnchor != (Object)null) ? _playerRootAnchor.eulerAngles.y : (-1f)):0.0} " + $"playerYaw={(((Object)(object)player != (Object)null) ? ((Component)player).transform.eulerAngles.y : (-1f)):0.0} cameraYaw={(((Object)(object)val2 != (Object)null) ? val2.eulerAngles.y : (-1f)):0.0} " + $"standDistance={num:0.00} screenDistance={num2:0.00} aimDot={num3:0.000} canUseThisFrame={_canUseThisFrame}.")); } ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[MainframeDiag.Interact] anchors phase=" + phase + " screen=" + FormatTransform(_screenCenter) + " playerRoot=" + FormatTransform(_playerRootAnchor) + " camera=" + FormatTransform(val2) + " player=" + FormatTransform(((Object)(object)player != (Object)null) ? ((Component)player).transform : null) + ".")); } ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)("[MainframeDiag.Interact] vectors phase=" + phase + " rootForward=" + FormatVector(((Component)this).transform.forward) + " anchorForward=" + FormatVector(((Object)(object)_playerRootAnchor != (Object)null) ? _playerRootAnchor.forward : Vector3.zero) + " cameraForward=" + FormatVector(((Object)(object)val2 != (Object)null) ? val2.forward : Vector3.zero) + " toStand=" + FormatVector(vector) + " toScreen=" + FormatVector(val3) + ".")); } } private static string FormatTransform(Transform target) { //IL_0031: 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_005d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return ""; } return "'" + GetHierarchyPath(target) + "' pos=" + FormatVector(target.position) + " rot=" + FormatVector(target.eulerAngles) + " forward=" + FormatVector(target.forward); } private static string FormatVector(Vector3 vector) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"({vector.x:0.###},{vector.y:0.###},{vector.z:0.###})"; } private void ShowHoverTip(string prompt) { HUDManager instance = HUDManager.Instance; if (!((Object)(object)instance == (Object)null) && instance.controlTipLines != null && instance.controlTipLines.Length != 0 && !((Object)(object)instance.controlTipLines[0] == (Object)null)) { if (!_tipActive) { _capturedTipText = ((TMP_Text)instance.controlTipLines[0]).text; _tipActive = true; } ((TMP_Text)instance.controlTipLines[0]).text = prompt; _activePrompt = prompt; } } private void HideHoverTip() { HUDManager instance = HUDManager.Instance; if ((Object)(object)instance != (Object)null && instance.controlTipLines != null && instance.controlTipLines.Length != 0 && (Object)(object)instance.controlTipLines[0] != (Object)null) { ((TMP_Text)instance.controlTipLines[0]).text = _capturedTipText ?? string.Empty; } _capturedTipText = null; _activePrompt = null; _tipActive = false; } private void ShowHoverCursor(PlayerControllerB player, string prompt) { if (!((Object)(object)player == (Object)null)) { if ((Object)(object)player.cursorIcon != (Object)null && (Object)(object)player.grabItemIcon != (Object)null) { player.cursorIcon.sprite = player.grabItemIcon; ((Behaviour)player.cursorIcon).enabled = true; } if ((Object)(object)player.cursorTip != (Object)null) { ((TMP_Text)player.cursorTip).text = prompt; } _cursorActive = true; _activePrompt = prompt; } } private void HideHoverCursor(PlayerControllerB player) { if (!_cursorActive) { return; } if ((Object)(object)player != (Object)null) { if ((Object)(object)player.cursorTip != (Object)null && string.Equals(((TMP_Text)player.cursorTip).text, _activePrompt, StringComparison.Ordinal)) { ((TMP_Text)player.cursorTip).text = string.Empty; } if ((Object)(object)player.cursorIcon != (Object)null && (Object)(object)player.cursorIcon.sprite == (Object)(object)player.grabItemIcon) { ((Behaviour)player.cursorIcon).enabled = false; } } _cursorActive = false; } private void ClearPromptState() { if (_tipActive) { HideHoverTip(); } if (_cursorActive) { HideHoverCursor(_lastPlayer); } } private void OnDisable() { ClearPromptState(); StopActiveSession("controller-disabled"); } private void OnDestroy() { ClearPromptState(); StopActiveSession("controller-destroyed"); } private static Transform FindDeepChild(Transform root, string name) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(name)) { return null; } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (string.Equals(((Object)val).name, name, StringComparison.Ordinal)) { return val; } } return null; } private static string GetHierarchyPath(Transform target) { if ((Object)(object)target == (Object)null) { return ""; } Stack stack = new Stack(); Transform val = target; while ((Object)(object)val != (Object)null) { stack.Push(((Object)val).name); val = val.parent; } return string.Join("/", stack.ToArray()); } } internal sealed class MainframeInteractionSession { private readonly struct SuppressedHudEntry { internal readonly HUDElement Element; internal readonly CanvasGroup Group; internal readonly float OriginalTargetAlpha; internal readonly float OriginalAlpha; internal readonly bool OriginalBlocksRaycasts; internal readonly bool OriginalInteractable; internal SuppressedHudEntry(HUDElement element, CanvasGroup group) { Element = element; Group = group; OriginalTargetAlpha = element?.targetAlpha ?? 0f; OriginalAlpha = (((Object)(object)group != (Object)null) ? group.alpha : 0f); OriginalBlocksRaycasts = (Object)(object)group != (Object)null && group.blocksRaycasts; OriginalInteractable = (Object)(object)group != (Object)null && group.interactable; } } private const float PlayerBlendDuration = 0.52f; private const float CameraApproachDuration = 0.52f; private const float KeyboardGlanceHoldSeconds = 1.1f; private const float CameraFocusBlendDuration = 0.9f; private const float TeleportFailsafeDistance = 5.25f; private const string DefaultStopTrigger = "SA_stopAnimation"; private const float FocusFovFactor = 0.72f; private const float MinFocusFieldOfView = 36f; private readonly MonoBehaviour _owner; private readonly Transform _root; private readonly MainframeSupport _mainframe; private readonly MainframeScreenController _screen; private MainframeTypingArms _arms; private Transform _playerRootAnchor; private Transform _focusAnchor; private Transform _glanceAnchor; private bool _missingAnchorLogged; private PlayerControllerB _player; private Camera _camera; private Transform _cameraTransform; private Transform _savedCameraParent; private Vector3 _savedCameraLocalPosition; private Quaternion _savedCameraLocalRotation; private float _savedCameraFieldOfView; private float _savedCameraNearClipPlane; private bool _cameraStateCaptured; private Vector3 _introStartPosition; private Quaternion _introStartRotation; private Vector3 _playerStartPosition; private Quaternion _playerStartRotation; private bool _savedInSpecialInteractAnimation; private bool _savedEnteringSpecialAnimation; private bool _savedDisableLookInput; private bool _savedDisableMoveInput; private bool _savedDisableInteract; private bool _savedControllerEnabled; private bool _controllerStateCaptured; private GrabbableObject _hiddenHeldItem; private Renderer[] _visorRenderers; private bool[] _visorRendererStates; private readonly List _suppressedHudEntries = new List(); private string _enterTrigger; private string _stopTrigger; private int _startingHealth = -1; private int _lastHealth = -1; private float _startedAt; private float _playerBlendStartedAt; private short _sessionYaw; private bool _active; private bool _playerBlendComplete; private static MainframeInteractionSession _activeLocalSession; private static int _lastActiveFrame = -1; internal bool IsActive => _active; internal static bool IsAnyLocalSessionActive { get { if (_activeLocalSession != null) { return _activeLocalSession.IsActive; } return false; } } internal static bool WasActiveThisFrame => _lastActiveFrame == Time.frameCount; internal static void NotifyScreenKeystroke(int fingerIndex, float strength) { MainframeInteractionSession activeLocalSession = _activeLocalSession; if (activeLocalSession != null && activeLocalSession.IsActive) { activeLocalSession._arms?.PlaySemanticKeystroke(fingerIndex, strength); } } internal MainframeInteractionSession(MonoBehaviour owner, Transform root, MainframeSupport mainframe, MainframeScreenController screen) { _owner = owner; _root = root; _mainframe = mainframe; _screen = screen; } internal bool Begin(PlayerControllerB player) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) if (_active) { Stop("reenter", returnScreenToIdle: true); } if ((Object)(object)player == (Object)null || !IsLocalPlayer(player)) { return false; } if ((Object)(object)_mainframe == (Object)null || (Object)(object)_screen == (Object)null || !EnsureAnchors()) { return false; } if (_mainframe.IsLockedOut) { return false; } _player = player; _camera = player.gameplayCamera; _cameraTransform = (((Object)(object)_camera != (Object)null) ? ((Component)_camera).transform : null); _playerStartPosition = ((Component)player).transform.position; _playerStartRotation = ((Component)player).transform.rotation; _sessionYaw = ResolveAnchorYaw(); _startedAt = Time.unscaledTime; _playerBlendStartedAt = _startedAt; _playerBlendComplete = false; _startingHealth = ReadPlayerHealth(player); _lastHealth = _startingHealth; _enterTrigger = null; _stopTrigger = "SA_stopAnimation"; _active = true; _activeLocalSession = this; MarkActiveThisFrame(); CaptureCameraState(); if ((Object)(object)_cameraTransform != (Object)null) { _introStartPosition = _cameraTransform.position; _introStartRotation = _cameraTransform.rotation; } CapturePlayerControlState(); HideLocalViewObstructions(); SuppressHudForSession(); ResolveVanillaTerminalAnimation(out _enterTrigger, out _stopTrigger); EnterSpecialAnimation(); CCTVOperatorAnimSync.SendMainframeEnter(player, _sessionYaw); _arms = new MainframeTypingArms(_root); if (!_arms.Begin(player)) { _arms = null; } if (_mainframe.IsHacked) { _screen.OpenHackedMainframe(); } else { _screen.BeginHackingIntro(); } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][MainframeInteract] session_started " + $"player=#{player.playerClientId} yaw={_sessionYaw} hacked={_mainframe.IsHacked} " + string.Format("health={0} root='{1}'.", _startingHealth, ((Object)(object)_root != (Object)null) ? ((Object)_root).name : ""))); } return true; } internal void Tick() { if (_active) { MarkActiveThisFrame(); string interruptReason = GetInterruptReason(); if (!string.IsNullOrEmpty(interruptReason)) { Stop(interruptReason, returnScreenToIdle: true); return; } if (IsEscapePressed()) { Stop("escape", returnScreenToIdle: true); return; } DrivePlayerAnchorBlend(); _arms?.Tick(); } } internal void LateTick() { if (_active) { MarkActiveThisFrame(); if (_playerBlendComplete) { SetPlayerRootToAnchor(); } DriveCameraLate(); _arms?.LateTick(Time.unscaledTime - _startedAt); } } internal void Stop(string reason, bool returnScreenToIdle) { //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) if (_active || !((Object)(object)_player == (Object)null)) { MarkActiveThisFrame(); PlayerControllerB player = _player; if ((Object)(object)player != (Object)null) { TryTriggerPlayerAnimator(player, _stopTrigger, "exit"); RestoreSpecialAnimation(player); RestorePlayerControl(player); CCTVOperatorAnimSync.SendMainframeExit(player); } _arms?.Stop(reason); _arms = null; RestoreLocalViewObstructions(player); RestoreHudForSession(); RestoreCameraState(); if (returnScreenToIdle && (Object)(object)_screen != (Object)null) { _screen.ReturnToIdleFromInteraction(reason ?? "session-ended"); } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][MainframeInteract] session_stopped reason='" + (reason ?? "unspecified") + "' player=#" + (((Object)(object)player != (Object)null) ? player.playerClientId.ToString() : "") + ".")); } if (_activeLocalSession == this) { _activeLocalSession = null; } _player = null; _camera = null; _cameraTransform = null; _savedCameraParent = null; _cameraStateCaptured = false; _introStartPosition = Vector3.zero; _introStartRotation = Quaternion.identity; _controllerStateCaptured = false; _enterTrigger = null; _stopTrigger = null; _startingHealth = -1; _lastHealth = -1; _sessionYaw = 0; _active = false; _playerBlendComplete = false; } } private bool EnsureAnchors() { if ((Object)(object)_playerRootAnchor == (Object)null) { _playerRootAnchor = FindDeepChild(_root, "MainframePlayerRootAnchor"); } if ((Object)(object)_focusAnchor == (Object)null) { _focusAnchor = FindDeepChild(_root, "MainframeFocusViewAnchor"); } if ((Object)(object)_glanceAnchor == (Object)null) { _glanceAnchor = FindDeepChild(_root, "MainframeKeyboardGlanceAnchor"); } int num; if ((Object)(object)_playerRootAnchor != (Object)null && (Object)(object)_focusAnchor != (Object)null) { num = (((Object)(object)_glanceAnchor != (Object)null) ? 1 : 0); if (num != 0) { goto IL_00bd; } } else { num = 0; } if (!_missingAnchorLogged) { _missingAnchorLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log == null) { return (byte)num != 0; } log.LogWarning((object)"[LethalCCTV][MainframeInteract] Missing MainframePlayerRootAnchor, MainframeKeyboardGlanceAnchor, or MainframeFocusViewAnchor; mainframe session disabled."); } goto IL_00bd; IL_00bd: return (byte)num != 0; } private void CaptureCameraState() { //IL_0035: 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_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) if (!((Object)(object)_camera == (Object)null) && !((Object)(object)_cameraTransform == (Object)null)) { _savedCameraParent = _cameraTransform.parent; _savedCameraLocalPosition = _cameraTransform.localPosition; _savedCameraLocalRotation = _cameraTransform.localRotation; _savedCameraFieldOfView = _camera.fieldOfView; _savedCameraNearClipPlane = _camera.nearClipPlane; _cameraStateCaptured = true; } } private void RestoreCameraState() { //IL_0045: 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) if (!_cameraStateCaptured || (Object)(object)_camera == (Object)null || (Object)(object)_cameraTransform == (Object)null) { return; } try { if ((Object)(object)_cameraTransform.parent == (Object)(object)_savedCameraParent) { _cameraTransform.localPosition = _savedCameraLocalPosition; _cameraTransform.localRotation = _savedCameraLocalRotation; } _camera.fieldOfView = _savedCameraFieldOfView; _camera.nearClipPlane = _savedCameraNearClipPlane; } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] Failed to restore camera state: " + ex.Message)); } } } private void HideLocalViewObstructions() { if ((Object)(object)_player == (Object)null) { return; } try { GrabbableObject currentlyHeldObjectServer = _player.currentlyHeldObjectServer; if ((Object)(object)currentlyHeldObjectServer != (Object)null) { currentlyHeldObjectServer.EnableItemMeshes(false); _hiddenHeldItem = currentlyHeldObjectServer; } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] Failed to hide held item meshes: " + ex.Message)); } } try { if (!((Object)(object)_player.localVisor != (Object)null)) { return; } _visorRenderers = ((Component)_player.localVisor).GetComponentsInChildren(true); _visorRendererStates = new bool[_visorRenderers.Length]; for (int i = 0; i < _visorRenderers.Length; i++) { _visorRendererStates[i] = (Object)(object)_visorRenderers[i] != (Object)null && _visorRenderers[i].enabled; if ((Object)(object)_visorRenderers[i] != (Object)null) { _visorRenderers[i].enabled = false; } } } catch (Exception ex2) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][MainframeInteract] Failed to hide local visor: " + ex2.Message)); } } } private void RestoreLocalViewObstructions(PlayerControllerB player) { try { if ((Object)(object)_hiddenHeldItem != (Object)null && (Object)(object)player != (Object)null && player.currentlyHeldObjectServer == _hiddenHeldItem) { _hiddenHeldItem.EnableItemMeshes(true); } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] Failed to restore held item meshes: " + ex.Message)); } } try { if (_visorRenderers != null && _visorRendererStates != null) { for (int i = 0; i < _visorRenderers.Length && i < _visorRendererStates.Length; i++) { if ((Object)(object)_visorRenderers[i] != (Object)null) { _visorRenderers[i].enabled = _visorRendererStates[i]; } } } } catch (Exception ex2) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][MainframeInteract] Failed to restore local visor: " + ex2.Message)); } } _hiddenHeldItem = null; _visorRenderers = null; _visorRendererStates = null; } private void SuppressHudForSession() { try { HUDManager instance = HUDManager.Instance; if (!((Object)(object)instance == (Object)null)) { SuppressHudElement(instance.Inventory); SuppressHudElement(instance.Tooltips); SuppressHudElement(instance.Chat); SuppressHudElement(instance.PlayerInfo); SuppressHudElement(instance.Clock); SuppressHudElement(instance.Compass); SuppressHudElement(instance.InstabilityCounter); SuppressCanvasGroup(instance.holdInteractionCanvasGroup); } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] Failed to suppress HUD for session: " + ex.Message)); } } } private void RestoreHudForSession() { try { for (int num = _suppressedHudEntries.Count - 1; num >= 0; num--) { SuppressedHudEntry suppressedHudEntry = _suppressedHudEntries[num]; if (suppressedHudEntry.Element != null) { suppressedHudEntry.Element.targetAlpha = suppressedHudEntry.OriginalTargetAlpha; } if ((Object)(object)suppressedHudEntry.Group != (Object)null) { suppressedHudEntry.Group.alpha = suppressedHudEntry.OriginalAlpha; suppressedHudEntry.Group.blocksRaycasts = suppressedHudEntry.OriginalBlocksRaycasts; suppressedHudEntry.Group.interactable = suppressedHudEntry.OriginalInteractable; } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] Failed to restore HUD after session: " + ex.Message)); } } finally { _suppressedHudEntries.Clear(); } } private void SuppressHudElement(HUDElement element) { if (element != null && !((Object)(object)element.canvasGroup == (Object)null)) { SuppressCanvasGroup(element.canvasGroup, element); } } private void SuppressCanvasGroup(CanvasGroup group, HUDElement element = null) { if ((Object)(object)group == (Object)null) { return; } for (int i = 0; i < _suppressedHudEntries.Count; i++) { if ((Object)(object)_suppressedHudEntries[i].Group == (Object)(object)group) { if (element != null) { element.targetAlpha = 0f; } group.alpha = 0f; group.blocksRaycasts = false; group.interactable = false; return; } } _suppressedHudEntries.Add(new SuppressedHudEntry(element, group)); if (element != null) { element.targetAlpha = 0f; } group.alpha = 0f; group.blocksRaycasts = false; group.interactable = false; } private void CapturePlayerControlState() { if (!((Object)(object)_player == (Object)null)) { _savedInSpecialInteractAnimation = _player.inSpecialInteractAnimation; _savedEnteringSpecialAnimation = _player.enteringSpecialAnimation; _savedDisableLookInput = _player.disableLookInput; _savedDisableMoveInput = _player.disableMoveInput; _savedDisableInteract = _player.disableInteract; if ((Object)(object)_player.thisController != (Object)null) { _savedControllerEnabled = ((Collider)_player.thisController).enabled; _controllerStateCaptured = true; } } } private void EnterSpecialAnimation() { if ((Object)(object)_player == (Object)null) { return; } try { _player.Crouch(false); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] Crouch(false) failed: " + ex.Message)); } } try { _player.disableLookInput = true; _player.disableMoveInput = true; _player.disableInteract = true; _player.UpdateSpecialAnimationValue(true, _sessionYaw, 0f, false); _player.inSpecialInteractAnimation = true; _player.enteringSpecialAnimation = false; } catch (Exception ex2) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][MainframeInteract] Failed to enter special-animation stance: " + ex2.Message)); } } TryTriggerPlayerAnimator(_player, _enterTrigger, "enter"); } private void RestoreSpecialAnimation(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return; } try { player.UpdateSpecialAnimationValue(false, (short)0, 0f, false); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] UpdateSpecialAnimationValue(false) failed: " + ex.Message)); } } try { player.inSpecialInteractAnimation = _savedInSpecialInteractAnimation; player.enteringSpecialAnimation = _savedEnteringSpecialAnimation; } catch (Exception ex2) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][MainframeInteract] Failed to restore special-animation flags: " + ex2.Message)); } } } private void RestorePlayerControl(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return; } try { player.disableLookInput = _savedDisableLookInput; player.disableMoveInput = _savedDisableMoveInput; player.disableInteract = _savedDisableInteract; if (_controllerStateCaptured && (Object)(object)player.thisController != (Object)null) { ((Collider)player.thisController).enabled = _savedControllerEnabled; } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] Failed to restore player controls: " + ex.Message)); } } } private void DrivePlayerAnchorBlend() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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) if ((Object)(object)_player == (Object)null || (Object)(object)_playerRootAnchor == (Object)null) { return; } float num = Mathf.Clamp01((Time.unscaledTime - _playerBlendStartedAt) / Mathf.Max(0.01f, 0.52f)); float num2 = Smooth(num); Vector3 position = _playerRootAnchor.position; Quaternion val = Quaternion.Euler(0f, _playerRootAnchor.eulerAngles.y, 0f); Vector3 val2 = Vector3.Lerp(_playerStartPosition, position, num2); Quaternion val3 = Quaternion.Slerp(_playerStartRotation, val, num2); try { ((Component)_player).transform.SetPositionAndRotation(val2, val3); if (num >= 1f) { _playerBlendComplete = true; SetPlayerRootToAnchor(); } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] Player anchor blend failed: " + ex.Message)); } } } private void SetPlayerRootToAnchor() { //IL_002f: 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_004e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_player == (Object)null || (Object)(object)_playerRootAnchor == (Object)null) { return; } try { ((Component)_player).transform.SetPositionAndRotation(_playerRootAnchor.position, Quaternion.Euler(0f, _playerRootAnchor.eulerAngles.y, 0f)); } catch { } } private void DriveCameraLate() { //IL_0047: 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_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_007a: 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_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_008f: 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_009d: 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_00fc: 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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_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_00ba: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_cameraTransform == (Object)null || (Object)(object)_playerRootAnchor == (Object)null || (Object)(object)_glanceAnchor == (Object)null || (Object)(object)_focusAnchor == (Object)null) { return; } float num = Time.unscaledTime - _startedAt; Vector3 introStartPosition = _introStartPosition; Quaternion introStartRotation = _introStartRotation; float num2 = 1.62f; Vector3 val; Quaternion val2; float focusBlend; if (num < 0.52f) { float num3 = Smooth(num / Mathf.Max(0.01f, 0.52f)); val = Vector3.Lerp(introStartPosition, _glanceAnchor.position, num3); val2 = Quaternion.Slerp(introStartRotation, _glanceAnchor.rotation, num3); focusBlend = 0f; } else if (num < num2) { val = _glanceAnchor.position; val2 = _glanceAnchor.rotation; focusBlend = 0f; } else { float num4 = Smooth(Mathf.Clamp01((num - num2) / Mathf.Max(0.01f, 0.9f))); val = Vector3.Lerp(_glanceAnchor.position, _focusAnchor.position, num4); val2 = Quaternion.Slerp(_glanceAnchor.rotation, _focusAnchor.rotation, num4); focusBlend = num4; } try { _cameraTransform.SetPositionAndRotation(val, val2); ApplyFocusZoom(focusBlend); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] Camera drive failed: " + ex.Message)); } } } private void ApplyFocusZoom(float focusBlend) { if (_cameraStateCaptured && !((Object)(object)_camera == (Object)null)) { float num = Mathf.Max(1f, _savedCameraFieldOfView); float num2 = Mathf.Max(36f, num * 0.72f); _camera.fieldOfView = Mathf.Lerp(num, Mathf.Min(num, num2), Mathf.Clamp01(focusBlend)); } } private string GetInterruptReason() { //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_player == (Object)null || !((Component)_player).gameObject.activeInHierarchy) { return "player-missing"; } if (!IsLocalPlayer(_player)) { return "not-local-player"; } if ((Object)(object)_mainframe == (Object)null) { return "mainframe-missing"; } if (_mainframe.IsLockedOut) { return "lockout"; } try { if (_player.isPlayerDead) { return "death"; } if (!_player.isPlayerControlled) { return "player-not-controlled"; } if (_player.isClimbingLadder) { return "ladder"; } if (_player.inTerminalMenu) { return "terminal-menu"; } if (_player.isTypingChat) { return "chat"; } if (_player.enteringSpecialAnimation) { return "other-special-entering"; } if (!_player.inSpecialInteractAnimation) { return "special-animation-lost"; } } catch { return "player-state-error"; } int num = ReadPlayerHealth(_player); if (_lastHealth >= 0 && num >= 0 && num < _lastHealth) { return "damaged"; } if (num >= 0) { _lastHealth = num; } if ((Object)(object)_playerRootAnchor != (Object)null) { Vector3 val = ((Component)_player).transform.position - _playerRootAnchor.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude > 27.5625f) { return "distance-failsafe"; } } return null; } private short ResolveAnchorYaw() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) return (short)Mathf.RoundToInt(Mathf.Repeat(((Object)(object)_playerRootAnchor != (Object)null) ? _playerRootAnchor.eulerAngles.y : (((Object)(object)_root != (Object)null) ? _root.eulerAngles.y : 0f), 360f)); } private static bool IsEscapePressed() { Keyboard current = Keyboard.current; if (current != null) { return ((ButtonControl)current.escapeKey).wasPressedThisFrame; } return false; } private static bool IsLocalPlayer(PlayerControllerB player) { PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)player != (Object)null && (Object)(object)val != (Object)null) { return player == val; } return false; } private static void MarkActiveThisFrame() { _lastActiveFrame = Time.frameCount; } private static float Smooth(float x) { x = Mathf.Clamp01(x); return x * x * (3f - 2f * x); } private static int ReadPlayerHealth(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return -1; } try { Type type = ((object)player).GetType(); FieldInfo field = type.GetField("health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object value = field.GetValue(player); if (value is int result) { return result; } if (value is short result2) { return result2; } if (value is byte result3) { return result3; } } PropertyInfo property = type.GetProperty("health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { object value2 = property.GetValue(player, null); if (value2 is int result4) { return result4; } if (value2 is short result5) { return result5; } if (value2 is byte result6) { return result6; } } } catch { } return -1; } private static void ResolveVanillaTerminalAnimation(out string enterTrigger, out string stopTrigger) { enterTrigger = null; stopTrigger = "SA_stopAnimation"; try { Terminal val = Object.FindObjectOfType(); InteractTrigger val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if (!((Object)(object)val2 == (Object)null)) { if (!string.IsNullOrWhiteSpace(val2.animationString)) { enterTrigger = val2.animationString; } if (!string.IsNullOrWhiteSpace(val2.stopAnimationString)) { stopTrigger = val2.stopAnimationString; } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] Vanilla terminal animation probe failed: " + ex.Message)); } } } private static void TryTriggerPlayerAnimator(PlayerControllerB player, string trigger, string phase) { if ((Object)(object)player == (Object)null || (Object)(object)player.playerBodyAnimator == (Object)null || string.IsNullOrWhiteSpace(trigger)) { return; } try { if (AnimatorHasTrigger(player.playerBodyAnimator, trigger)) { player.playerBodyAnimator.ResetTrigger(trigger); player.playerBodyAnimator.SetTrigger(trigger); } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeInteract] Animator " + phase + " trigger '" + trigger + "' failed: " + ex.Message)); } } } private static bool AnimatorHasTrigger(Animator animator, string trigger) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 if ((Object)(object)animator == (Object)null || string.IsNullOrWhiteSpace(trigger)) { return false; } try { AnimatorControllerParameter[] parameters = animator.parameters; for (int i = 0; i < parameters.Length; i++) { if ((int)parameters[i].type == 9 && string.Equals(parameters[i].name, trigger, StringComparison.Ordinal)) { return true; } } } catch { } return false; } private static Transform FindDeepChild(Transform root, string name) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(name)) { return null; } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (string.Equals(((Object)val).name, name, StringComparison.Ordinal)) { return val; } } return null; } } internal sealed class MainframeIntercomPushButton : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IPointerUpHandler, IPointerExitHandler { internal Action HoldChanged; private bool _held; public void OnPointerDown(PointerEventData eventData) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)Cursor.lockState != 1) { SetHeld(held: true); } } public void OnPointerUp(PointerEventData eventData) { SetHeld(held: false); } public void OnPointerExit(PointerEventData eventData) { SetHeld(held: false); } private void OnDisable() { SetHeld(held: false); } private void SetHeld(bool held) { if (_held != held) { _held = held; HoldChanged?.Invoke(held); } } } internal sealed class MainframeScreenController : MonoBehaviour { internal enum ScreenState { IdleUnhacked, HackingIntro, Minigame, HackedMainframe, IdleHacked } private const float PixelsPerMeter = 1000f; private const float IdleRefreshSeconds = 0.18f; private const float ScreenSizeDriftTolerance = 0.05f; private const float ScreenDepthDriftTolerance = 0.01f; private const float ScreenSizeRejectRatio = 2f; private static readonly Color ScreenBlack = new Color(0.003f, 0.01f, 0.004f, 0.98f); private static readonly Color ScreenGreen = new Color(0.16f, 1f, 0.34f, 1f); private static readonly Color ScreenGreenDim = new Color(0.08f, 0.45f, 0.18f, 1f); private static readonly Color ScreenAmber = new Color(0.92f, 0.82f, 0.3f, 1f); private MainframeSupport _mainframe; private Transform _screenSurface; private Transform _screenCenter; private Transform _screenTopLeft; private Transform _screenBottomRight; private GameObject _canvasRoot; private RectTransform _canvasRect; private GameObject _idleRoot; private TextMeshProUGUI _idleText; private HackingOverlay _hackingOverlay; private MainframeControlOverlay _mainframeOverlay; private MainframeAudio _audio; private ScreenState _state; private float _nextIdleRefresh; private float _introUntil; private float _introStartedAt; private int _idleLineOffset; private int _roundRobinFinger; private bool _pushToTalkHeld; private bool _missingAnchorLogged; private Bounds _screenSurfaceLocalBounds; private bool _hasScreenSurfaceBounds; private bool _screenSizeDriftLogged; private Matrix4x4 _screenSurfaceMeasureMatrix; private bool _hasScreenSurfaceMeasure; private bool _screenSurfaceMeasureValid; private Vector3 _screenSurfaceMeasureCenter; private Vector2 _screenSurfaceMeasureSize; internal ScreenState State => _state; private void Awake() { EnsureInitialized(); } private void OnEnable() { EnsureInitialized(); ShowIdleForCurrentHackState(); } private void OnDisable() { ReleasePushToTalk(); _hackingOverlay?.Close("mainframe-screen-disabled"); _mainframeOverlay?.Close("mainframe-screen-disabled"); } private void LateUpdate() { if (!EnsureInitialized()) { return; } PositionCanvasFromAnchors(); if (_hackingOverlay != null && _hackingOverlay.IsOpen) { _hackingOverlay.Tick(); if (_hackingOverlay.ConsumeSolved()) { OpenHackedMainframe(); } else if (_hackingOverlay.ConsumeEscapeIfOpen()) { ShowIdleForCurrentHackState(); } return; } if (_mainframeOverlay != null && _mainframeOverlay.IsOpen) { _mainframeOverlay.Tick(); PollMainframeOverlayInput(); return; } if (_state == ScreenState.HackingIntro && _introUntil > 0f && (Time.unscaledTime >= _introUntil || IsIntroSkipRequested())) { OpenMinigame(); return; } if (_state == ScreenState.IdleUnhacked || _state == ScreenState.IdleHacked || _state == ScreenState.HackingIntro) { RefreshIdleTextIfNeeded(); } if (_state == ScreenState.IdleUnhacked && (Object)(object)_mainframe != (Object)null && _mainframe.IsHacked) { ShowIdleHacked(); } else if (_state == ScreenState.IdleHacked && (Object)(object)_mainframe != (Object)null && !_mainframe.IsHacked) { ShowIdleUnhacked(); } } internal void BeginHackingIntro(float seconds = 1.9f) { if (EnsureInitialized()) { _introStartedAt = Time.unscaledTime; _introUntil = _introStartedAt + Mathf.Max(0.15f, seconds); SetState(ScreenState.HackingIntro); RefreshIdleText(force: true); _audio?.PlayScreenTransition(); _audio?.StartIdle(); } } private bool IsIntroSkipRequested() { if (Time.unscaledTime - _introStartedAt < 0.2f) { return false; } Keyboard current = Keyboard.current; if (current == null) { return false; } if (!((ButtonControl)current.enterKey).wasPressedThisFrame) { return ((ButtonControl)current.numpadEnterKey).wasPressedThisFrame; } return true; } internal void OpenMinigame() { if (EnsureInitialized() && !((Object)(object)_mainframe == (Object)null)) { _introUntil = 0f; SetState(ScreenState.Minigame); ReleasePushToTalk(); _mainframeOverlay?.Close("mainframe-screen-minigame"); _hackingOverlay.Open((Component)(object)_mainframe); _audio?.PlayHackStart(); } } internal void OpenHackedMainframe() { if (EnsureInitialized() && !((Object)(object)_mainframe == (Object)null)) { _introUntil = 0f; SetState(ScreenState.HackedMainframe); _hackingOverlay?.Close("mainframe-screen-control"); _mainframeOverlay.Open((Component)(object)_mainframe); _audio?.PlayScreenTransition(); _audio?.StartIdle(); } } internal void ShowIdleUnhacked() { _introUntil = 0f; SetState(ScreenState.IdleUnhacked); RefreshIdleText(force: true); } internal void ShowIdleHacked() { _introUntil = 0f; SetState(ScreenState.IdleHacked); RefreshIdleText(force: true); } internal void ReturnToIdleFromInteraction(string reason) { if (EnsureInitialized()) { string reason2 = "mainframe-session-" + (string.IsNullOrWhiteSpace(reason) ? "ended" : reason); _introUntil = 0f; ReleasePushToTalk(); _hackingOverlay?.Close(reason2); _mainframeOverlay?.Close(reason2); _audio?.StopIdle(); _audio?.PlayPowerOff(); ShowIdleForCurrentHackState(); } } internal void PlayDeliberateKeystroke(int fingerIndex, float strength) { int num = Mathf.Clamp(fingerIndex, 0, 7); float num2 = Mathf.Clamp(strength, 0f, 1.5f); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)string.Format("[LethalCCTV][MainframeScreen] PlayDeliberateKeystroke finger={0} strength={1:0.00} state={2} mainframe='{3}'.", num, num2, _state, ((Object)(object)_mainframe != (Object)null) ? ((Object)_mainframe).name : "")); } MainframeInteractionSession.NotifyScreenKeystroke(num, num2); } private bool EnsureInitialized() { //IL_0113: 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_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_canvasRoot != (Object)null) { return true; } _mainframe = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); _screenSurface = FindDeepChild(((Component)this).transform, "Mainframe_ScreenSurface"); _screenCenter = FindDeepChild(((Component)this).transform, "MainframeScreenCenter"); _screenTopLeft = FindDeepChild(((Component)this).transform, "MainframeScreenTopLeft"); _screenBottomRight = FindDeepChild(((Component)this).transform, "MainframeScreenBottomRight"); CacheScreenSurfaceBounds(); if ((Object)(object)_screenCenter == (Object)null || (Object)(object)_screenTopLeft == (Object)null || (Object)(object)_screenBottomRight == (Object)null) { if (!_missingAnchorLogged) { _missingAnchorLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV][MainframeScreen] Missing MainframeScreenCenter/TopLeft/BottomRight anchors; physical mainframe monitor UI disabled."); } } return false; } BuildCanvas(); _hackingOverlay = new HackingOverlay((Transform)(object)_canvasRect); _hackingOverlay.KeystrokeRequested = OnHackingOverlayKeystroke; _hackingOverlay.EnsureBuilt(); _hackingOverlay.SetDock(Vector2.zero, _canvasRect.sizeDelta); _mainframeOverlay = new MainframeControlOverlay((Transform)(object)_canvasRect); _mainframeOverlay.EnsureBuilt(); _mainframeOverlay.SetDock(Vector2.zero, _canvasRect.sizeDelta); _audio = MainframeAudio.Ensure(((Component)this).transform); return true; } private void BuildCanvas() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0082: 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_00b6: Unknown result type (might be due to invalid IL or missing references) _canvasRoot = new GameObject("MainframeWorldSpaceCanvas", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); _canvasRoot.transform.SetParent(((Component)this).transform, false); _canvasRect = _canvasRoot.GetComponent(); _canvasRect.anchorMin = new Vector2(0.5f, 0.5f); _canvasRect.anchorMax = new Vector2(0.5f, 0.5f); _canvasRect.pivot = new Vector2(0.5f, 0.5f); Canvas component = _canvasRoot.GetComponent(); component.renderMode = (RenderMode)2; component.sortingOrder = 12; CanvasScaler component2 = _canvasRoot.GetComponent(); component2.dynamicPixelsPerUnit = 1f; component2.referencePixelsPerUnit = 100f; PositionCanvasFromAnchors(); BuildIdleLayer(); } private void PositionCanvasFromAnchors() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_006b: 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_0071: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_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_008f: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_0154: 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_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_019a: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_012d: 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_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_canvasRect == (Object)null || (Object)(object)_screenCenter == (Object)null || (Object)(object)_screenTopLeft == (Object)null || (Object)(object)_screenBottomRight == (Object)null) { return; } Vector3 val = ((Component)this).transform.InverseTransformVector(((Component)this).transform.forward * 0.003f); Vector3 val2 = ((Component)this).transform.InverseTransformPoint(_screenCenter.position); Vector3 localPosition = val2 - val; Vector3 val3 = ((Component)this).transform.InverseTransformPoint(_screenTopLeft.position); Vector3 val4 = ((Component)this).transform.InverseTransformPoint(_screenBottomRight.position); float num = Mathf.Max(0.05f, Mathf.Abs(val3.x - val4.x)); float num2 = Mathf.Max(0.05f, Mathf.Abs(val3.y - val4.y)); if (TryMeasureScreenSurface(out var center, out var size)) { bool flag = IsSurfaceMeasurementPlausible(num, num2, size); EvaluateScreenSurfaceDriftOnce(num, num2, val2.z, center, size, flag); if (flag) { num = size.x; num2 = size.y; ((Vector3)(ref localPosition))..ctor(center.x, center.y, center.z - val.z); } } ((Transform)_canvasRect).localPosition = localPosition; ((Transform)_canvasRect).localRotation = Quaternion.identity; ((Transform)_canvasRect).localScale = Vector3.one / 1000f; _canvasRect.sizeDelta = new Vector2(num * 1000f, num2 * 1000f); _hackingOverlay?.SetDock(Vector2.zero, _canvasRect.sizeDelta); _mainframeOverlay?.SetDock(Vector2.zero, _canvasRect.sizeDelta); } private void CacheScreenSurfaceBounds() { //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) //IL_0081: 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_004c: Unknown result type (might be due to invalid IL or missing references) _hasScreenSurfaceBounds = false; _hasScreenSurfaceMeasure = false; if ((Object)(object)_screenSurface == (Object)null) { return; } MeshFilter component = ((Component)_screenSurface).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) { _screenSurfaceLocalBounds = component.sharedMesh.bounds; _hasScreenSurfaceBounds = true; return; } Renderer component2 = ((Component)_screenSurface).GetComponent(); if (!((Object)(object)component2 == (Object)null)) { _screenSurfaceLocalBounds = MainframeSpawnDiagnostics.ConvertWorldBoundsToLocal(_screenSurface, component2.bounds); _hasScreenSurfaceBounds = true; } } private bool TryMeasureScreenSurface(out Vector3 center, out Vector2 size) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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) center = Vector3.zero; size = Vector2.zero; if (!_hasScreenSurfaceBounds || (Object)(object)_screenSurface == (Object)null) { return false; } Matrix4x4 val = ((Component)this).transform.worldToLocalMatrix * _screenSurface.localToWorldMatrix; if (!_hasScreenSurfaceMeasure || val != _screenSurfaceMeasureMatrix) { _screenSurfaceMeasureMatrix = val; _hasScreenSurfaceMeasure = true; _screenSurfaceMeasureValid = MeasureScreenSurface(val, out _screenSurfaceMeasureCenter, out _screenSurfaceMeasureSize); } center = _screenSurfaceMeasureCenter; size = _screenSurfaceMeasureSize; return _screenSurfaceMeasureValid; } private bool MeasureScreenSurface(Matrix4x4 surfaceToRoot, out Vector3 center, out Vector2 size) { //IL_0006: 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_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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0091: 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_0094: 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_009e: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00ac: 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) Vector3 center2 = ((Bounds)(ref _screenSurfaceLocalBounds)).center; Vector3 extents = ((Bounds)(ref _screenSurfaceLocalBounds)).extents; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(float.MinValue, float.MinValue, float.MinValue); Vector3 val3 = default(Vector3); for (int i = 0; i < 8; i++) { ((Vector3)(ref val3))..ctor(((i & 1) == 0) ? (0f - extents.x) : extents.x, ((i & 2) == 0) ? (0f - extents.y) : extents.y, ((i & 4) == 0) ? (0f - extents.z) : extents.z); Vector3 val4 = ((Matrix4x4)(ref surfaceToRoot)).MultiplyPoint3x4(center2 + val3); val = Vector3.Min(val, val4); val2 = Vector3.Max(val2, val4); } size = new Vector2(val2.x - val.x, val2.y - val.y); center = (val + val2) * 0.5f; if (size.x > 0.05f) { return size.y > 0.05f; } return false; } private static bool IsSurfaceMeasurementPlausible(float anchorWidth, float anchorHeight, Vector2 surfaceSize) { //IL_0001: 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) if (IsWithinRejectRatio(anchorWidth, surfaceSize.x)) { return IsWithinRejectRatio(anchorHeight, surfaceSize.y); } return false; } private static bool IsWithinRejectRatio(float anchorAxis, float surfaceAxis) { float num = Mathf.Max(0.0001f, anchorAxis); float num2 = Mathf.Max(0.0001f, surfaceAxis); if (num2 <= num * 2f) { return num <= num2 * 2f; } return false; } private void EvaluateScreenSurfaceDriftOnce(float anchorWidth, float anchorHeight, float anchorCenterZ, Vector3 surfaceCenter, Vector2 surfaceSize, bool accepted) { //IL_0010: 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_0046: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if (_screenSizeDriftLogged) { return; } _screenSizeDriftLogged = true; float num = Mathf.Abs(surfaceSize.x - anchorWidth) / Mathf.Max(0.0001f, anchorWidth); float num2 = Mathf.Abs(surfaceSize.y - anchorHeight) / Mathf.Max(0.0001f, anchorHeight); float num3 = Mathf.Abs(surfaceCenter.z - anchorCenterZ); if (!accepted || !(num <= 0.05f) || !(num2 <= 0.05f) || !(num3 <= 0.01f)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeScreen] Mainframe_ScreenSurface bounds disagree with the screen anchors: " + $"surface={surfaceSize.x:0.0000}x{surfaceSize.y:0.0000}m anchors={anchorWidth:0.0000}x{anchorHeight:0.0000}m " + $"drift={num * 100f:0.0}%/{num2 * 100f:0.0}% " + $"surfaceZ={surfaceCenter.z:0.0000}m anchorZ={anchorCenterZ:0.0000}m depthDrift={num3:0.0000}m; " + (accepted ? "sizing the canvas from the surface. Re-author MainframeScreenTopLeft/BottomRight to match the glass." : ($"the disagreement exceeds {2f:0.#}x, so the surface measurement is rejected and the anchors size the canvas. " + "Check that Mainframe_ScreenSurface is the glass quad.")))); } } } private void BuildIdleLayer() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0060: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00fc: 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_011c: 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_01b4: Unknown result type (might be due to invalid IL or missing references) _idleRoot = new GameObject("MainframeIdleDiagnostics", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); _idleRoot.transform.SetParent((Transform)(object)_canvasRect, false); RectTransform component = _idleRoot.GetComponent(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; Image component2 = _idleRoot.GetComponent(); ((Graphic)component2).color = ScreenBlack; ((Graphic)component2).raycastTarget = false; GameObject val = new GameObject("DiagnosticsText", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val.transform.SetParent(_idleRoot.transform, false); RectTransform component3 = val.GetComponent(); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.offsetMin = new Vector2(12f, 10f); component3.offsetMax = new Vector2(-12f, -10f); _idleText = val.GetComponent(); ((TMP_Text)_idleText).alignment = (TextAlignmentOptions)257; ((TMP_Text)_idleText).enableAutoSizing = true; ((TMP_Text)_idleText).fontSizeMin = 17f; ((TMP_Text)_idleText).fontSizeMax = 34f; ((TMP_Text)_idleText).fontSize = 30f; ((TMP_Text)_idleText).lineSpacing = 8f; ((TMP_Text)_idleText).fontStyle = (FontStyles)1; ((Graphic)_idleText).color = ScreenGreen; ((TMP_Text)_idleText).richText = false; ((Graphic)_idleText).raycastTarget = false; ((TMP_Text)_idleText).enableWordWrapping = false; ((TMP_Text)_idleText).overflowMode = (TextOverflowModes)3; } private void PollMainframeOverlayPushToTalk() { if (_mainframeOverlay == null) { _pushToTalkHeld = false; return; } bool flag = _mainframeOverlay.IsIntercomActive && MonitorFocus.IsWalkiePushToTalkHeld(); if (flag != _pushToTalkHeld) { _pushToTalkHeld = flag; _mainframeOverlay.SetPushToTalk(flag); } } private void ReleasePushToTalk() { if (_pushToTalkHeld) { _pushToTalkHeld = false; _mainframeOverlay?.SetPushToTalk(held: false); } } private void PollMainframeOverlayInput() { PollMainframeOverlayPushToTalk(); Keyboard current = Keyboard.current; if (current == null || _mainframeOverlay == null || !_mainframeOverlay.IsOpen) { return; } bool flag = false; int fingerIndex = 0; float strength = 0.82f; bool flag2 = false; bool flag3 = false; int viewToken = _mainframeOverlay.ViewToken; if (((ButtonControl)current.upArrowKey).wasPressedThisFrame) { flag = _mainframeOverlay.NavigateUp("mainframe-screen-up"); fingerIndex = 2; } else if (((ButtonControl)current.downArrowKey).wasPressedThisFrame) { flag = _mainframeOverlay.NavigateDown("mainframe-screen-down"); fingerIndex = 3; } else if (((ButtonControl)current.leftArrowKey).wasPressedThisFrame) { flag = _mainframeOverlay.NavigateLeft("mainframe-screen-left"); fingerIndex = 1; } else if (((ButtonControl)current.rightArrowKey).wasPressedThisFrame) { flag = _mainframeOverlay.NavigateRight("mainframe-screen-right"); fingerIndex = 4; } else if (((ButtonControl)current.enterKey).wasPressedThisFrame || ((ButtonControl)current.numpadEnterKey).wasPressedThisFrame) { flag = _mainframeOverlay.Submit("mainframe-screen-enter"); fingerIndex = 5; strength = 1.3f; flag2 = true; } else if (((ButtonControl)current.escapeKey).wasPressedThisFrame) { flag = _mainframeOverlay.ConsumeEscapeIfOpen(); fingerIndex = 0; strength = 0.75f; flag3 = true; } if (flag) { PlayDeliberateKeystroke(fingerIndex, strength); if (_mainframeOverlay.IsOpen && _mainframeOverlay.ViewToken != viewToken) { _audio?.PlayScreenTransition(); } else if (!flag3) { if (flag2) { _audio?.PlaySelect(); } else { _audio?.PlayNavigate(); } } } if (_mainframeOverlay != null && !_mainframeOverlay.IsOpen) { _pushToTalkHeld = false; ShowIdleForCurrentHackState(); } } private void OnHackingOverlayKeystroke(int fingerIndex, float strength, string source) { if (fingerIndex < 0) { _roundRobinFinger = (_roundRobinFinger + 1) % 5; fingerIndex = _roundRobinFinger; } PlayDeliberateKeystroke(fingerIndex, strength); } private void SetState(ScreenState state) { _state = state; bool active = state == ScreenState.IdleUnhacked || state == ScreenState.IdleHacked || state == ScreenState.HackingIntro; if ((Object)(object)_idleRoot != (Object)null) { _idleRoot.SetActive(active); } } private void ShowIdleForCurrentHackState() { if ((Object)(object)_mainframe != (Object)null && _mainframe.IsHacked) { ShowIdleHacked(); } else { ShowIdleUnhacked(); } } private void RefreshIdleTextIfNeeded() { if (!(Time.unscaledTime < _nextIdleRefresh)) { RefreshIdleText(force: false); } } private void RefreshIdleText(bool force) { //IL_0043: 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_00ab: 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) if (!((Object)(object)_idleText == (Object)null)) { _nextIdleRefresh = Time.unscaledTime + 0.18f; if (!force) { _idleLineOffset = (_idleLineOffset + 1) % 64; } if (_state == ScreenState.HackingIntro) { ((Graphic)_idleText).color = ScreenGreen; ((TMP_Text)_idleText).text = BuildIntroText(); } else if (_state == ScreenState.IdleHacked) { ((Graphic)_idleText).color = ScreenGreen; ((TMP_Text)_idleText).text = BuildIdleHackedText(); } else { ((Graphic)_idleText).color = (((Object)(object)_mainframe != (Object)null && _mainframe.IsLockedOut) ? ScreenAmber : ScreenGreen); ((TMP_Text)_idleText).text = BuildIdleUnhackedText(); } } } private string BuildIntroText() { float num = Mathf.Max(0f, _introUntil - Time.unscaledTime); return "MAINFRAME BOOT\n> KVM BUS\n> SPLICE\n> HANDSHAKE " + Mathf.CeilToInt(num * 10f).ToString("00"); } private string BuildIdleHackedText() { return "MAINFRAME OS\nACCESS GRANTED\n\nSTORAGE READY\nCHECKS OPEN\n\n" + BlinkCursor("OPERATOR?"); } private string BuildIdleUnhackedText() { string value = (((Object)(object)_mainframe != (Object)null && _mainframe.IsLockedOut) ? ("LOCKOUT " + _mainframe.LockoutRemaining.ToString("0") + "S") : "TRACE ARMED"); StringBuilder stringBuilder = new StringBuilder(160); stringBuilder.Append("DIAGNOSTIC BUS\n"); stringBuilder.Append(value).Append("\n\n"); string[] array = new string[8] { "CRT SYNC....OK", "KVM SW....IDLE", "PATCH....NOISE", "RELAY...SEALED", "STASH...LOCKED", "COMMS.....COLD", "ALARM....READY", "SPLICE....WAIT" }; for (int i = 0; i < 3; i++) { stringBuilder.Append(array[(_idleLineOffset + i) % array.Length]).Append('\n'); } stringBuilder.Append('\n').Append(BlinkCursor("HANDSHAKE?")); return stringBuilder.ToString(); } private static string BlinkCursor(string text) { if (!(Time.unscaledTime % 1f < 0.5f)) { return text; } return text + " _"; } private static Transform FindDeepChild(Transform root, string name) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(name)) { return null; } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (string.Equals(((Object)val).name, name, StringComparison.Ordinal)) { return val; } } return null; } } internal sealed class MainframeTypingArms { private enum StrikeStyle { Normal, Thumb, Enter, Arrow } private sealed class ArmChain { public Transform Upper; public Transform Lower; public Transform Hand; public Transform Target; public Vector3 RestTargetLocalPosition; public Quaternion RestTargetLocalRotation; public Quaternion RestHandInLower; public Vector3 LowerBoneAxisLocal; public Vector3 LastUnclampedGoal; public Vector3 LastClampedGoal; public float ChainLength; public float KeyDriftX; public float StrikeElapsed = -1f; public float StrikeDuration = 0.16f; public float StrikeStrength; public float StrikeDip; public float StrikeForward; public float WristRollAccentDegrees; } private sealed class BoneRestPose { public readonly Transform Transform; public readonly Vector3 LocalPosition; public readonly Quaternion LocalRotation; public BoneRestPose(Transform transform, Vector3 localPosition, Quaternion localRotation) { //IL_000e: 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_0015: 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) Transform = transform; LocalPosition = localPosition; LocalRotation = localRotation; } } private sealed class FingerChain { public int Index; public Transform Root; public Transform Mid; public bool IsThumb; public float SpeedScale; public float LiftScale; public float PressScale; public float Phase; public Vector3 RootCurlAxis = Vector3.right; public Vector3 MidCurlAxis = Vector3.right; public float KeystrokeElapsed = -1f; public float KeystrokeStrength; public float KeystrokeDuration = 0.16f; public ArmChain Arm; } private static readonly Vector3 HandHomeLocalOffset = new Vector3(0f, 0.05f, -0.22f); private const float ArmRigVerticalLift = 0.25f; private const float ArmRigBackShift = 0.2f; private const float CameraApproachDuration = 0.52f; private const float CameraGlanceDuration = 1.1f; private const float CameraFocusBlendDuration = 0.9f; private const float CameraGlanceEndSeconds = 1.62f; private const float CameraFocusBlendEndSeconds = 2.52f; private const int MainframeArmsDiagPhaseNone = -1; private const int MainframeArmsDiagPhaseApproach = 0; private const int MainframeArmsDiagPhaseGlance = 1; private const int MainframeArmsDiagPhaseFocusBlend = 2; private const int MainframeArmsDiagPhaseFocus = 3; private const float BobGainRampSeconds = 0.35f; private const float HandPitchDegrees = 2f; private const float HandYawInwardDegrees = 8f; private const float HandRollThumbUpDegrees = 6f; private const float HandLiftAmplitude = 0.01f; private const float HandLiftHz = 0.9f; private const float WanderAmplitude = 0.03f; private const float WanderHz = 0.5f; private const float TapDipDepth = 0.004f; private const float HandStrikeDipMin = 0.025f; private const float HandStrikeDipMax = 0.035f; private const float HandStrikeForwardDepth = 0.018f; private const float HandStrikeLateralMax = 0.02f; private const float HandDriftRelaxMetersPerSecond = 0.005f; private const float KeyFieldHalfWidth = 0.28f; private const float MaxReachFraction = 0.92f; private const float IntroBurstEndSeconds = 1.5699999f; private const float FingerBaseCurlDegrees = 22f; private const float FingerBaseCurlMidDegrees = 18f; private const float FingerLiftDegrees = 14f; private const float FingerMidLiftBendDegrees = 10f; private const float FingerPressDegrees = 10f; private const float ThumbCurlScale = 0.3f; private const float KeystrokeBaseDuration = 0.16f; private const int FabrikIterations = 15; private const float FabrikTolerance = 0.0001f; private readonly Transform _mainframeRoot; private readonly List _boneRest = new List(); private readonly List _leftFingers = new List(); private readonly List _rightFingers = new List(); private readonly List _allFingers = new List(); private readonly List _leftThumbFingerIndices = new List(); private readonly List _rightThumbFingerIndices = new List(); private readonly List _leftNonThumbFingerIndices = new List(); private readonly List _rightNonThumbFingerIndices = new List(); private readonly List _nonThumbFingerIndices = new List(); private PlayerControllerB _player; private Transform _armsRoot; private Transform _armsMetarig; private bool _armsRigPoseCaptured; private bool _armsMetarigPoseCaptured; private bool _armsCameraPinningEnabled; private Vector3 _armsRigRestLocalPosition; private Quaternion _armsRigRestLocalRotation; private Vector3 _armsRigCameraRelativePosition; private Quaternion _armsRigCameraRelativeRotation; private Vector3 _armsMetarigRestLocalPosition; private Quaternion _armsMetarigRestLocalRotation; private Vector3 _armsMetarigCameraRelativePosition; private Quaternion _armsMetarigCameraRelativeRotation; private Transform _leftHome; private Transform _rightHome; private ArmChain _left; private ArmChain _right; private SkinnedMeshRenderer _armsRenderer; private bool _armsRendererStateCaptured; private bool _savedArmsRendererEnabled; private bool _begun; private bool _disabled; private bool _missingWarningLogged; private bool _runtimeFaulted; private bool _runtimeFaultLogged; private bool _inputWarningLogged; private float _startedAt; private float _lastLateSessionTime = -1f; private int _lastLoggedMainframeArmsDiagPhase = -1; private int _nextThumbHand; private int _lastStrikeFrame = -1; private readonly Random _runtimeRng = new Random(); private float _nextIntroBurstTime; private int _introBurstTargetCount; private int _introBurstCount; private int _lastIntroFingerIndex = -1; private bool _introBurstComplete; private bool _introSpaceStrokePlayed; private int _strokeSerial; internal MainframeTypingArms(Transform mainframeRoot) { _mainframeRoot = mainframeRoot; } internal bool Begin(PlayerControllerB player) { if (_disabled) { return false; } _player = player; _startedAt = Time.unscaledTime; _lastLateSessionTime = -1f; _lastLoggedMainframeArmsDiagPhase = -1; _nextThumbHand = 0; _nextIntroBurstTime = 0.52f + Range(_runtimeRng, 0.02f, 0.08f); _introBurstTargetCount = 8 + _runtimeRng.Next(0, 5); _introBurstCount = 0; _lastIntroFingerIndex = -1; _introBurstComplete = false; _introSpaceStrokePlayed = false; _strokeSerial = 0; try { List list = new List(); if ((Object)(object)player == (Object)null) { AddMissing(list, "player"); } Transform val = ResolveArmsSearchRoot(player); if ((Object)(object)val == (Object)null) { AddMissing(list, "localArmsTransform/gameplayCamera.root"); } if ((Object)(object)_mainframeRoot == (Object)null) { AddMissing(list, "mainframe root"); } Transform upper = Require(val, "arm.L_upper", list); Transform lower = Require(val, "arm.L_lower", list); Transform hand = Require(val, "hand.L", list); Transform val2 = Require(val, "ArmsLeftArm_target", list); Transform upper2 = Require(val, "arm.R_upper", list); Transform lower2 = Require(val, "arm.R_lower", list); Transform hand2 = Require(val, "hand.R", list); Transform val3 = Require(val, "ArmsRightArm_target", list); Transform leftHome = Require(_mainframeRoot, "MainframeLeftHandHome", list); Transform rightHome = Require(_mainframeRoot, "MainframeRightHandHome", list); if ((Object)(object)val2 != (Object)null && (Object)(object)val2.parent == (Object)null) { AddMissing(list, "ArmsLeftArm_target.parent"); } if ((Object)(object)val3 != (Object)null && (Object)(object)val3.parent == (Object)null) { AddMissing(list, "ArmsRightArm_target.parent"); } if (list.Count > 0) { DisableWithMissing(list); return false; } _armsRoot = val; _leftHome = leftHome; _rightHome = rightHome; _left = new ArmChain { Upper = upper, Lower = lower, Hand = hand, Target = val2 }; _right = new ArmChain { Upper = upper2, Lower = lower2, Hand = hand2, Target = val3 }; CaptureCameraRelativeArmsPose(); CaptureRendererState(player); CaptureTargetRest(_left); CaptureTargetRest(_right); CaptureBoneRest(_left.Upper); CaptureBoneRest(_right.Upper); CaptureChainLength(_left); CaptureChainLength(_right); CaptureForearmRollCarrier(_left); CaptureForearmRollCarrier(_right); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV][MainframeArms] Chain lengths: left={_left.ChainLength:0.000}m, right={_right.ChainLength:0.000}m, clamp={0.92f:0.00}."); } TryLogBeginDiagnostics(); CollectFingers(_left.Hand, 1000, _leftFingers); CollectFingers(_right.Hand, 2000, _rightFingers); RegisterFingerIndices(); RestoreBoneRestSnapshot(); DeriveFingerCurlAxes(_left.Hand, _leftFingers); DeriveFingerCurlAxes(_right.Hand, _rightFingers); _begun = true; return true; } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][MainframeArms] Begin failed; procedural typing arms disabled: " + ex.Message)); } RestoreAfterBeginFailure(); ClearState(); _disabled = true; return false; } } internal void Tick() { //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Invalid comparison between Unknown and I4 //IL_00f0: 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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected I4, but got Unknown if (!_begun || _disabled || _runtimeFaulted) { return; } float num = Time.unscaledTime - _startedAt; try { DriveIntroBurst(num); if (num <= 0.52f) { return; } Keyboard current = Keyboard.current; if (current == null || !((ButtonControl)current.anyKey).wasPressedThisFrame) { return; } for (int i = 0; i < current.allKeys.Count; i++) { KeyControl val = current.allKeys[i]; if (val != null && ((ButtonControl)val).wasPressedThisFrame && (int)val.keyCode != 60) { if (IsEnterKey(val)) { PlayRightThumbKeystroke(1.3f, 0.22f, StrikeStyle.Enter); } else if (IsSpaceKey(val)) { PlayAlternatingThumbKeystroke(1.05f, RandomKeystrokeDuration(), StrikeStyle.Thumb); } else if (IsArrowKey(val)) { PlayArrowKeystroke(val); } else if (_nonThumbFingerIndices.Count > 0) { int index = (val.keyCode & 0x7FFFFFFF) % _nonThumbFingerIndices.Count; PlayDeliberateKeystroke(_nonThumbFingerIndices[index], Range(_runtimeRng, 0.9f, 1.15f)); } break; } } } catch (Exception ex) { if (!_inputWarningLogged) { _inputWarningLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeArms] Keyboard keystroke probe failed: " + ex.Message)); } } } } internal void LateTick(float sessionTime) { //IL_00bf: 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) if (!_begun || _disabled || _runtimeFaulted) { return; } float deltaTime = 0f; if (_lastLateSessionTime >= 0f) { deltaTime = Mathf.Max(0f, sessionTime - _lastLateSessionTime); } _lastLateSessionTime = sessionTime; try { PinArmsToGameplayCamera(); RestoreBoneRestSnapshot(); AdvanceHandMotion(_left, deltaTime); AdvanceHandMotion(_right, deltaTime); float num = Smooth(Mathf.Clamp01(sessionTime / 0.52f)); float num2 = sessionTime - 0.52f; float bobGain = Mathf.Clamp01(num2 / 0.35f) * ((num2 > 0f) ? 1f : 0f); PoseTarget(_left, _leftHome, ComputeHandGoalRotation(_leftHome, -1f), num, num2, bobGain, 0f, GetHandTapDip(_leftFingers)); PoseTarget(_right, _rightHome, ComputeHandGoalRotation(_rightHome, 1f), num, num2, bobGain, 2.3f, GetHandTapDip(_rightFingers)); SolveChainIk(_left); SolveChainIk(_right); TryLogLatePhaseDiagnostics(sessionTime); ApplyFingerTyping(_leftFingers, num); ApplyFingerTyping(_rightFingers, num); AdvanceKeystrokes(_leftFingers, deltaTime); AdvanceKeystrokes(_rightFingers, deltaTime); } catch (Exception ex) { _runtimeFaulted = true; if (!_runtimeFaultLogged) { _runtimeFaultLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeArms] LateTick failed; procedural typing arms disabled for this session: " + ex.Message)); } } } } internal void Stop(string reason) { if (!_begun && !_armsRendererStateCaptured && _boneRest.Count <= 0 && !_armsRigPoseCaptured && !_armsMetarigPoseCaptured) { return; } try { RestoreBoneRestSnapshot(); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeArms] Failed to restore arm bone rest on stop '" + (reason ?? "unspecified") + "': " + ex.Message)); } } try { RestoreTargetPose(_left); RestoreTargetPose(_right); } catch (Exception ex2) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][MainframeArms] Failed to restore IK targets on stop '" + (reason ?? "unspecified") + "': " + ex2.Message)); } } try { RestorePinnedArmsLocalPose(); } catch (Exception ex3) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV][MainframeArms] Failed to restore local arms rig pose on stop '" + (reason ?? "unspecified") + "': " + ex3.Message)); } } try { RestoreRendererState(); } catch (Exception ex4) { ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogWarning((object)("[LethalCCTV][MainframeArms] Failed to restore local arms renderer on stop '" + (reason ?? "unspecified") + "': " + ex4.Message)); } } ClearState(); } internal void PlaySemanticKeystroke(int fingerIndex, float strength) { if (_begun && !_disabled && !_runtimeFaulted && _nonThumbFingerIndices.Count > 0) { if (strength >= 1.25f) { PlayRightThumbKeystroke(1.3f, 0.22f, StrikeStyle.Enter); return; } int index = (fingerIndex % _nonThumbFingerIndices.Count + _nonThumbFingerIndices.Count) % _nonThumbFingerIndices.Count; PlayDeliberateKeystroke(_nonThumbFingerIndices[index], strength); } } private void DriveIntroBurst(float sessionTime) { if (_introBurstComplete || sessionTime < 0.52f) { return; } if (sessionTime > 1.5699999f && _introBurstCount >= _introBurstTargetCount) { _introBurstComplete = true; } else if (!(sessionTime < _nextIntroBurstTime)) { if (!_introSpaceStrokePlayed && (_introBurstCount >= Mathf.Max(1, _introBurstTargetCount - 2) || sessionTime >= 1.3899999f)) { _introSpaceStrokePlayed = true; PlayAlternatingThumbKeystroke(Range(_runtimeRng, 0.95f, 1.2f), Range(_runtimeRng, 0.15f, 0.2f), StrikeStyle.Thumb); } else if (_nonThumbFingerIndices.Count > 0) { int fingerIndex = PickIntroNonThumbFinger(); PlayDeliberateKeystroke(fingerIndex, Range(_runtimeRng, 0.85f, 1.25f), RandomKeystrokeDuration(), StrikeStyle.Normal, Range(_runtimeRng, -0.02f, 0.02f)); } _introBurstCount++; if (_introBurstCount >= _introBurstTargetCount && _introSpaceStrokePlayed) { _introBurstComplete = true; } _nextIntroBurstTime = sessionTime + Range(_runtimeRng, 0.06f, 0.14f); } } private int PickIntroNonThumbFinger() { if (_nonThumbFingerIndices.Count <= 0) { return -1; } int num = _nonThumbFingerIndices[_runtimeRng.Next(0, _nonThumbFingerIndices.Count)]; for (int i = 0; i < 8; i++) { if (num != _lastIntroFingerIndex) { break; } if (_nonThumbFingerIndices.Count <= 1) { break; } num = _nonThumbFingerIndices[_runtimeRng.Next(0, _nonThumbFingerIndices.Count)]; } _lastIntroFingerIndex = num; return num; } private bool PlayDeliberateKeystroke(int fingerIndex, float strength) { return PlayDeliberateKeystroke(fingerIndex, strength, RandomKeystrokeDuration(), StrikeStyle.Normal, Range(_runtimeRng, -0.02f, 0.02f)); } private bool PlayDeliberateKeystroke(int fingerIndex, float strength, float duration, StrikeStyle style, float lateralDrift) { if (fingerIndex < 0 || fingerIndex >= _allFingers.Count) { return false; } if (_lastStrikeFrame == Time.frameCount) { return false; } FingerChain fingerChain = _allFingers[fingerIndex]; if (fingerChain == null) { return false; } _lastStrikeFrame = Time.frameCount; fingerChain.KeystrokeElapsed = 0f; fingerChain.KeystrokeStrength = Mathf.Max(0f, strength); fingerChain.KeystrokeDuration = Mathf.Max(0.08f, duration); BeginHandStrike(fingerChain, strength, fingerChain.KeystrokeDuration, style, lateralDrift); MainframeAudio.Current?.PlayTyping(); return true; } private void BeginHandStrike(FingerChain finger, float strength, float duration, StrikeStyle style, float lateralDrift) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) ArmChain armChain = finger?.Arm; Transform val = ResolveHomeForArm(armChain); if (armChain != null && !((Object)(object)val == (Object)null) && !((Object)(object)_mainframeRoot == (Object)null)) { float x = _mainframeRoot.InverseTransformPoint(val.position).x; float num = Mathf.Sign(x); if (Mathf.Abs(num) < 0.5f) { num = ((armChain == _left) ? 1f : (-1f)); } float num2 = x + armChain.KeyDriftX + lateralDrift; if (style == StrikeStyle.Arrow) { num2 = num * 0.28f * 0.88f; } num2 = Mathf.Clamp(num2, -0.28f, 0.28f); num2 = ((!(num > 0f)) ? Mathf.Min(-0.035f, num2) : Mathf.Max(0.035f, num2)); armChain.KeyDriftX = num2 - x; armChain.StrikeElapsed = 0f; armChain.StrikeDuration = Mathf.Max(0.08f, duration); armChain.StrikeStrength = Mathf.Max(0f, strength); armChain.StrikeDip = Range(_runtimeRng, 0.025f, 0.035f) * armChain.StrikeStrength; armChain.StrikeForward = 0.018f * Mathf.Clamp(armChain.StrikeStrength, 0.6f, 1.4f); switch (style) { case StrikeStyle.Enter: armChain.StrikeDip *= 1.25f; armChain.StrikeForward *= 1.2f; break; case StrikeStyle.Arrow: armChain.StrikeDip *= 0.72f; armChain.StrikeForward *= 0.7f; break; } _strokeSerial++; armChain.WristRollAccentDegrees = ((_strokeSerial % 4 == 0) ? (Range(_runtimeRng, 2f, 3f) * ((num > 0f) ? 1f : (-1f))) : 0f); } } private void PlayAlternatingThumbKeystroke(float strength, float duration, StrikeStyle style) { int num = -1; num = (((_nextThumbHand & 1) != 0) ? FirstIndexOrFallback(_rightThumbFingerIndices, _leftThumbFingerIndices) : FirstIndexOrFallback(_leftThumbFingerIndices, _rightThumbFingerIndices)); _nextThumbHand++; if (num >= 0) { PlayDeliberateKeystroke(num, strength, duration, style, Range(_runtimeRng, -0.01f, 0.01f)); } } private void PlayRightThumbKeystroke(float strength, float duration, StrikeStyle style) { int num = FirstIndexOrFallback(_rightThumbFingerIndices, _rightNonThumbFingerIndices); if (num < 0) { num = FirstIndexOrFallback(_leftThumbFingerIndices, _nonThumbFingerIndices); } if (num >= 0) { PlayDeliberateKeystroke(num, strength, duration, style, -0.0069999998f); } } private void PlayArrowKeystroke(KeyControl key) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) List list = ((_rightNonThumbFingerIndices.Count > 0) ? _rightNonThumbFingerIndices : _rightThumbFingerIndices); if (list == null || list.Count <= 0) { list = _nonThumbFingerIndices; } if (list != null && list.Count > 0) { int num = ((key == null) ? _runtimeRng.Next() : ((int)key.keyCode)); int fingerIndex = list[(num & 0x7FFFFFFF) % list.Count]; PlayDeliberateKeystroke(fingerIndex, 0.78f, 0.12f, StrikeStyle.Arrow, -0.02f); } } private float RandomKeystrokeDuration() { return Range(_runtimeRng, 0.13f, 0.2f); } private static int FirstIndexOrFallback(List preferred, List fallback) { if (preferred != null && preferred.Count > 0) { return preferred[0]; } if (fallback != null && fallback.Count > 0) { return fallback[0]; } return -1; } private static bool IsSpaceKey(KeyControl key) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 if (key != null) { return (int)key.keyCode == 1; } return false; } private static bool IsEnterKey(KeyControl key) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 if (key != null) { if ((int)key.keyCode != 2) { return (int)key.keyCode == 77; } return true; } return false; } private static bool IsArrowKey(KeyControl key) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 if (key == null) { return false; } if ((int)key.keyCode != 63 && (int)key.keyCode != 64 && (int)key.keyCode != 61) { return (int)key.keyCode == 62; } return true; } private Transform ResolveHomeForArm(ArmChain arm) { if (arm == _left) { return _leftHome; } if (arm == _right) { return _rightHome; } return null; } private void PoseTarget(ArmChain arm, Transform home, Quaternion goalRot, float extend, float typingTime, float bobGain, float phase, float tapDip) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: 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_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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_012f: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) if (arm != null && !((Object)(object)arm.Target == (Object)null) && !((Object)(object)arm.Target.parent == (Object)null) && !((Object)(object)home == (Object)null)) { Transform parent = arm.Target.parent; Vector3 val = parent.TransformPoint(arm.RestTargetLocalPosition); Quaternion val2 = parent.rotation * arm.RestTargetLocalRotation; Vector3 val3 = Vector3.zero; if (bobGain > 0f) { float num = 0.01f * (0.6f * Mathf.Sin(5.6548667f * typingTime + phase) + 0.4f * Mathf.Sin(9.78292f * typingTime + phase * 2.1f)); float num2 = 0.03f * (0.6f * Mathf.Sin(MathF.PI * typingTime + phase * 1.7f) + 0.4f * Mathf.Sin(4.115486f * typingTime + phase * 0.6f)); float num3 = 0.004f * Mathf.Clamp01(tapDip); val3 += Vector3.up * (num * bobGain) + Vector3.down * (num3 * num3 / Mathf.Max(0.0001f, 0.004f) * bobGain); val3 += _mainframeRoot.right * (num2 * bobGain); } val3 += GetHandStrikeOffset(arm, extend); Vector3 val4 = home.position + _mainframeRoot.rotation * HandHomeLocalOffset + val3; Vector3 val5 = ClampGoalToReach(arm, val4); arm.LastUnclampedGoal = val4; arm.LastClampedGoal = val5; Vector3 val6 = Vector3.Lerp(val, val5, 0.5f); val6.y = Mathf.Min(val.y, val5.y) - 0.02f; Vector3 val7 = Vector3.Lerp(val, val6, extend); Vector3 val8 = Vector3.Lerp(val6, val5, extend); arm.Target.position = Vector3.Lerp(val7, val8, extend); Quaternion val9 = goalRot; float handStrikeEnvelope = GetHandStrikeEnvelope(arm); if (handStrikeEnvelope > 0f && Mathf.Abs(arm.WristRollAccentDegrees) > 0.001f) { val9 = Quaternion.AngleAxis(arm.WristRollAccentDegrees * handStrikeEnvelope, _mainframeRoot.forward) * val9; } arm.Target.rotation = Quaternion.Slerp(val2, val9, extend); } } private Vector3 GetHandStrikeOffset(ArmChain arm, float extend) { //IL_0011: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0055: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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) if (arm == null || (Object)(object)_mainframeRoot == (Object)null) { return Vector3.zero; } Vector3 val = _mainframeRoot.right * arm.KeyDriftX; float handStrikeEnvelope = GetHandStrikeEnvelope(arm); if (handStrikeEnvelope > 0f) { val += Vector3.down * (arm.StrikeDip * handStrikeEnvelope); val += _mainframeRoot.forward * (arm.StrikeForward * handStrikeEnvelope); } return val * Mathf.Clamp01(extend); } private static Vector3 ClampGoalToReach(ArmChain arm, Vector3 goalPos) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00d9: 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_00e3: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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) if (arm == null || (Object)(object)arm.Upper == (Object)null || arm.ChainLength <= 0.05f) { return goalPos; } Vector3 position = arm.Upper.position; Vector3 val = goalPos - position; float magnitude = ((Vector3)(ref val)).magnitude; float num = arm.ChainLength * 0.92f; if (magnitude <= num || magnitude <= 0.0001f) { return goalPos; } float num2 = goalPos.y - position.y; if (Mathf.Abs(num2) >= num * 0.98f) { return position + val * (num / magnitude); } Vector3 val2 = val; val2.y = 0f; float magnitude2 = ((Vector3)(ref val2)).magnitude; if (magnitude2 <= 0.0001f) { return position + val * (num / magnitude); } float num3 = Mathf.Sqrt(Mathf.Max(0f, num * num - num2 * num2)); return position + val2 * (num3 / magnitude2) + Vector3.up * num2; } private static float GetHandStrikeEnvelope(ArmChain arm) { if (arm == null || arm.StrikeElapsed < 0f || arm.StrikeDuration <= 0f) { return 0f; } float num = Mathf.Clamp01(arm.StrikeElapsed / arm.StrikeDuration); if (num < 0.35f) { return Smooth(num / 0.35f); } return 1f - Smooth((num - 0.35f) / 0.65f); } private static void AdvanceHandMotion(ArmChain arm, float deltaTime) { if (arm == null || deltaTime <= 0f) { return; } if (arm.StrikeElapsed >= 0f) { arm.StrikeElapsed += deltaTime; if (arm.StrikeElapsed >= arm.StrikeDuration) { arm.StrikeElapsed = -1f; arm.StrikeStrength = 0f; arm.StrikeDip = 0f; arm.StrikeForward = 0f; arm.WristRollAccentDegrees = 0f; } } else { arm.KeyDriftX = Mathf.MoveTowards(arm.KeyDriftX, 0f, 0.005f * deltaTime); } } private Quaternion ComputeHandGoalRotation(Transform home, float thumbLocalX) { //IL_0006: 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_0013: 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_002e: 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_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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0071: 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_0078: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_0098: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00a5: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) Vector3 up = _mainframeRoot.up; Vector3 val = Quaternion.AngleAxis((0f - Mathf.Sign(_mainframeRoot.InverseTransformPoint(home.position).x)) * 8f, up) * _mainframeRoot.forward; Vector3 val2 = Vector3.Cross(val, up); val = Quaternion.AngleAxis(2f, ((Vector3)(ref val2)).normalized * -1f) * val; val2 = up - Vector3.Dot(up, val) * val; Quaternion val3 = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, val); Quaternion val4 = Quaternion.AngleAxis(6f, val) * val3; if ((val4 * new Vector3(thumbLocalX, 0f, 0f)).y < (val3 * new Vector3(thumbLocalX, 0f, 0f)).y) { val4 = Quaternion.AngleAxis(-6f, val) * val3; } return val4; } private static void ApplyFingerTyping(List fingers, float baseGain) { //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) if (fingers == null || fingers.Count <= 0) { return; } for (int i = 0; i < fingers.Count; i++) { FingerChain fingerChain = fingers[i]; if (fingerChain == null || (Object)(object)fingerChain.Root == (Object)null) { continue; } float num = (fingerChain.IsThumb ? 0.3f : 1f); float liftK = 0f; float pressK = 0f; float keystrokeStrength = fingerChain.KeystrokeStrength; if (fingerChain.KeystrokeElapsed >= 0f && fingerChain.KeystrokeDuration > 0f) { float num2 = fingerChain.KeystrokeElapsed / fingerChain.KeystrokeDuration; if (num2 < 1f) { KeystrokeEnvelope(num2, out liftK, out pressK); } else { fingerChain.KeystrokeElapsed = -1f; } } float num3 = 22f * baseGain * num; float num4 = 18f * baseGain * num; float num5 = 14f * fingerChain.LiftScale * num * keystrokeStrength; float num6 = 10f * fingerChain.LiftScale * num * keystrokeStrength; float num7 = 10f * fingerChain.PressScale * num * keystrokeStrength; float num8 = Mathf.Lerp(num3, 0f - num5, liftK) + num7 * pressK; float num9 = num4 + num6 * liftK + num7 * 0.6f * pressK; Transform root = fingerChain.Root; root.localRotation *= Quaternion.AngleAxis(num8, fingerChain.RootCurlAxis); if ((Object)(object)fingerChain.Mid != (Object)null) { Transform mid = fingerChain.Mid; mid.localRotation *= Quaternion.AngleAxis(num9, fingerChain.MidCurlAxis); } } } private static void AdvanceKeystrokes(List fingers, float deltaTime) { if (fingers == null || deltaTime <= 0f) { return; } for (int i = 0; i < fingers.Count; i++) { FingerChain fingerChain = fingers[i]; if (fingerChain != null && !(fingerChain.KeystrokeElapsed < 0f)) { fingerChain.KeystrokeElapsed += deltaTime; if (fingerChain.KeystrokeElapsed >= fingerChain.KeystrokeDuration) { fingerChain.KeystrokeElapsed = -1f; fingerChain.KeystrokeStrength = 0f; } } } } private static float GetHandTapDip(List fingers) { if (fingers == null || fingers.Count <= 0) { return 0f; } float num = 0f; for (int i = 0; i < fingers.Count; i++) { FingerChain fingerChain = fingers[i]; if (fingerChain != null && !(fingerChain.KeystrokeElapsed < 0f) && !(fingerChain.KeystrokeDuration <= 0f)) { float num2 = fingerChain.KeystrokeElapsed / fingerChain.KeystrokeDuration; if (!(num2 >= 1f)) { KeystrokeEnvelope(num2, out var _, out var pressK); num = Mathf.Max(num, pressK * fingerChain.PressScale * fingerChain.KeystrokeStrength); } } } return Mathf.Clamp01(num); } private static void KeystrokeEnvelope(float u, out float liftK, out float pressK) { if (u < 0.18f) { liftK = Smooth(u / 0.18f); pressK = 0f; } else if (u < 0.35f) { float num = Smooth((u - 0.18f) / 0.17f); liftK = 1f - num; pressK = num; } else if (u < 0.7f) { liftK = 0f; pressK = 1f - Smooth((u - 0.35f) / 0.35f); } else { liftK = 0f; pressK = 0f; } } private static float Smooth(float x) { return x * x * (3f - 2f * x); } private void CaptureRendererState(PlayerControllerB player) { if (!((Object)(object)player == (Object)null)) { _armsRenderer = player.thisPlayerModelArms; if (!((Object)(object)_armsRenderer == (Object)null)) { _savedArmsRendererEnabled = ((Renderer)_armsRenderer).enabled; _armsRendererStateCaptured = true; ((Renderer)_armsRenderer).enabled = true; } } } private void RestoreRendererState() { if (_armsRendererStateCaptured && !((Object)(object)_armsRenderer == (Object)null)) { ((Renderer)_armsRenderer).enabled = _savedArmsRendererEnabled; } } private void CaptureTargetRest(ArmChain arm) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0064: Unknown result type (might be due to invalid IL or missing references) if (arm != null && !((Object)(object)arm.Target == (Object)null) && !((Object)(object)arm.Target.parent == (Object)null)) { Transform parent = arm.Target.parent; arm.RestTargetLocalPosition = parent.InverseTransformPoint(arm.Target.position); arm.RestTargetLocalRotation = Quaternion.Inverse(parent.rotation) * arm.Target.rotation; } } private static void RestoreTargetPose(ArmChain arm) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (arm != null && !((Object)(object)arm.Target == (Object)null)) { if ((Object)(object)arm.Target.parent != (Object)null) { arm.Target.localPosition = arm.RestTargetLocalPosition; arm.Target.localRotation = arm.RestTargetLocalRotation; } else { arm.Target.position = arm.RestTargetLocalPosition; arm.Target.rotation = arm.RestTargetLocalRotation; } } } private void CaptureBoneRest(Transform armRoot) { //IL_0022: 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) if (!((Object)(object)armRoot == (Object)null)) { Transform[] componentsInChildren = ((Component)armRoot).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { _boneRest.Add(new BoneRestPose(val, val.localPosition, val.localRotation)); } } } private void RestoreBoneRestSnapshot() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _boneRest.Count; i++) { BoneRestPose boneRestPose = _boneRest[i]; if (!((Object)(object)boneRestPose.Transform == (Object)null)) { boneRestPose.Transform.localPosition = boneRestPose.LocalPosition; boneRestPose.Transform.localRotation = boneRestPose.LocalRotation; } } } private static void CaptureChainLength(ArmChain arm) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (arm != null && !((Object)(object)arm.Upper == (Object)null) && !((Object)(object)arm.Lower == (Object)null) && !((Object)(object)arm.Hand == (Object)null)) { float num = Vector3.Distance(arm.Upper.position, arm.Lower.position); float num2 = Vector3.Distance(arm.Lower.position, arm.Hand.position); arm.ChainLength = num + num2; } } private static void CaptureForearmRollCarrier(ArmChain arm) { //IL_0027: 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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) //IL_0052: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) if (arm != null && !((Object)(object)arm.Lower == (Object)null) && !((Object)(object)arm.Hand == (Object)null)) { arm.RestHandInLower = Quaternion.Inverse(arm.Lower.rotation) * arm.Hand.rotation; Quaternion val = Quaternion.Inverse(arm.Lower.rotation); Vector3 val2 = arm.Hand.position - arm.Lower.position; arm.LowerBoneAxisLocal = val * ((Vector3)(ref val2)).normalized; } } private static void DeriveFingerCurlAxes(Transform hand, List fingers) { //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_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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0050: 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_0076: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hand == (Object)null || fingers == null) { return; } Vector3 palmWorld = hand.rotation * Vector3.back; foreach (FingerChain finger in fingers) { Vector3 val = (((Object)(object)finger.Mid != (Object)null) ? (finger.Mid.position - finger.Root.position) : (finger.Root.rotation * Vector3.up)); Vector3 normalized = ((Vector3)(ref val)).normalized; finger.RootCurlAxis = SignedCurlAxis(finger.Root, normalized, palmWorld, ((Object)(object)finger.Mid != (Object)null) ? finger.Mid : finger.Root); if ((Object)(object)finger.Mid != (Object)null) { val = finger.Mid.rotation * Vector3.up; Vector3 normalized2 = ((Vector3)(ref val)).normalized; finger.MidCurlAxis = SignedCurlAxis(finger.Mid, normalized2, palmWorld, finger.Mid); } } } private static Vector3 SignedCurlAxis(Transform bone, Vector3 boneDirWorld, Vector3 palmWorld, Transform tipRef) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_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_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_001c: 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_0022: 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_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_0041: 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_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) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_0079: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.Cross(boneDirWorld, palmWorld); Vector3 normalized = ((Vector3)(ref val)).normalized; Vector3 val2 = Quaternion.Inverse(bone.rotation) * normalized; Vector3 val3 = tipRef.TransformPoint(0f, 0.05f, 0f); Quaternion localRotation = bone.localRotation; bone.localRotation = localRotation * Quaternion.AngleAxis(20f, val2); Vector3 val4 = tipRef.TransformPoint(0f, 0.05f, 0f); bone.localRotation = localRotation; if (Vector3.Dot(val4 - val3, palmWorld) < 0f) { val2 = -val2; } return val2; } private static void CollectFingers(Transform hand, int seed, List fingers) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown if ((Object)(object)hand == (Object)null || fingers == null) { return; } Random random = new Random(seed); foreach (Transform item in hand) { Transform val = item; if (!((Object)val).name.StartsWith("finger", StringComparison.Ordinal)) { continue; } Transform mid = null; foreach (Transform item2 in val) { Transform val2 = item2; if (((Object)val2).name.StartsWith("finger", StringComparison.Ordinal)) { mid = val2; } } bool flag = ((Object)val).name.StartsWith("finger1", StringComparison.Ordinal); fingers.Add(new FingerChain { Root = val, Mid = mid, IsThumb = flag, SpeedScale = (flag ? Range(random, 0.3f, 0.45f) : Range(random, 0.75f, 1.25f)), LiftScale = (flag ? 0.25f : Range(random, 0.55f, 1.35f)), PressScale = (flag ? 0.5f : Range(random, 0.75f, 1.25f)), Phase = (float)random.NextDouble(), KeystrokeElapsed = -1f }); } } private static float Range(Random rng, float lo, float hi) { return lo + (float)rng.NextDouble() * (hi - lo); } private void RegisterFingerIndices() { _allFingers.Clear(); _leftThumbFingerIndices.Clear(); _rightThumbFingerIndices.Clear(); _leftNonThumbFingerIndices.Clear(); _rightNonThumbFingerIndices.Clear(); _nonThumbFingerIndices.Clear(); RegisterFingerIndices(_leftFingers, _leftThumbFingerIndices, _leftNonThumbFingerIndices, _left); RegisterFingerIndices(_rightFingers, _rightThumbFingerIndices, _rightNonThumbFingerIndices, _right); } private void RegisterFingerIndices(List fingers, List thumbIndices, List handNonThumbIndices, ArmChain arm) { if (fingers == null) { return; } for (int i = 0; i < fingers.Count; i++) { FingerChain fingerChain = fingers[i]; if (fingerChain != null) { fingerChain.Index = _allFingers.Count; fingerChain.Arm = arm; _allFingers.Add(fingerChain); if (fingerChain.IsThumb) { thumbIndices.Add(fingerChain.Index); continue; } handNonThumbIndices.Add(fingerChain.Index); _nonThumbFingerIndices.Add(fingerChain.Index); } } } private static Transform ResolveArmsSearchRoot(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return null; } if ((Object)(object)player.localArmsTransform != (Object)null) { return player.localArmsTransform; } Camera gameplayCamera = player.gameplayCamera; Transform val = (((Object)(object)gameplayCamera != (Object)null) ? ((Component)gameplayCamera).transform : null); if (!((Object)(object)val != (Object)null)) { return null; } return val.root; } private static Transform Require(Transform root, string name, List missing) { Transform obj = FindDeepChild(root, name); if ((Object)(object)obj == (Object)null) { AddMissing(missing, name); } return obj; } private static void AddMissing(List missing, string name) { if (missing == null || string.IsNullOrEmpty(name)) { return; } for (int i = 0; i < missing.Count; i++) { if (string.Equals(missing[i], name, StringComparison.Ordinal)) { return; } } missing.Add(name); } private void DisableWithMissing(List missing) { _disabled = true; if (!_missingWarningLogged) { _missingWarningLogged = true; string text = ((missing != null && missing.Count > 0) ? string.Join(", ", missing.ToArray()) : ""); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeArms] Missing required transform(s): " + text + "; procedural typing arms disabled.")); } } } private void CaptureCameraRelativeArmsPose() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_011d: 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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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) _armsRigPoseCaptured = false; _armsMetarigPoseCaptured = false; _armsCameraPinningEnabled = false; _armsMetarig = null; if ((Object)(object)_armsRoot == (Object)null) { return; } _armsRigRestLocalPosition = _armsRoot.localPosition; _armsRigRestLocalRotation = _armsRoot.localRotation; _armsRigPoseCaptured = true; _armsMetarig = FindDirectChild(_armsRoot, "metarig"); if ((Object)(object)_armsMetarig != (Object)null) { _armsMetarigRestLocalPosition = _armsMetarig.localPosition; _armsMetarigRestLocalRotation = _armsMetarig.localRotation; _armsMetarigPoseCaptured = true; } else { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV][MainframeArms] Missing direct 'metarig' child under local arms rig; metarig camera pinning skipped for this session."); } } Transform gameplayCameraTransform = GetGameplayCameraTransform(); if ((Object)(object)gameplayCameraTransform == (Object)null) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)"[LethalCCTV][MainframeArms] Gameplay camera unavailable at Begin; local arms camera pinning skipped for this session."); } return; } Quaternion val = Quaternion.Inverse(gameplayCameraTransform.rotation); _armsRigCameraRelativePosition = val * (_armsRoot.position - gameplayCameraTransform.position); _armsRigCameraRelativeRotation = val * _armsRoot.rotation; if (_armsMetarigPoseCaptured && (Object)(object)_armsMetarig != (Object)null) { _armsMetarigCameraRelativePosition = val * (_armsMetarig.position - gameplayCameraTransform.position); _armsMetarigCameraRelativeRotation = val * _armsMetarig.rotation; } _armsCameraPinningEnabled = true; } private void PinArmsToGameplayCamera() { //IL_0031: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0070: 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) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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) //IL_00d9: 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_00e0: 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) if (!_armsCameraPinningEnabled || !_armsRigPoseCaptured || (Object)(object)_armsRoot == (Object)null) { return; } Transform gameplayCameraTransform = GetGameplayCameraTransform(); if (!((Object)(object)gameplayCameraTransform == (Object)null)) { Quaternion rotation = gameplayCameraTransform.rotation; Vector3 val = Vector3.up * 0.25f; if ((Object)(object)_mainframeRoot != (Object)null) { val -= _mainframeRoot.forward * 0.2f; } _armsRoot.SetPositionAndRotation(gameplayCameraTransform.position + rotation * _armsRigCameraRelativePosition + val, rotation * _armsRigCameraRelativeRotation); if (_armsMetarigPoseCaptured && (Object)(object)_armsMetarig != (Object)null) { _armsMetarig.SetPositionAndRotation(gameplayCameraTransform.position + rotation * _armsMetarigCameraRelativePosition + val, rotation * _armsMetarigCameraRelativeRotation); } } } private void RestorePinnedArmsLocalPose() { //IL_001d: 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_0055: 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) if (_armsRigPoseCaptured && (Object)(object)_armsRoot != (Object)null) { _armsRoot.localPosition = _armsRigRestLocalPosition; _armsRoot.localRotation = _armsRigRestLocalRotation; } if (_armsMetarigPoseCaptured && (Object)(object)_armsMetarig != (Object)null) { _armsMetarig.localPosition = _armsMetarigRestLocalPosition; _armsMetarig.localRotation = _armsMetarigRestLocalRotation; } } private static Transform FindDirectChild(Transform root, string name) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(name)) { return null; } for (int i = 0; i < root.childCount; i++) { Transform child = root.GetChild(i); if ((Object)(object)child != (Object)null && string.Equals(((Object)child).name, name, StringComparison.Ordinal)) { return child; } } return null; } private void RestoreAfterBeginFailure() { try { RestoreBoneRestSnapshot(); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][MainframeArms] Begin-failure bone restore failed: " + ex.Message)); } } try { RestoreTargetPose(_left); RestoreTargetPose(_right); } catch (Exception ex2) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][MainframeArms] Begin-failure target restore failed: " + ex2.Message)); } } try { RestorePinnedArmsLocalPose(); } catch (Exception ex3) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV][MainframeArms] Begin-failure local arms rig restore failed: " + ex3.Message)); } } try { RestoreRendererState(); } catch (Exception ex4) { ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogWarning((object)("[LethalCCTV][MainframeArms] Begin-failure renderer restore failed: " + ex4.Message)); } } } private void TryLogBeginDiagnostics() { try { Transform gameplayCameraTransform = GetGameplayCameraTransform(); int num = CountNamedChildren(_mainframeRoot, "MainframeLeftHandHome"); int num2 = CountNamedChildren(_mainframeRoot, "MainframeRightHandHome"); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][MainframeArmsDiag] Begin diagnostics\nmainframeRoot name=" + TransformName(_mainframeRoot) + " pos=" + FormatTransformPosition(_mainframeRoot) + " forward=" + FormatTransformForward(_mainframeRoot) + " right=" + FormatTransformRight(_mainframeRoot) + " up=" + FormatTransformUp(_mainframeRoot) + "\n" + $"homeL path={FullPath(_leftHome)} pos={FormatTransformPosition(_leftHome)} count(MainframeLeftHandHome)={num}\n" + $"homeR path={FullPath(_rightHome)} pos={FormatTransformPosition(_rightHome)} count(MainframeRightHandHome)={num2}\n" + BuildBeginArmDiagnostics("L", _left) + "\n" + BuildBeginArmDiagnostics("R", _right) + "\ngameplayCamera pos=" + FormatTransformPosition(gameplayCameraTransform))); } LogMainframeConsoleBounds(); } catch { } } private void LogMainframeConsoleBounds() { //IL_0023: 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_0058: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_00b8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_mainframeRoot == (Object)null || (Object)(object)_leftHome == (Object)null) { return; } Vector3 position = _leftHome.position; Renderer[] componentsInChildren = ((Component)_mainframeRoot).GetComponentsInChildren(true); string text = "[LethalCCTV][MainframeArmsDiag] Console-area renderer bounds (world AABB, within 1.0m of left home):"; int num = 0; foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { Bounds bounds = val.bounds; if (!(Vector3.Distance(((Bounds)(ref bounds)).ClosestPoint(position), position) > 1f)) { text = text + "\n " + ((Object)((Component)val).transform).name + " min=" + FormatVector(((Bounds)(ref bounds)).min) + " max=" + FormatVector(((Bounds)(ref bounds)).max); num++; } } } if (num == 0) { text += "\n "; } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)text); } } private void TryLogLatePhaseDiagnostics(float sessionTime) { try { int mainframeArmsDiagPhase = GetMainframeArmsDiagPhase(sessionTime); if (mainframeArmsDiagPhase != _lastLoggedMainframeArmsDiagPhase) { _lastLoggedMainframeArmsDiagPhase = mainframeArmsDiagPhase; string mainframeArmsDiagPhaseName = GetMainframeArmsDiagPhaseName(mainframeArmsDiagPhase); string cameraPosition = FormatTransformPosition(GetGameplayCameraTransform()); LogLatePhaseArmDiagnostics("L", mainframeArmsDiagPhaseName, sessionTime, _leftHome, _left, cameraPosition); LogLatePhaseArmDiagnostics("R", mainframeArmsDiagPhaseName, sessionTime, _rightHome, _right, cameraPosition); } } catch { } } private Transform GetGameplayCameraTransform() { Camera val = (((Object)(object)_player != (Object)null) ? _player.gameplayCamera : null); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).transform; } private static int GetMainframeArmsDiagPhase(float sessionTime) { if (sessionTime < 0.52f) { return 0; } if (sessionTime < 1.62f) { return 1; } if (sessionTime < 2.52f) { return 2; } return 3; } private static string GetMainframeArmsDiagPhaseName(int phase) { return phase switch { 0 => "approach", 1 => "glance", 2 => "focusblend", 3 => "focus", _ => "unknown", }; } private static void LogLatePhaseArmDiagnostics(string tag, string phaseName, float sessionTime, Transform home, ArmChain arm, string cameraPosition) { //IL_006e: 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) if (arm == null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV][MainframeArmsDiag] LateTick phase={phaseName} t={sessionTime:F3} arm={tag} arm= camera={cameraPosition}"); } return; } ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV][MainframeArmsDiag] LateTick phase={phaseName} t={sessionTime:F3} arm={tag} home={FormatTransformPosition(home)} unclampedGoal={FormatVector(arm.LastUnclampedGoal)} clampedGoal={FormatVector(arm.LastClampedGoal)} upper={FormatTransformPosition(arm.Upper)} target={FormatTransformPosition(arm.Target)} hand={FormatTransformPosition(arm.Hand)} camera={cameraPosition}"); } } private static string BuildBeginArmDiagnostics(string tag, ArmChain arm) { Transform transform = arm?.Upper; Transform transform2 = arm?.Hand; Transform val = arm?.Target; Transform transform3 = (((Object)(object)val != (Object)null) ? val.parent : null); return tag + " upperPath=" + FullPath(transform) + " upperPos=" + FormatTransformPosition(transform) + " handPos=" + FormatTransformPosition(transform2) + " targetPath=" + FullPath(val) + " targetParent=" + TransformName(transform3) + " targetParentPos=" + FormatTransformPosition(transform3); } private static int CountNamedChildren(Transform root, string name) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(name)) { return 0; } int num = 0; Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (string.Equals(((Object)componentsInChildren[i]).name, name, StringComparison.Ordinal)) { num++; } } return num; } private static string FullPath(Transform transform) { if ((Object)(object)transform == (Object)null) { return ""; } string text = ((Object)transform).name; Transform parent = transform.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private static string TransformName(Transform transform) { if (!((Object)(object)transform != (Object)null)) { return ""; } return ((Object)transform).name; } private static string FormatTransformPosition(Transform transform) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)transform != (Object)null)) { return ""; } return FormatVector(transform.position); } private static string FormatTransformForward(Transform transform) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)transform != (Object)null)) { return ""; } return FormatVector(transform.forward); } private static string FormatTransformRight(Transform transform) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)transform != (Object)null)) { return ""; } return FormatVector(transform.right); } private static string FormatTransformUp(Transform transform) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)transform != (Object)null)) { return ""; } return FormatVector(transform.up); } private static string FormatVector(Vector3 value) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"({value.x:F3}, {value.y:F3}, {value.z:F3})"; } private void ClearState() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_0062: 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_006d: 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_0078: 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) _player = null; _armsRoot = null; _armsMetarig = null; _armsRigPoseCaptured = false; _armsMetarigPoseCaptured = false; _armsCameraPinningEnabled = false; _armsRigRestLocalPosition = Vector3.zero; _armsRigRestLocalRotation = Quaternion.identity; _armsRigCameraRelativePosition = Vector3.zero; _armsRigCameraRelativeRotation = Quaternion.identity; _armsMetarigRestLocalPosition = Vector3.zero; _armsMetarigRestLocalRotation = Quaternion.identity; _armsMetarigCameraRelativePosition = Vector3.zero; _armsMetarigCameraRelativeRotation = Quaternion.identity; _leftHome = null; _rightHome = null; _left = null; _right = null; _armsRenderer = null; _armsRendererStateCaptured = false; _savedArmsRendererEnabled = false; _begun = false; _runtimeFaulted = false; _runtimeFaultLogged = false; _inputWarningLogged = false; _lastLateSessionTime = -1f; _lastLoggedMainframeArmsDiagPhase = -1; _lastStrikeFrame = -1; _nextIntroBurstTime = 0f; _introBurstTargetCount = 0; _introBurstCount = 0; _lastIntroFingerIndex = -1; _introBurstComplete = false; _introSpaceStrokePlayed = false; _strokeSerial = 0; _boneRest.Clear(); _leftFingers.Clear(); _rightFingers.Clear(); _allFingers.Clear(); _leftThumbFingerIndices.Clear(); _rightThumbFingerIndices.Clear(); _leftNonThumbFingerIndices.Clear(); _rightNonThumbFingerIndices.Clear(); _nonThumbFingerIndices.Clear(); } private static Transform FindDeepChild(Transform root, string name) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(name)) { return null; } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (string.Equals(((Object)val).name, name, StringComparison.Ordinal)) { return val; } } return null; } private static void SolveChainIk(ArmChain arm) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_003b: 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) //IL_0046: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_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_0137: 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_013c: 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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: 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_0166: 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_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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) //IL_00c4: 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_00c8: 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_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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) Transform upper = arm.Upper; Transform lower = arm.Lower; Transform hand = arm.Hand; Vector3 position = arm.Target.position; Vector3 position2 = upper.position; Vector3 val = lower.position; Vector3 val2 = hand.position; float num = Vector3.Distance(position2, val); float num2 = Vector3.Distance(val, val2); Vector3 val3; if (Vector3.Distance(position2, position) >= num + num2) { val3 = position - position2; Vector3 normalized = ((Vector3)(ref val3)).normalized; val = position2 + normalized * num; val2 = val + normalized * num2; } else { for (int i = 0; i < 15; i++) { if (!(Vector3.Distance(val2, position) > 0.0001f)) { break; } val2 = position; Vector3 val4 = val2; val3 = val - val2; val = val4 + ((Vector3)(ref val3)).normalized * num2; val3 = val - position2; val = position2 + ((Vector3)(ref val3)).normalized * num; Vector3 val5 = val; val3 = val2 - val; val2 = val5 + ((Vector3)(ref val3)).normalized * num2; } } Vector3 val6 = lower.position - upper.position; upper.rotation = Quaternion.FromToRotation(val6, val - position2) * upper.rotation; Quaternion val7 = arm.Target.rotation * Quaternion.Inverse(arm.RestHandInLower); val3 = val2 - val; Vector3 normalized2 = ((Vector3)(ref val3)).normalized; lower.rotation = Quaternion.FromToRotation(val7 * arm.LowerBoneAxisLocal, normalized2) * val7; hand.rotation = arm.Target.rotation; } } internal static class MonitorFocus { private sealed class ScanLabel { public RectTransform Rect; public Image Tracer; public Image Background; public Image Top; public Image Bottom; public Image Left; public Image Right; public Image Center; public TextMeshProUGUI Header; public TextMeshProUGUI SubText; } private sealed class PaneFrame { public Image[] Segments; } private sealed class ContextTarget { public Component Component; public string DisplayName; public string CommandHint; public Vector3 Position; public float Radius; public bool Commandable; public Color Color; public float ExpiresAt; } private sealed class FocusHudDimTarget { public CanvasGroup Group; public float OriginalAlpha; public int InstanceId; public bool AddedByUs; } private sealed class FocusHudGraphicTarget { public Graphic Graphic; public float OriginalAlpha; public int InstanceId; } private struct FocusPathKnot { internal float T; internal Vector3 Position; internal Quaternion Rotation; } private enum StationEditMenuTarget { None, BothHands, LeftHand, RightHandCamera, RightHandAction, FocusView, RadarView, ThirdPersonDebug, ThirdPersonPlayer } private struct StationPlayerPoseSnapshot { internal bool Valid; internal PlayerControllerB Player; internal Vector3 Position; internal Quaternion Rotation; internal Vector3 ServerPosition; internal bool SnapToServerPosition; internal bool DisableSyncInAnimation; internal bool DisableLookInput; internal bool FreeRotationInInteractAnimation; internal bool ClampLooking; internal float MinVerticalClamp; internal float MaxVerticalClamp; internal float HorizontalClamp; internal bool InSpecialInteractAnimation; internal bool EnteringSpecialAnimation; internal bool HadController; internal bool ControllerDetectCollisions; internal bool ControllerEnabled; internal bool WasCrouching; internal bool CameraBaselineCaptured; internal Vector3 CameraPlayerLocalPosition; } private sealed class LocalRendererState { public Renderer Renderer; public bool WasEnabled; public Material[] SharedMaterials; public ShadowCastingMode ShadowCastingMode; public bool ReceiveShadows; public bool ForceRenderingOff; public bool AllowOcclusionWhenDynamic; public bool HasUpdateWhenOffscreen; public bool UpdateWhenOffscreen; public Transform Transform; public Vector3 LocalPosition; public bool ApplyFirstPersonArmsOffset; public Transform OffsetTransform; public Vector3 OffsetLocalPosition; public Quaternion OffsetLocalRotation; } private sealed class LocalLodGroupState { public LODGroup Group; public bool WasEnabled; } private sealed class PlacementEditSession { public Transform Transform; public CCTVCamera Camera; public Tile Tile; public string ObjectKind; public string ObjectId; public string Label; public Vector3 StartPosition; public Quaternion StartRotation; public bool CreatedDuringEdit; public int PreviousPage; public int PreviousSlot; } [CompilerGenerated] private static class <>O { public static Action <0>__OnExitFocusPerformed; public static Action <1>__OnCycleActivePrevPerformed; public static Action <2>__OnCycleActiveNextPerformed; public static Action <3>__OnPagePrevPerformed; public static Action <4>__OnPageNextPerformed; public static Action <5>__OnHackSubmitPerformed; public static Action <6>__OnPingMarkerPerformed; public static Action <7>__OnWalkiePushToTalkPerformed; public static Action <8>__OnWalkiePushToTalkCanceled; public static Action <9>__OnToggleControlsOverlayPerformed; public static CameraCallback <10>__OnCameraPreCull; public static Action <11>__ApplyStationPlayerPoseLock; public static Action <12>__ReassertLocalPlayerObstructors; public static Action <13>__ApplyPhysicalFocusView; public static Action <14>__ApplyFirstPersonArmsOffsetToForcedRenderers; public static Action <15>__SyncCameraAudioProxy; public static Action <16>__RefreshBodycamFocusSlot; public static Action <17>__RefreshTurretFocusPage; } private static HackingOverlay _hackingOverlay; private static MainframeControlOverlay _mainframeOverlay; private const int ENTRY_PERF_MAX_STEPS = 96; private const int ENTRY_PERF_FOLLOWUP_FRAMES = 1; private const double ENTRY_PERF_MIN_REPORTED_MS = 0.05; private static readonly string[] _entryPerfStepNames = new string[96]; private static readonly long[] _entryPerfStepTicks = new long[96]; private static readonly StringBuilder _entryPerfBuilder = new StringBuilder(1024); private static int _entryPerfStepCount; private static bool _entryPerfCapturing; private static bool _entryPerfWasFocusedAtFrameStart; private static bool _entryPerfFollowupFrame; private static int _entryPerfFollowupFramesRemaining; private static long _entryPerfFrameStartedAt; private static long _entryPerfLastMarkAt; private static long _entryPerfOverflowTicks; private static int _entryPerfOverflowSteps; private const float VISOR_SNAP_MAX_TRACK_DISTANCE_M = 2f; private const int VISOR_SNAP_PROBE_LOG_BUDGET = 3; private static int _visorSnapProbeLogsRemaining; private static double _hudScanFieldsMs; private static double _hudScanCanvasSiblingsMs; private static double _hudScanCursorMs; private static double _hudScanPromptsMs; private static double _hudScanNamedChromeMs; private static double _hudScanScreenSpaceMs; private static float _focusHudScanRearmAt; private const float OVERLAY_WIDTH = 960f; private const float OVERLAY_HEIGHT = 720f; private const float OVERLAY_TOP_SECTION_HEIGHT = 480f; private const float OVERLAY_BOTTOM_SECTION_HEIGHT = 240f; private const float OVERLAY_QUAD_WIDTH = 420f; private const float OVERLAY_QUAD_HEIGHT = 212f; private const float OVERLAY_GAP = 14f; private const float OVERLAY_LEFT_COLUMN_WIDTH = 520f; private const float OVERLAY_RIGHT_COLUMN_WIDTH = 392f; private const float OVERLAY_BOTTOM_MARGIN = 10f; private const float OVERLAY_BOTTOM_DOCK_HEIGHT = 220f; private const float OVERLAY_RIGHT_TOP_PANEL_HEIGHT = 92f; private const float OVERLAY_RIGHT_DOCK_GAP = 8f; private const float OVERLAY_RIGHT_BOTTOM_RADAR_HEIGHT = 120f; private const float OVERLAY_OUTLINE_BORDER_PX = 3f; private const float OVERLAY_LABEL_WIDTH = 92f; private const float OVERLAY_LABEL_HEIGHT = 22f; private const float OVERLAY_LABEL_INSET = 8f; private const float OVERLAY_STATUS_HEIGHT = 30f; private const float OVERLAY_BACKPLATE_MARGIN = 12f; private const float OVERLAY_BACKPLATE_RULE_PX = 3f; private const float OVERLAY_FRAME_CORNER_PX = 46f; private const float OVERLAY_FRAME_THICKNESS_PX = 2f; private const int OVERLAY_SCAN_LABEL_COUNT = 6; private const float OVERLAY_SCAN_LABEL_WIDTH = 190f; private const float OVERLAY_SCAN_LABEL_HEIGHT = 48f; private const float OVERLAY_SCAN_TRACER_THICKNESS = 3f; private const float OVERLAY_CONTEXT_DURATION = 8f; private const float CONTEXT_RAY_DISTANCE = 85f; private const float CONTEXT_SNAP_VIEWPORT_RADIUS = 0.095f; private const float ZOOM_MIN_FOV = 22f; private const float STATION_FOCUS_EXIT_SECONDS = 0.6f; private const float STATION_POSE_SETTLE_RATE = 20f; private const float STATION_POSE_SETTLE_TIMEOUT_SECONDS = 1.5f; private const float STATION_POSE_SETTLE_POSITION_TOLERANCE_M = 0.01f; private const float STATION_POSE_SETTLE_YAW_TOLERANCE_DEG = 0.5f; private const float STATION_POSE_SETTLE_CAMERA_TOLERANCE_DEG = 0.5f; private const float API_ROOT_WORLD_TELEMETRY_INTERVAL_SECONDS = 1f; private const float STATION_FOCUS_ENTER_BUTTON_PRESS_DELAY = 0f; private const float STATION_FOCUS_ENTER_TOTAL_SECONDS = 1.1f; private const float STATION_INTRO_HAND_FOLLOW_SMOOTHING_RATE = 14f; private const float STATION_INTRO_HAND_FOLLOW_BLEND_IN_SECONDS = 0.15f; private const float STATION_INTRO_HAND_FOLLOW_BLEND_OUT_START_T = 0.73f; private const float STATION_INTRO_HAND_FOLLOW_MIN_DIRECTION_SQR_M = 0.0025f; private const string STATION_INTRO_HAND_FOLLOW_TARGET_NAME = "ArmsLeftArm_target"; private const string STATION_INTRO_HAND_FOLLOW_TARGET_PATH = "ScavengerModelArmsOnly/metarig/spine.003/RigArms/LeftArm/ArmsLeftArm_target"; private const float STATION_FOCUS_ENTER_KNOT_BUTTON = 0.218f; private const float STATION_FOCUS_ENTER_KNOT_BUTTON_HOLD = 0.455f; private const float STATION_FOCUS_ENTER_KNOT_LEVER = 0.818f; private const float STATION_FOCUS_ENTER_BUTTON_FOV_WIDEN_DEG = 6f; private const float STATION_FOCUS_ENTER_LEVER_FOV_WIDEN_DEG = 4f; private const float STATION_FOCUS_ENTER_BUTTON_LOOK_BLEND_END_T = 0.12f; private const float STATION_FOCUS_ENTER_BUTTON_EYE_FRACTION = 0.4f; private const float STATION_FOCUS_ENTER_PRESS_REACH_BOUND_M = 0.6f; private const float STATION_FOCUS_ENTER_LEVER_REACH_BOUND_M = 0.75f; private const float STATION_FOCUS_EYE_PULLBACK_M = 0.22f; private const float STATION_FOCUS_EYE_RAISE_M = 0.12f; private const float STATION_FOCUS_EYE_PITCH_UP_DEG = 3.5f; private const float STATION_FOCUS_ENTER_MIN_CONTACT_EYE_DISTANCE_M = 0.35f; private const float STATION_FOCUS_ENTER_FEED_FLIP_DELAY = 0.6f; private const float STATION_FOCUS_EXIT_HAND_RELEASE_DELAY = 0.15f; private const float STATION_CAMERA_CONTROL_ENABLE_DELAY = 1.35f; private const int INTRO_CAMERA_FOCUS_RENDER_TELEMETRY_BUDGET = 16; private const float STATION_RADAR_LOOK_YAW_DEG = 28f; private const float STATION_RADAR_LOOK_PITCH_DEG = -1.5f; private const float STATION_RADAR_LOOK_ROLL_DEG = -3.5f; private const float STATION_RADAR_GLANCE_SECONDS = 0.46f; private const float STATION_THIRD_PERSON_PREVIEW_DISTANCE = 1.45f; private const float STATION_THIRD_PERSON_PREVIEW_SIDE_OFFSET = 0.82f; private const float STATION_THIRD_PERSON_PREVIEW_HEIGHT_OFFSET = 0.42f; private const float STATION_THIRD_PERSON_PREVIEW_TARGET_HEIGHT = 0.42f; private const float STATION_GLOBAL_THIRD_PERSON_DISTANCE = 2.1f; private const float STATION_GLOBAL_THIRD_PERSON_SIDE_OFFSET = 0.92f; private const float STATION_GLOBAL_THIRD_PERSON_HEIGHT_OFFSET = 0.34f; private const float STATION_GLOBAL_THIRD_PERSON_FOV = 68f; private const float STATION_THIRD_PERSON_ORBIT_YAW_MIN = -160f; private const float STATION_THIRD_PERSON_ORBIT_YAW_MAX = 160f; private const float STATION_THIRD_PERSON_ORBIT_PITCH_MIN = -48f; private const float STATION_THIRD_PERSON_ORBIT_PITCH_MAX = 58f; private const float FIRST_PERSON_ARMS_OFFSET_SPEED = 0.22f; private const float FIRST_PERSON_ARMS_OFFSET_FAST_SPEED = 1.2f; private const float FIRST_PERSON_ARMS_OFFSET_MAX = 2.5f; private const float FIRST_PERSON_ARMS_OFFSET_STATUS_INTERVAL = 0.25f; private const float RADAR_INSET_REFRESH_INTERVAL = 0.2f; private const int PHYSICAL_FOCUS_RT_WIDTH = 1920; private const int PHYSICAL_FOCUS_RT_HEIGHT = 1440; private const int PHYSICAL_FOCUS_UI_LAYER = 29; private const float FOCUS_PLAYER_HUD_ALPHA = 0.01f; private const float FOCUS_PLAYER_HUD_REFRESH_INTERVAL = 8f; private const float STATION_FOCUS_OVERLAY_REFRESH_INTERVAL = 0.2f; private const float STATION_CAMERA_RENDER_BOOST_SECONDS = 0.2f; private const float STATION_FOCUS_GAMEPLAY_FAR_CLIP_M = 55f; private const float AUDIO_PROXY_VOICE_REFRESH_INTERVAL = 0.35f; private const float FOCUS_MACHINE_LOOP_VOLUME = 0.22f; private const string FOCUS_AUDIO_DIR = "Audio"; private const string FOCUS_CLICK_2_FILE = "ui_click_mx_2.ogg"; private const string FOCUS_CLICK_3_FILE = "ui_click_mx_3.ogg"; private const string FOCUS_MACHINE_LOOP_FILE = "old_machine_mx_2_loop.ogg"; private const string FOCUS_PAGE_FILE = "ui_submit_mx_7.ogg"; private const string FOCUS_PING_FILE = "retro_computer_beep_mx_1.ogg"; private const string FOCUS_INTERACT_FILE = "retro_computer_beep_mx_2.ogg"; private const string FOCUS_BOOT_FILE = "analog_computer_boot.ogg"; private static readonly Color OVERLAY_ACTIVE_GREEN = new Color(0.2f, 1f, 0.4f, 1f); private static readonly Color OVERLAY_AMBER = new Color(1f, 0.72f, 0.18f, 1f); private static readonly Color OVERLAY_REC_RED = new Color(1f, 0.28f, 0.24f, 1f); private const float OVERLAY_REC_BLINK_PERIOD = 1f; private const float OVERLAY_REC_BLINK_ON_FRACTION = 0.55f; private static readonly Color OVERLAY_SCAN_BLUE = new Color(0.18f, 0.76f, 1f, 1f); private static readonly Color OVERLAY_SCAN_RED = new Color(1f, 0.25f, 0.22f, 1f); private static readonly string[] FocusHudNameTokens = new string[15] { "health", "sprint", "stamina", "weight", "battery", "hotbar", "inventory", "itemslot", "item slot", "slot", "tooltip", "controltip", "control tip", "cursor", "scan" }; private static GameObject _overlayRoot; private static GameObject _physicalFocusRenderRigRoot; private static RenderTexture _physicalFocusRenderTexture; private static Camera _physicalFocusUiCamera; private static Texture2D _crtScanlineTexture; private static Sprite _crtScanlineSprite; private static Texture2D _terminalBackdropTexture; private static Sprite _terminalBackdropSprite; private static RawImage[] _overlayRawImages; private static RectTransform[] _overlayPaneRects; private static RectTransform[] _overlayOutlineRects; private static PaneFrame[] _overlayPaneFrames; private static TextMeshProUGUI[] _overlayCameraLabels; private static Image[] _overlayCameraLabelBackgrounds; private static RectTransform[] _overlayCameraLabelRects; private static TextMeshProUGUI _overlayHeaderText; private static TextMeshProUGUI _overlayPageText; private static TextMeshProUGUI _overlayClockText; private static TextMeshProUGUI _overlayRecText; private static Image _overlayRecDot; private static bool _overlayRecOn; private static float _nextOverlayHeaderRefreshTime; private static TextMeshProUGUI _overlayActiveText; private static RawImage _radarInsetImage; private static RectTransform _radarInsetRect; private static RectTransform _radarImageRect; private static TextMeshProUGUI _radarInsetStatus; private static RectTransform _operatorStatsRect; private static TextMeshProUGUI _operatorStatsText; private static RectTransform _signalLogRect; private static TextMeshProUGUI _signalLogTitleText; private static TextMeshProUGUI _signalLogText; private static TextMeshProUGUI _scanStatusText; private static GameObject _reviewMenuRoot; private static TextMeshProUGUI _reviewMenuText; private static GameObject _placementEditorRoot; private static TextMeshProUGUI _placementEditorText; private static Image _centerReticle; private static ScanLabel[] _scanLabels; private static LethalCCTVInputActions _inputActions; private static PlayerControllerB _audioListenerPlayer; private static GameObject _cameraAudioProxyRoot; private static AudioListener _cameraAudioProxyListener; private static AudioClip _switchSfx; private static AudioClip _scanSfx; private static AudioClip _pingSfx; private static AudioClip _rotateSfx; private static AudioClip[] _switchSfxPool; private static AudioClip _pageSfx; private static AudioClip _interactSfx; private static AudioClip _bootSfx; private static AudioClip _machineLoopSfx; private static GameObject _focusMachineLoopRoot; private static AudioSource _focusMachineLoopSource; private static bool _providedFocusAudioLoadStarted; private static float _nextRotateSfxTime; private static float _nextStatsRefreshTime; private static float _nextRadarInsetRefreshTime; private static float _nextSignalLogRefreshTime; private static float _scanVisibleUntil; private static bool _turretPageActive; private static float _turretHitmarkerUntil; private static bool _turretHitmarkerEnemy; private static bool _lastHackDockState; private static bool _lastDockTurretState; private static bool _focusDockLayoutInitialized; private static readonly Dictionary _zoomByCamera = new Dictionary(); private static readonly List _focusHudDimTargets = new List(64); private static readonly HashSet _focusHudDimTargetIds = new HashSet(); private static readonly List _focusHudGraphicTargets = new List(96); private static readonly HashSet _focusHudGraphicTargetIds = new HashSet(); private static bool _stationCameraControlActive; private static bool _stationCameraControlEnablePending; private static float _stationCameraControlEnableAt; private static ContextTarget _contextTarget; private static float _nextFocusHudDimRefreshAt; private static bool _focusHudDimActive; private static bool _focusHudSceneScanCompleted; private static float _nextStationFocusOverlayRefreshAt; private static float _stationCameraRenderBoostUntil; private static CCTVCamera _audioProxyCamera; private static GameObject _audioProxyTarget; private static bool _audioProxyFlip; private static float _nextAudioProxyVoiceRefreshAt; private static bool _isExitingFocus; private static bool _enterPerfLogPending; private static int _enterPerfFrame; private static float _exitSeamStartedAt; private static float _exitSeamLogUntil; private static float _exitSeamNextLogAt; private static Quaternion _exitSeamReferenceRotation = Quaternion.identity; private static bool _settleViewFramingLogPending; private static bool _arrivalViewFramingLogPending; private static bool _exitHandbackAnimationCompletePoseCaptured; private static Vector3 _exitHandbackAnimationCompletePosition; private static Quaternion _exitHandbackAnimationCompleteRotation = Quaternion.identity; private static bool _exitPostureLogPending; private static PlayerControllerB _exitPosturePlayer; private static float _exitPostureRestoredAt; private static float _exitPostureLogAt; private static int _exitPostureSampleIndex; private static PlayerControllerB _exitCameraInvariantPlayer; private static int _exitCameraInvariantScheduledFrame = -1; private static int _wasActiveSetFrame = -1; private static bool _priorDisableLook; private static bool _priorDisableMove; private static bool _priorDisableInteract; private static bool _cameraPlacementEditModeOpen; private static bool _reviewMenuOpen; private static int _reviewMenuSelectedIndex; private static readonly List _reviewSelectedTags = new List(); private static bool _reviewMenuTagMode; private static bool _placementEditorOpen; private static PlacementEditSession _placementEditSession; private static PlayerControllerB _focusedPlayer; private static Camera _physicalFocusCamera; private static Transform _physicalFocusCameraTransform; private static Vector3 _priorFocusCameraLocalPosition; private static Quaternion _priorFocusCameraLocalRotation; private static float _priorFocusCameraFov; private static bool _focusRenderBudgetActive; private static Camera _focusRenderBudgetCamera; private static float _focusRenderBudgetSavedFarClip; private static Vector3 _priorFocusCameraWorldPosition; private static Quaternion _priorFocusCameraWorldRotation; private static Vector3 _focusViewAnimationStartPosition; private static Quaternion _focusViewAnimationStartRotation; private static float _focusViewAnimationStartFov; private static Vector3 _focusViewAnimationTargetPosition; private static Quaternion _focusViewAnimationTargetRotation; private static float _focusViewAnimationTargetFov; private static float _focusViewAnimationStartedAt; private static float _focusViewAnimationDelayUntil; private static float _focusViewAnimationDuration; private const float FOCUS_ANIMATION_MAX_FRAME_STEP_SECONDS = 0.05f; private static float _focusViewAnimationElapsedSeconds; private static int _focusViewAnimationLastAdvanceFrame = -1; private static bool _focusViewAnimating; private static bool _focusViewExitPending; private static int _introCameraRenderedFramesLogged; private static int _introCameraLastRenderedFrame = -1; private static FocusPathKnot[] _focusViewEnterPath; private static Transform _stationIntroHandFollowTarget; private static Quaternion _stationIntroHandFollowSmoothedRotation = Quaternion.identity; private static bool _stationIntroHandFollowRotationInitialized; private static bool _stationIntroHandFollowResolutionAttempted; private static bool _stationIntroHandFollowTargetWasResolved; private static bool _stationIntroHandFollowActivated; private static bool _stationIntroHandFollowActiveLogged; private static bool _stationIntroHandFollowFallbackLogged; private static bool _stationIntroHandFollowSettleLogged; private static bool _focusViewAnimationHasWaypoint; private static Vector3 _focusViewWaypointPosition; private static Quaternion _focusViewWaypointRotation; private static bool _physicalFocusViewActive; private static bool _stationThirdPersonPreviewActive; private static bool _stationThirdPersonDebugPersistent; private static bool _stationGlobalThirdPersonCameraActive; private static Camera _stationGlobalThirdPersonCamera; private static Transform _stationGlobalThirdPersonCameraTransform; private static Vector3 _stationGlobalThirdPersonSavedLocalPosition; private static Quaternion _stationGlobalThirdPersonSavedLocalRotation; private static float _stationGlobalThirdPersonSavedFov; private static bool _stationGlobalThirdPersonSaved; private static bool _stationGlobalThirdPersonFramingLogged; private static float _stationThirdPersonOrbitYawDeg; private static float _stationThirdPersonOrbitPitchDeg; private static bool _stationEditMenuOpen; private static bool _operatorDebugToolsEnabledLastFrame = true; private static StationEditMenuTarget _stationEditMenuTarget; private static bool _stationPoseTrackingLogged; private static bool _stationPoseSettleActive; private static bool _stationPoseSettleTransferToFocus; private static PlayerControllerB _stationPoseSettlePlayer; private static Transform _stationPoseSettleAnchor; private static Vector3 _stationPoseSettleTargetPosition; private static Quaternion _stationPoseSettleTargetRotation; private static float _stationPoseSettleTargetCameraUp; private static bool _stationPoseSettleEntryCameraPoseCaptured; private static Vector3 _stationPoseSettleEntryCameraWorldPosition; private static Quaternion _stationPoseSettleEntryCameraWorldRotation = Quaternion.identity; private static bool _stationPoseSettleCameraRenderPinActive; private static Vector3 _stationPoseSettleCameraRenderPinSavedPosition; private static StationPlayerPoseSnapshot _stationPoseSettleSnapshot; private static float _stationPoseSettleStartedAt; private static int _stationPoseSettleFrames; private static int _stationPoseSettleHardSetFrame = -1; private static bool _stationPlayerPoseLockActive; private static PlayerControllerB _stationPlayerPosePlayer; private static Vector3 _stationPlayerPoseTargetPosition; private static Quaternion _stationPlayerPoseTargetRotation = Quaternion.identity; private static string _stationPlayerPoseTargetAnchorKind; private static bool _stationPlayerPoseApiModeConfigured; private static bool _stationPlayerPoseUsesApiFloorRoot; private static float _stationPlayerPoseFloorDeltaWorldY; private static float _stationPlayerPoseNextRootTelemetryAt; private static Vector3 _stationPlayerPoseSavedPosition; private static Quaternion _stationPlayerPoseSavedRotation; private static Quaternion _stationPlayerPoseHandbackRotation = Quaternion.identity; private static float _stationPlayerPoseHandbackCameraPitch; private static Vector3 _stationPlayerPoseSavedServerPosition; private static bool _stationPlayerPoseSavedSnapToServerPosition; private static bool _stationPlayerPoseSavedDisableSyncInAnimation; private static bool _stationPlayerPoseSavedFreeRotationInInteractAnimation; private static bool _stationPlayerPoseSavedInSpecialInteractAnimation; private static bool _stationPlayerPoseSavedEnteringSpecialAnimation; private static bool _stationPlayerPoseHadController; private static bool _stationPlayerPoseSavedControllerDetectCollisions; private static bool _stationPlayerPoseSavedControllerEnabled; private static bool _stationPlayerPoseSavedWasCrouching; private static bool _stationPlayerCameraBaselineCaptured; private static Vector3 _stationPlayerCameraPlayerLocalPosition; private static CCTVLocalCameraPositionStabilizer _stationPlayerCameraPositionStabilizer; private static readonly List _focusHiddenLocalRenderers = new List(); private static readonly List _focusForcedLocalRenderers = new List(); private static readonly List _controllerRestoreLocalRenderers = new List(); private static PlayerControllerB _controllerRestorePlayer; private static Transform _controllerRestoreLocalVisor; private static Vector3 _controllerRestoreLocalVisorLocalPosition; private static Quaternion _controllerRestoreLocalVisorLocalRotation = Quaternion.identity; private static Vector3 _controllerRestoreLocalVisorLocalScale = Vector3.one; private static readonly List _previewForcedLocalRenderers = new List(); private static readonly List _previewForcedLodGroups = new List(); private static bool _previewRendererFailureLogged; private static bool _previewCameraFramingLogged; private static bool _localFirstPersonArmsActiveLogged; private static bool _localFirstPersonArmsMissingLogged; private static bool _firstPersonArmsOffsetLoaded; private static Vector3 _firstPersonArmsOffset; private static bool _firstPersonArmsOffsetDirty; private static bool _firstPersonArmsOffsetEditingLastFrame; private static float _nextFirstPersonArmsOffsetStatusAt; private static bool _firstPersonArmsCameraPoseCaptured; private static Transform _firstPersonArmsCameraPoseRoot; private static bool _firstPersonArmsCameraFollowLogged; private static int _firstPersonArmsPresentationFrame = -1; private static Transform _firstPersonArmsPresentationRoot; private static Vector3 _firstPersonArmsPresentationAnimPosition; private static Quaternion _firstPersonArmsPresentationAnimRotation = Quaternion.identity; private static Vector3 _firstPersonArmsPresentationFinalPosition; private static Quaternion _firstPersonArmsPresentationFinalRotation = Quaternion.identity; private static Camera _previewForcedCamera; private static int _previewSavedCameraCullingMask; private static bool _previewCameraCullingMaskSaved; private static Transform _focusHiddenLocalVisor; private static Vector3 _focusHiddenLocalVisorLocalPosition; private static Quaternion _focusHiddenLocalVisorLocalRotation; private static Vector3 _focusHiddenLocalVisorLocalScale; private static Vector3 _focusHiddenLocalVisorHiddenWorldPosition; private static bool _holdLocalObstructorsForInteractionsApiRestore; private static readonly HashSet _localObstructorCallLogs = new HashSet(StringComparer.Ordinal); private static readonly HashSet _boundaryInputRecoveryLogs = new HashSet(StringComparer.Ordinal); private static float _stationRadarLookBlend; private static float _stationGlanceRestYawDeg; private static float _stationGlanceRestPitchDeg; private static bool _stationFeedFlipPending; private static float _stationFeedFlipAt; private static float _stationRadarLookSuppressedUntil; private static float _stationFocusAnchorForcedUntil; private static bool _radarLookEventState; private static bool _chairEventActive; private static readonly CameraPlacementReviewRating[] ReviewMenuRatings = new CameraPlacementReviewRating[10] { CameraPlacementReviewRating.Perfect, CameraPlacementReviewRating.TooLow, CameraPlacementReviewRating.Floating, CameraPlacementReviewRating.TooHigh, CameraPlacementReviewRating.PoorCoverage, CameraPlacementReviewRating.BlockedView, CameraPlacementReviewRating.LookingAtWall, CameraPlacementReviewRating.SkyboxVisible, CameraPlacementReviewRating.Duplicate, CameraPlacementReviewRating.ImportantRoom }; private static readonly string[] ReviewMenuLabels = new string[10] { "PERFECT", "TOO LOW / FLOOR", "FLOATING", "TOO HIGH", "POOR COVERAGE", "BLOCKED VIEW", "LOOKING AT WALL", "SKYBOX VISIBLE", "DUPLICATE", "IMPORTANT ROOM" }; private static readonly string[] ReviewTagValues = new string[13] { "doorway-visible", "doorway-not-visible", "frames-room-well", "does-not-frame-room", "stuck-in-furniture", "pipe-obstructed", "covers-mainframe", "good-height", "good-corner", "mainframe-room", "bad-mainframe-room", "company-stash-room", "bad-company-stash-room" }; private static readonly string[] ReviewTagLabels = new string[13] { "DOORWAY VISIBLE", "DOORWAY NOT VISIBLE", "FRAMES ROOM WELL", "DOES NOT FRAME ROOM", "STUCK IN FURNITURE/FIXTURE", "PIPE/OBSTRUCTION BLOCKING VIEW", "COVERS MAINFRAME", "GOOD HEIGHT", "GOOD CORNER", "MAINFRAME ROOM", "BAD MAINFRAME ROOM", "COMPANY STASH ROOM", "BAD COMPANY STASH ROOM" }; private static float _radarEditDiagNextLogAt; private static string _radarEditDiagBranch = ""; private static bool _radarEditDiagWrotePreviousFrame; private static Quaternion _radarEditDiagLastWrittenRotation = Quaternion.identity; private static bool _radarEditDiagHavePreviousSample; private static float _radarEditDiagPreviousAnchorYaw; private static float _radarEditDiagPreviousCamYaw; private static bool _stationViewpointChannelOverrideActive; private static Quaternion _stationViewpointSavedPoseRotation = Quaternion.identity; private static float _stationViewpointSavedCameraUp; private static float _stationViewpointSavedMinVerticalClamp; private static float _stationViewpointSavedMaxVerticalClamp; private static bool _debugToolsBindMissingLogged; private const float MAX_PRESENTATION_CAMERA_PITCH_DEGREES = 16f; internal static HackingOverlay HackingOverlay => _hackingOverlay; internal static MainframeControlOverlay MainframeOverlay => _mainframeOverlay; private static bool IsMainframeOverlayOpen { get { if (_mainframeOverlay != null) { return _mainframeOverlay.IsOpen; } return false; } } private static bool KeepLocalVisorDuringSessionEnabled => true; internal static bool InputBindingsUnavailable { get; private set; } internal static bool IsStationFeedFlipPending => _stationFeedFlipPending; internal static Image[] OverlayOutlines { get; private set; } internal static bool IsFocused { get; private set; } internal static bool IsEntryPoseSettleActive => _stationPoseSettleActive; internal static bool IsEnterCameraPathComplete { get { if (IsFocused && !_focusViewExitPending) { if (_physicalFocusViewActive) { return !_focusViewAnimating; } return true; } return false; } } internal static float EnterPresentationClockSeconds { get { if (!_focusViewAnimating || _focusViewExitPending || _focusViewEnterPath == null) { return -1f; } return _focusViewAnimationElapsedSeconds; } } internal static bool IsStationCameraFeedInteractionActive { get { if (IsFocused) { return Time.unscaledTime < _stationCameraRenderBoostUntil; } return false; } } internal static bool IsStationRadarLookActive { get { if (IsFocused) { if (!_radarLookEventState && !(_stationRadarLookBlend > 0.001f) && !IsStationRadarLookHeld()) { return CCTVOperatorStation.IsEditingDebugPlacement("radar"); } return true; } return false; } } internal static bool IsStationCameraControlActive => _stationCameraControlActive; internal static bool IsStationThirdPersonDebugViewActive { get { if (IsFocused) { if (!_stationThirdPersonPreviewActive) { return _stationThirdPersonDebugPersistent; } return true; } return false; } } internal static bool IsStationEditMenuOpen => _stationEditMenuOpen; internal static bool IsStationEditThirdPersonDebugActive { get { if (_stationEditMenuOpen) { return _stationEditMenuTarget == StationEditMenuTarget.ThirdPersonDebug; } return false; } } internal static bool IsTurretPageActive { get { if (_turretPageActive) { return ShipTurretController.IsUnlocked; } return false; } } private static bool IsHackingOverlayOpen { get { if (_hackingOverlay != null) { return _hackingOverlay.IsOpen; } return false; } } internal static bool WasActiveThisFrame { get; private set; } internal static int ActiveSlot { get; private set; } internal static bool IsReviewMenuOpen => _reviewMenuOpen; private static bool UseExitToStationPose => true; internal static bool IsOperatorDebugToolsEnabled { get { ConfigEntry val = SurveillanceBootstrap.Config?.EnableOperatorDebugTools; if (val == null) { if (!_debugToolsBindMissingLogged) { _debugToolsBindMissingLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Enable Operator Debug Tools binding missing; operator debug tools read as disabled."); } } return false; } return val.Value; } } private static void EnsureCameraAudioProxy() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)_cameraAudioProxyListener != (Object)null)) { _cameraAudioProxyRoot = new GameObject("LethalCCTV_CameraAudioProxy"); if ((Object)(object)SurveillanceBootstrap.Instance != (Object)null) { _cameraAudioProxyRoot.transform.SetParent(((Component)SurveillanceBootstrap.Instance).transform, false); } else { Object.DontDestroyOnLoad((Object)(object)_cameraAudioProxyRoot); } _cameraAudioProxyListener = _cameraAudioProxyRoot.AddComponent(); ((Behaviour)_cameraAudioProxyListener).enabled = false; } } private static void SyncCameraAudioProxy() { //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) if (!IsFocused) { RestoreAudioListenerToPlayer(); return; } CCTVCamera activeCamera = GetActiveCamera(); if ((Object)(object)activeCamera == (Object)null) { RestoreAudioListenerToPlayer(); return; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null || (Object)(object)val.activeAudioListener == (Object)null) { return; } EnsureCameraAudioProxy(); GameObject val2 = (((Object)(object)activeCamera.Cam != (Object)null) ? ((Component)activeCamera.Cam).gameObject : ((Component)activeCamera).gameObject); if ((Object)(object)val2 == (Object)null) { RestoreAudioListenerToPlayer(); return; } if ((Object)(object)_audioListenerPlayer != (Object)(object)val) { RestoreAudioListenerToPlayer(); _audioListenerPlayer = val; } bool flag = (Object)(object)IngamePlayerSettings.Instance != (Object)null && IngamePlayerSettings.Instance.flipCamera; bool flag2 = (Object)(object)_audioProxyCamera != (Object)(object)activeCamera || (Object)(object)_audioProxyTarget != (Object)(object)val2 || _audioProxyFlip != flag || !((Behaviour)_cameraAudioProxyListener).enabled || (Object)(object)_cameraAudioProxyRoot.transform.parent != (Object)(object)val2.transform; if (((Behaviour)val.activeAudioListener).enabled) { ((Behaviour)val.activeAudioListener).enabled = false; } if (flag2) { _cameraAudioProxyRoot.transform.SetParent(val2.transform, false); _cameraAudioProxyRoot.transform.localPosition = Vector3.zero; _cameraAudioProxyRoot.transform.localRotation = Quaternion.identity; if (flag) { _cameraAudioProxyRoot.transform.Rotate(0f, 180f, 0f, (Space)1); } ((Behaviour)_cameraAudioProxyListener).enabled = true; _audioProxyCamera = activeCamera; _audioProxyTarget = val2; _audioProxyFlip = flag; } if ((Object)(object)StartOfRound.Instance != (Object)null && (flag2 || Time.unscaledTime >= _nextAudioProxyVoiceRefreshAt)) { StartOfRound.Instance.audioListener = _cameraAudioProxyListener; StartOfRound.Instance.UpdatePlayerVoiceEffects(); _nextAudioProxyVoiceRefreshAt = Time.unscaledTime + 0.35f; } } private static void RestoreAudioListenerToPlayer() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = (((Object)(object)_audioListenerPlayer != (Object)null) ? _audioListenerPlayer : (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null)); _audioListenerPlayer = null; _audioProxyCamera = null; _audioProxyTarget = null; _audioProxyFlip = false; _nextAudioProxyVoiceRefreshAt = 0f; if ((Object)(object)_cameraAudioProxyListener != (Object)null) { ((Behaviour)_cameraAudioProxyListener).enabled = false; } if ((Object)(object)_cameraAudioProxyRoot != (Object)null && (Object)(object)SurveillanceBootstrap.Instance != (Object)null) { _cameraAudioProxyRoot.transform.SetParent(((Component)SurveillanceBootstrap.Instance).transform, false); _cameraAudioProxyRoot.transform.localPosition = Vector3.zero; _cameraAudioProxyRoot.transform.localRotation = Quaternion.identity; } if ((Object)(object)val != (Object)null && (Object)(object)val.gameplayCamera != (Object)null && (Object)(object)val.activeAudioListener != (Object)null) { val.ChangeAudioListenerToObject(((Component)val.gameplayCamera).gameObject); ((Behaviour)val.activeAudioListener).enabled = true; } if ((Object)(object)StartOfRound.Instance != (Object)null) { StartOfRound.Instance.UpdatePlayerVoiceEffects(); } } private static void EnsureFocusSfx() { if (_switchSfx == null) { _switchSfx = CreateSwitchClickClip(); } if (_scanSfx == null) { _scanSfx = CreateScanSweepClip(); } if (_pingSfx == null) { _pingSfx = CreateToneClip("LethalCCTV_PingBlip", 0.1f, 760f, 520f, 0.24f); } if (_rotateSfx == null) { _rotateSfx = CreateRotateServoClip(); } } private static void EnsureProvidedFocusAudioLoading() { if (!_providedFocusAudioLoadStarted && !((Object)(object)SurveillanceBootstrap.Instance == (Object)null)) { _providedFocusAudioLoadStarted = true; ((MonoBehaviour)SurveillanceBootstrap.Instance).StartCoroutine(LoadProvidedFocusAudio()); } } private static IEnumerator LoadProvidedFocusAudio() { List switchClips = new List(2); yield return LoadProvidedFocusAudioClip("ui_click_mx_2.ogg", "LethalCCTV_UI_Click_2", delegate(AudioClip clip) { if ((Object)(object)clip != (Object)null) { switchClips.Add(clip); } }); yield return LoadProvidedFocusAudioClip("ui_click_mx_3.ogg", "LethalCCTV_UI_Click_3", delegate(AudioClip clip) { if ((Object)(object)clip != (Object)null) { switchClips.Add(clip); } }); if (switchClips.Count > 0) { _switchSfxPool = switchClips.ToArray(); } yield return LoadProvidedFocusAudioClip("ui_submit_mx_7.ogg", "LethalCCTV_UI_PageSubmit", delegate(AudioClip clip) { if ((Object)(object)clip != (Object)null) { _pageSfx = clip; } }); yield return LoadProvidedFocusAudioClip("retro_computer_beep_mx_1.ogg", "LethalCCTV_UI_Ping", delegate(AudioClip clip) { if ((Object)(object)clip != (Object)null) { _pingSfx = clip; } }); yield return LoadProvidedFocusAudioClip("retro_computer_beep_mx_2.ogg", "LethalCCTV_UI_Interact", delegate(AudioClip clip) { if ((Object)(object)clip != (Object)null) { _interactSfx = clip; } }); yield return LoadProvidedFocusAudioClip("analog_computer_boot.ogg", "LethalCCTV_UI_Boot", delegate(AudioClip clip) { if ((Object)(object)clip != (Object)null) { _bootSfx = clip; } }); yield return LoadProvidedFocusAudioClip("old_machine_mx_2_loop.ogg", "LethalCCTV_OldMachineLoop", delegate(AudioClip clip) { if (!((Object)(object)clip == (Object)null)) { _machineLoopSfx = clip; if (IsFocused) { StartFocusMachineLoop(); } } }); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV] Focus audio load complete: switchPool={((_switchSfxPool != null) ? _switchSfxPool.Length : 0)} " + $"page={(Object)(object)_pageSfx != (Object)null} ping={(Object)(object)_pingSfx != (Object)null} interact={(Object)(object)_interactSfx != (Object)null} boot={(Object)(object)_bootSfx != (Object)null} loop={(Object)(object)_machineLoopSfx != (Object)null}.")); } } private static IEnumerator LoadProvidedFocusAudioClip(string fileName, string clipName, Action onLoaded) { string path = ResolveFocusAudioPath(fileName); if (string.IsNullOrEmpty(path)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Focus audio missing: " + fileName)); } onLoaded?.Invoke(null); yield break; } UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(new Uri(path).AbsoluteUri, (AudioType)14); try { yield return request.SendWebRequest(); if ((int)request.result != 1) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Failed loading focus audio '" + path + "': " + request.error)); } onLoaded?.Invoke(null); yield break; } AudioClip content = DownloadHandlerAudioClip.GetContent(request); if ((Object)(object)content == (Object)null) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV] Focus audio decoded null: " + path)); } onLoaded?.Invoke(null); yield break; } ((Object)content).name = clipName; onLoaded?.Invoke(content); } finally { ((IDisposable)request)?.Dispose(); } } private static string ResolveFocusAudioPath(string fileName) { if (string.IsNullOrEmpty(fileName)) { return null; } string text = null; try { text = Path.GetDirectoryName(typeof(SurveillanceBootstrap).Assembly.Location); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Focus audio plugin-dir resolve failed: " + ex.Message)); } } if (string.IsNullOrEmpty(text)) { return null; } string text2 = Path.Combine(text, "Audio", fileName); if (File.Exists(text2)) { return text2; } string text3 = Path.Combine(text, fileName); if (!File.Exists(text3)) { return null; } return text3; } private static void PlaySwitchCameraSfx() { AudioClip val = null; if (_switchSfxPool != null && _switchSfxPool.Length != 0) { val = _switchSfxPool[Random.Range(0, _switchSfxPool.Length)]; } PlayFocusSfx(((Object)(object)val != (Object)null) ? val : _switchSfx, 0.78f); } private static void PlayPageSfx() { PlayFocusSfx(((Object)(object)_pageSfx != (Object)null) ? _pageSfx : _scanSfx, 0.82f); } private static void PlayPingSfx() { PlayFocusSfx(_pingSfx, 0.78f); } private static void PlayInteractSfx() { PlayFocusSfx(((Object)(object)_interactSfx != (Object)null) ? _interactSfx : _pingSfx, 0.72f); } private static void PlayBootSfx() { PlayFocusSfx(((Object)(object)_bootSfx != (Object)null) ? _bootSfx : _scanSfx, 0.78f); } private static void EnsureFocusMachineLoopSource() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_005a: 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_0082: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_focusMachineLoopSource != (Object)null)) { _focusMachineLoopRoot = new GameObject("LethalCCTV_FocusMachineLoopAudio"); if ((Object)(object)SurveillanceBootstrap.Instance != (Object)null) { _focusMachineLoopRoot.transform.SetParent(((Component)SurveillanceBootstrap.Instance).transform, false); } else { Object.DontDestroyOnLoad((Object)(object)_focusMachineLoopRoot); } _focusMachineLoopRoot.transform.localPosition = Vector3.zero; _focusMachineLoopRoot.transform.localRotation = Quaternion.identity; _focusMachineLoopRoot.transform.localScale = Vector3.one; _focusMachineLoopSource = _focusMachineLoopRoot.AddComponent(); _focusMachineLoopSource.playOnAwake = false; _focusMachineLoopSource.loop = true; _focusMachineLoopSource.spatialBlend = 0f; _focusMachineLoopSource.volume = 0.22f; _focusMachineLoopSource.priority = 96; _focusMachineLoopSource.dopplerLevel = 0f; _focusMachineLoopSource.ignoreListenerPause = true; } } private static void StartFocusMachineLoop() { if ((Object)(object)_machineLoopSfx == (Object)null) { return; } EnsureFocusMachineLoopSource(); if (!((Object)(object)_focusMachineLoopSource == (Object)null)) { _focusMachineLoopSource.clip = _machineLoopSfx; _focusMachineLoopSource.volume = 0.22f; _focusMachineLoopSource.loop = true; if (!_focusMachineLoopSource.isPlaying) { _focusMachineLoopSource.Play(); } } } private static void StopFocusMachineLoop() { if ((Object)(object)_focusMachineLoopSource != (Object)null && _focusMachineLoopSource.isPlaying) { _focusMachineLoopSource.Stop(); } } private static AudioClip CreateSwitchClickClip() { int num = Mathf.RoundToInt(2520f); float[] array = new float[num]; uint num2 = 12648430u; for (int i = 0; i < num; i++) { float num3 = (float)i / (float)(num - 1); num2 = num2 * 1664525 + 1013904223; float num4 = (float)(num2 >> 9) / 8388607f * 2f - 1f; float num5 = Mathf.Clamp01(1f - num3 / 0.045f); float num6 = Mathf.Exp((0f - num3) * 34f); float num7 = Mathf.Sin(MathF.PI * 310f * num3) * num6 * 0.54f; float num8 = num4 * num5 * 0.16f; array[i] = (num7 + num8) * 0.58f; } AudioClip obj = AudioClip.Create("LethalCCTV_SwitchClick", num, 1, 24000, false); obj.SetData(array, 0); return obj; } private static AudioClip CreateScanSweepClip() { int num = Mathf.RoundToInt(8160f); float[] array = new float[num]; float num2 = 0f; float num3 = 0f; uint num4 = 85314065u; for (int i = 0; i < num; i++) { float num5 = (float)i / (float)(num - 1); float num6 = Mathf.Sin(Mathf.Clamp01(num5) * MathF.PI); float num7 = Mathf.Lerp(190f, 430f, num5); float num8 = Mathf.Lerp(320f, 680f, num5); num2 += num7 / 24000f; num3 += num8 / 24000f; num4 = num4 * 1664525 + 1013904223; float num9 = (float)(num4 >> 9) / 8388607f * 2f - 1f; float num10 = Mathf.Sin(num2 * MathF.PI * 2f) * 0.34f + Mathf.Sin(num3 * MathF.PI * 2f) * 0.18f; array[i] = (num10 + num9 * 0.035f) * num6 * 0.42f; } AudioClip obj = AudioClip.Create("LethalCCTV_ScanSweepSoft", num, 1, 24000, false); obj.SetData(array, 0); return obj; } private static AudioClip CreateRotateServoClip() { int num = Mathf.RoundToInt(2880f); float[] array = new float[num]; float num2 = 0f; uint num3 = 659918u; for (int i = 0; i < num; i++) { float num4 = (float)i / (float)(num - 1); float num5 = Mathf.Sin(Mathf.Clamp01(num4) * MathF.PI); num2 += Mathf.Lerp(92f, 118f, num4) / 24000f; num3 = num3 * 1664525 + 1013904223; float num6 = (float)(num3 >> 9) / 8388607f * 2f - 1f; array[i] = (Mathf.Sin(num2 * MathF.PI * 2f) * 0.2f + num6 * 0.035f) * num5 * 0.28f; } AudioClip obj = AudioClip.Create("LethalCCTV_RotateServo", num, 1, 24000, false); obj.SetData(array, 0); return obj; } private static AudioClip CreateToneClip(string name, float duration, float startHz, float endHz, float gain) { int num = Mathf.Max(1, Mathf.RoundToInt(duration * 24000f)); float[] array = new float[num]; float num2 = 0f; for (int i = 0; i < num; i++) { float num3 = (float)i / (float)(num - 1); float num4 = Mathf.Lerp(startHz, endHz, num3); num2 += num4 / 24000f; float num5 = Mathf.Sin(Mathf.Clamp01(num3) * MathF.PI); array[i] = Mathf.Sin(num2 * MathF.PI * 2f) * num5 * gain; } AudioClip obj = AudioClip.Create(name, num, 1, 24000, false); obj.SetData(array, 0); return obj; } private static void PlayFocusSfx(AudioClip clip, float volume) { if (!((Object)(object)clip == (Object)null)) { HUDManager instance = HUDManager.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.UIAudio != (Object)null) { instance.UIAudio.PlayOneShot(clip, volume); } } } internal static void NotifySlotDisplayTextureChanged(int slot, Texture tex) { if (_overlayRawImages == null || slot < 0 || slot >= _overlayRawImages.Length || (Object)(object)_overlayRawImages[slot] == (Object)null) { return; } if (IsTurretPageActive && slot == 0) { _overlayRawImages[slot].texture = (Texture)(((object)ShipTurretController.ViewTexture) ?? ((object)Texture2D.blackTexture)); return; } _overlayRawImages[slot].texture = tex; if (OpenBodyCamsCompat.IsFocusSlot(slot)) { RefreshBodycamFocusSlot(); } } internal static void TriggerCameraContextOrScan() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) if (!Y4NGZPlayerAnimationBridge.IsFirstPersonHandEditModeActive && IsFocused && !IsHackingOverlayOpen) { CCTVCamera activeCamera = GetActiveCamera(); if (!((Object)(object)activeCamera == (Object)null) && !((Object)(object)activeCamera.Cam == (Object)null) && TryResolveContextTarget(activeCamera.Cam, out var target) && target.Commandable) { _contextTarget = target; _scanVisibleUntil = Time.unscaledTime + 8f; CCTVMarkerManager.PublishContextMarker(target.Position, target.Radius, target.DisplayName, 0, activeCamera.CameraIndex); HandleContextTargetAction(target); } } } internal static void TriggerCameraPing() { //IL_0042: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00f0: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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) if (!IsFocused || IsHackingOverlayOpen) { return; } CCTVCamera activeCamera = GetActiveCamera(); if ((Object)(object)activeCamera == (Object)null || (Object)(object)activeCamera.Cam == (Object)null) { _scanVisibleUntil = Time.unscaledTime + 0.9f; ShowScanStatus("NO ACTIVE CAMERA", OVERLAY_SCAN_RED); HideScanLabels(); return; } Camera cam = activeCamera.Cam; Ray val = default(Ray); ((Ray)(ref val))..ctor(((Component)cam).transform.position, ((Component)cam).transform.forward); Vector3 val2 = ((Ray)(ref val)).GetPoint(25f); int num = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-1)); RaycastHit val3 = default(RaycastHit); if (Physics.Raycast(val, ref val3, 80f, num, (QueryTriggerInteraction)1)) { val2 = ((RaycastHit)(ref val3)).point + ((RaycastHit)(ref val3)).normal * 0.05f; } CCTVMarkerManager.PublishPing(val2, activeCamera.CameraIndex); _scanVisibleUntil = Time.unscaledTime + 0.9f; ShowScanStatus("PING SENT", OVERLAY_ACTIVE_GREEN); HideScanLabels(); PlayPingSfx(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] CCTV ping from CAM_{activeCamera.CameraIndex:D2}: pos={val2}"); } } private static bool TryResolveContextTarget(Camera cam, out ContextTarget target) { //IL_0014: 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) //IL_0024: 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) target = null; if ((Object)(object)cam == (Object)null) { return false; } RaycastHit val = default(RaycastHit); if (Physics.Raycast(new Ray(((Component)cam).transform.position, ((Component)cam).transform.forward), ref val, 85f, -1, (QueryTriggerInteraction)2) && TryResolveAllowedContextTarget(((RaycastHit)(ref val)).transform, ((RaycastHit)(ref val)).point, out target)) { return true; } return TryFindSnapContextTarget(cam, out target); } private static bool TryResolveAllowedContextTarget(Transform hitTransform, Vector3 hitPoint, out ContextTarget target) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) target = null; if ((Object)(object)hitTransform == (Object)null) { return false; } if (TryResolveCommandTarget(hitTransform, hitPoint, out target)) { return true; } GrabbableObject componentInParent = ((Component)hitTransform).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && !componentInParent.isHeld && !componentInParent.isHeldByEnemy) { target = CreateItemTarget(componentInParent); return true; } EnemyAI componentInParent2 = ((Component)hitTransform).GetComponentInParent(); if ((Object)(object)componentInParent2 != (Object)null && !componentInParent2.isEnemyDead) { target = CreateEnemyTarget(componentInParent2); return true; } ScanNodeProperties node = ((Component)hitTransform).GetComponent() ?? ((Component)hitTransform).GetComponentInParent(); if (IsAllowedInfoNode(node)) { target = CreateInfoNodeTarget(node); return true; } return false; } private static bool TryResolveCommandTarget(Transform hitTransform, Vector3 hitPoint, out ContextTarget target) { //IL_0030: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) target = null; if ((Object)(object)hitTransform == (Object)null) { return false; } Turret componentInParent = ((Component)hitTransform).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null) { target = CreateContextTarget((Component)(object)componentInParent, "TURRET", "enable / disable", ((Component)componentInParent).transform.position, OVERLAY_ACTIVE_GREEN); return true; } Landmine componentInParent2 = ((Component)hitTransform).GetComponentInParent(); if ((Object)(object)componentInParent2 != (Object)null) { target = CreateContextTarget((Component)(object)componentInParent2, "MINE", "enable / disable", ((Component)componentInParent2).transform.position, OVERLAY_ACTIVE_GREEN); return true; } TerminalAccessibleObject componentInParent3 = ((Component)hitTransform).GetComponentInParent(); if ((Object)(object)componentInParent3 != (Object)null) { target = CreateContextTarget((Component)(object)componentInParent3, "SECURITY DOOR", "open / close", ((Component)componentInParent3).transform.position, OVERLAY_ACTIVE_GREEN); return true; } DoorLock componentInParent4 = ((Component)hitTransform).GetComponentInParent(); if ((Object)(object)componentInParent4 != (Object)null) { target = CreateContextTarget((Component)(object)componentInParent4, "DOOR", "open / close", hitPoint, OVERLAY_ACTIVE_GREEN); return true; } if (CctvCommandTargetBridge.TryDescribeTarget((Component)(object)hitTransform, out var info)) { target = CreateContextTarget(info.Component, info.DisplayName, info.CommandHint, info.Position, OVERLAY_ACTIVE_GREEN, info.Radius); return true; } return false; } private static bool TryFindSnapContextTarget(Camera cam, out ContextTarget target) { //IL_0043: 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_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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) target = null; if ((Object)(object)cam == (Object)null) { return false; } float bestScore = float.PositiveInfinity; Turret[] array = Object.FindObjectsOfType(); foreach (Turret val in array) { if (!((Object)(object)val == (Object)null)) { TryChooseSnapTarget(cam, CreateContextTarget((Component)(object)val, "TURRET", "enable / disable", ((Component)val).transform.position, OVERLAY_ACTIVE_GREEN), ref target, ref bestScore); } } Landmine[] array2 = Object.FindObjectsOfType(); foreach (Landmine val2 in array2) { if (!((Object)(object)val2 == (Object)null)) { TryChooseSnapTarget(cam, CreateContextTarget((Component)(object)val2, "MINE", "enable / disable", ((Component)val2).transform.position, OVERLAY_ACTIVE_GREEN), ref target, ref bestScore); } } DoorLock[] array3 = Object.FindObjectsOfType(); foreach (DoorLock val3 in array3) { if (!((Object)(object)val3 == (Object)null)) { TryChooseSnapTarget(cam, CreateContextTarget((Component)(object)val3, "DOOR", "open / close", ((Component)val3).transform.position, OVERLAY_ACTIVE_GREEN), ref target, ref bestScore); } } TerminalAccessibleObject[] array4 = Object.FindObjectsOfType(); foreach (TerminalAccessibleObject val4 in array4) { if (!((Object)(object)val4 == (Object)null) && val4.isBigDoor) { TryChooseSnapTarget(cam, CreateContextTarget((Component)(object)val4, "SECURITY DOOR", "open / close", ((Component)val4).transform.position, OVERLAY_ACTIVE_GREEN), ref target, ref bestScore); } } List activeTargets = CctvCommandTargetBridge.GetActiveTargets(); for (int m = 0; m < activeTargets.Count; m++) { CctvCommandTargetBridge.TargetInfo targetInfo = activeTargets[m]; if (targetInfo != null && !((Object)(object)targetInfo.Component == (Object)null)) { TryChooseSnapTarget(cam, CreateContextTarget(targetInfo.Component, targetInfo.DisplayName, targetInfo.CommandHint, targetInfo.Position, OVERLAY_ACTIVE_GREEN, targetInfo.Radius), ref target, ref bestScore); } } GrabbableObject[] array5 = Object.FindObjectsOfType(); foreach (GrabbableObject val5 in array5) { if (!((Object)(object)val5 == (Object)null) && !val5.isHeld && !val5.isHeldByEnemy) { TryChooseSnapTarget(cam, CreateItemTarget(val5), ref target, ref bestScore); } } RoundManager instance = RoundManager.Instance; if ((Object)(object)instance != (Object)null && instance.SpawnedEnemies != null) { for (int num = 0; num < instance.SpawnedEnemies.Count; num++) { EnemyAI val6 = instance.SpawnedEnemies[num]; if (!((Object)(object)val6 == (Object)null) && !val6.isEnemyDead && !val6.isOutside && !val6.isInsidePlayerShip) { TryChooseSnapTarget(cam, CreateEnemyTarget(val6), ref target, ref bestScore); } } } ScanNodeProperties[] array6 = Object.FindObjectsOfType(); foreach (ScanNodeProperties node in array6) { if (IsAllowedInfoNode(node)) { TryChooseSnapTarget(cam, CreateInfoNodeTarget(node), ref target, ref bestScore); } } return target != null; } private static void TryChooseSnapTarget(Camera cam, ContextTarget candidate, ref ContextTarget best, ref float bestScore) { //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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cam == (Object)null || candidate == null) { return; } Vector3 val = cam.WorldToViewportPoint(candidate.Position); if (val.z <= 0f || val.z > 85f) { return; } float num = val.x - 0.5f; float num2 = val.y - 0.5f; float num3 = Mathf.Sqrt(num * num + num2 * num2); if (!(num3 > 0.095f)) { float num4 = num3 * 10f + val.z * 0.0025f + (candidate.Commandable ? (-0.08f) : 0f); if (!(num4 >= bestScore)) { bestScore = num4; best = candidate; } } } private static ContextTarget CreateItemTarget(GrabbableObject item) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_00bf: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) string displayName = (((Object)(object)item != (Object)null && (Object)(object)item.itemProperties != (Object)null && !string.IsNullOrEmpty(item.itemProperties.itemName)) ? item.itemProperties.itemName.ToUpperInvariant() : CleanTargetName(((Object)(object)item != (Object)null) ? ((Object)item).name : "ITEM")); return new ContextTarget { Component = (Component)(object)item, DisplayName = displayName, CommandHint = "", Position = (((Object)(object)item != (Object)null) ? ((Component)item).transform.position : Vector3.zero), Radius = EstimateContextRadius(((Object)(object)item != (Object)null) ? ((Component)item).gameObject : null, ((Object)(object)item != (Object)null) ? ((Component)item).transform.position : Vector3.zero), Commandable = false, Color = OVERLAY_SCAN_BLUE, ExpiresAt = Time.unscaledTime + 8f }; } private static ContextTarget CreateEnemyTarget(EnemyAI enemy) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_00bf: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) string displayName = (((Object)(object)enemy != (Object)null && (Object)(object)enemy.enemyType != (Object)null && !string.IsNullOrEmpty(enemy.enemyType.enemyName)) ? enemy.enemyType.enemyName.ToUpperInvariant() : CleanTargetName(((Object)(object)enemy != (Object)null) ? ((Object)enemy).name : "HOSTILE")); return new ContextTarget { Component = (Component)(object)enemy, DisplayName = displayName, CommandHint = "", Position = (((Object)(object)enemy != (Object)null) ? ((Component)enemy).transform.position : Vector3.zero), Radius = EstimateContextRadius(((Object)(object)enemy != (Object)null) ? ((Component)enemy).gameObject : null, ((Object)(object)enemy != (Object)null) ? ((Component)enemy).transform.position : Vector3.zero), Commandable = false, Color = OVERLAY_SCAN_RED, ExpiresAt = Time.unscaledTime + 8f }; } private static ContextTarget CreateInfoNodeTarget(ScanNodeProperties node) { //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_004a: 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_0078: 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) Color color = ColorForScanNode(node); return new ContextTarget { Component = (Component)(object)node, DisplayName = (string.IsNullOrEmpty(node.headerText) ? "CCTV TARGET" : node.headerText.ToUpperInvariant()), CommandHint = "", Position = ((Component)node).transform.position, Radius = EstimateContextRadius(((Component)node).gameObject, ((Component)node).transform.position), Commandable = false, Color = color, ExpiresAt = Time.unscaledTime + 8f }; } private static bool IsAllowedInfoNode(ScanNodeProperties node) { if ((Object)(object)node == (Object)null || !((Component)node).gameObject.activeInHierarchy) { return false; } if ((Object)(object)((Component)node).GetComponentInParent() != (Object)null) { return true; } if ((Object)(object)((Component)node).GetComponentInParent() != (Object)null) { return true; } if ((Object)(object)((Component)node).GetComponentInParent() != (Object)null) { return true; } if ((Object)(object)((Component)node).GetComponentInParent() != (Object)null) { return true; } if ((Object)(object)((Component)node).GetComponentInParent() != (Object)null) { return true; } if ((Object)(object)((Component)node).GetComponentInParent() != (Object)null) { return true; } string headerText = node.headerText; if (string.IsNullOrWhiteSpace(headerText)) { return false; } if (headerText.IndexOf("mesh", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } if (headerText.IndexOf("wall connector", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } if (headerText.IndexOf("contract", StringComparison.OrdinalIgnoreCase) < 0 && headerText.IndexOf("objective", StringComparison.OrdinalIgnoreCase) < 0 && headerText.IndexOf("quota", StringComparison.OrdinalIgnoreCase) < 0) { return node.nodeType == 2; } return true; } private static ContextTarget CreateContextTarget(Component component, string displayName, string commandHint, Vector3 position, Color color, float radius = -1f) { //IL_001b: 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_0054: 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_003d: Unknown result type (might be due to invalid IL or missing references) return new ContextTarget { Component = component, DisplayName = displayName, CommandHint = commandHint, Position = position, Radius = ((radius > 0f) ? radius : EstimateContextRadius(((Object)(object)component != (Object)null) ? component.gameObject : null, position)), Commandable = true, Color = color, ExpiresAt = Time.unscaledTime + 8f }; } private static float EstimateContextRadius(GameObject root, Vector3 fallbackPosition) { //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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_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_00bb: 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) float num = 0.65f; if ((Object)(object)root == (Object)null) { return num; } Collider[] componentsInChildren = root.GetComponentsInChildren(true); Bounds bounds; Vector3 extents; foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { float num2 = num; bounds = val.bounds; extents = ((Bounds)(ref bounds)).extents; num = Mathf.Max(num2, ((Vector3)(ref extents)).magnitude * 0.55f); } } Renderer[] componentsInChildren2 = root.GetComponentsInChildren(true); foreach (Renderer val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null)) { float num3 = num; bounds = val2.bounds; extents = ((Bounds)(ref bounds)).extents; num = Mathf.Max(num3, ((Vector3)(ref extents)).magnitude * 0.55f); } } if (num <= 0.65f) { num = Mathf.Max(num, Vector3.Distance(root.transform.position, fallbackPosition) + 0.45f); } return Mathf.Clamp(num, 0.45f, 3f); } private static void PrepareInteractiveOverlayDock() { //IL_004a: 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_0050: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) bool num = _hackingOverlay == null || CCTVVanillaMonitorDisplay.TryAttachToLowerLeftOverlay(_hackingOverlay.RootObject); bool flag = _mainframeOverlay == null || CCTVVanillaMonitorDisplay.TryAttachToLowerLeftOverlay(_mainframeOverlay.RootObject); Vector2 anchoredPosition; Vector2 sizeDelta; if (num && flag) { anchoredPosition = CCTVVanillaMonitorDisplay.GetLowerLeftOverlayDockPosition(); sizeDelta = CCTVVanillaMonitorDisplay.GetLowerLeftOverlayDockSize(); } else { RestoreInteractiveOverlaysToFocusOverlay(); anchoredPosition = GetBottomLeftDockPosition(); sizeDelta = GetBottomLeftDockSize(); } _hackingOverlay?.SetDock(anchoredPosition, sizeDelta); _mainframeOverlay?.SetDock(anchoredPosition, sizeDelta); } private static void RestoreInteractiveOverlaysToFocusOverlay() { if (!((Object)(object)_overlayRoot == (Object)null)) { if (_hackingOverlay != null) { _hackingOverlay.SetParent(_overlayRoot.transform); SetLayerRecursive(_hackingOverlay.RootObject, 29); } if (_mainframeOverlay != null) { _mainframeOverlay.SetParent(_overlayRoot.transform); SetLayerRecursive(_mainframeOverlay.RootObject, 29); } } } private static void TickInteractiveOverlays() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (IsHackingOverlayOpen) { _hackingOverlay.Tick(); if (_hackingOverlay.ConsumeSolved()) { OpenMainframeOverlayForCurrent(); } else if (_hackingOverlay.ConsumeEscapeIfOpen()) { RefreshFocusDockLayout(); ShowScanStatus("HACK CANCELED", OVERLAY_SCAN_RED); } } else if (IsMainframeOverlayOpen) { _mainframeOverlay.Tick(); } } private static void HandleContextTargetAction(ContextTarget target) { //IL_002a: 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_004c: Unknown result type (might be due to invalid IL or missing references) if (target == null || (Object)(object)target.Component == (Object)null || TryOpenMainframeFromContextTarget(target)) { return; } string status; Color color; if (!TryGetDefaultContextCommand(target, out var command)) { ShowTimedScanStatus("NO DIRECT ACTION", OVERLAY_SCAN_RED, 1.4f); } else if (TryExecuteCommand(command, out status, out color)) { PlayInteractSfx(); ShowTimedScanStatus(status, color, 1.4f); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] CCTV direct action target='" + target.DisplayName + "' command='" + command + "' status='" + status + "'.")); } } else { ShowTimedScanStatus(status, color, 1.4f); } } private static bool TryGetDefaultContextCommand(ContextTarget target, out string command) { command = null; if (target == null || (Object)(object)target.Component == (Object)null) { return false; } if (target.Component is Turret || target.Component is Landmine) { command = "disable"; return true; } if (target.Component is TerminalAccessibleObject || target.Component is DoorLock) { command = "open"; return true; } string commandHint = target.CommandHint; if (CctvCommandTargetBridge.TryDescribeTarget(target.Component, out var info)) { commandHint = info.CommandHint; } return TryResolveCommandHint(commandHint, out command); } private static bool TryResolveCommandHint(string hint, out string command) { command = null; string text = (hint ?? string.Empty).Trim().ToLowerInvariant(); if (string.IsNullOrEmpty(text)) { return false; } switch (text) { case "hack": case "lure": case "activate": command = text; return true; default: if (text.IndexOf("disable", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("enable", StringComparison.OrdinalIgnoreCase) >= 0) { command = "disable"; return true; } if (text.IndexOf("open", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("close", StringComparison.OrdinalIgnoreCase) >= 0) { command = "open"; return true; } if (text.IndexOf("on", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("off", StringComparison.OrdinalIgnoreCase) >= 0) { command = "on"; return true; } return false; } } private static bool TryOpenMainframeFromContextTarget(ContextTarget target) { //IL_0058: 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_003b: 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_00bd: Unknown result type (might be due to invalid IL or missing references) if (!IsMainframeContextTarget(target)) { return false; } if (CctvSupportApi.IsMainframeHacked) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][MainframeControl] Mainframe already hacked; opening control menu from CCTV target click for target='" + target.DisplayName + "'.")); } ShowScanStatus("MAINFRAME ONLINE", OVERLAY_ACTIVE_GREEN); OpenMainframeOverlayForCurrent(); return true; } if (_hackingOverlay == null) { ShowTimedScanStatus("HACK UNAVAILABLE", OVERLAY_SCAN_RED, 1.4f); return true; } if (TryExecuteCommand("hack", out var status, out var color)) { if (!string.IsNullOrEmpty(status) && status.IndexOf("ALREADY HACKED", StringComparison.OrdinalIgnoreCase) >= 0) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV][MainframeControl] Mainframe returned already hacked; opening control menu from CCTV target click for target='" + target.DisplayName + "'.")); } ShowScanStatus("MAINFRAME ONLINE", OVERLAY_ACTIVE_GREEN); OpenMainframeOverlayForCurrent(); return true; } ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)("[LethalCCTV] Opening CCTV hack terminal from target click target='" + target.DisplayName + "' status='" + status + "'.")); } PlayInteractSfx(); ShowScanStatus("HACK STARTED", OVERLAY_ACTIVE_GREEN); OpenHackingOverlayForCurrent(); return true; } ShowTimedScanStatus(status, color, 1.4f); return true; } private static bool IsMainframeContextTarget(ContextTarget target) { if (target == null || (Object)(object)target.Component == (Object)null) { return false; } if (string.Equals(target.CommandHint, "hack", StringComparison.OrdinalIgnoreCase)) { return true; } if (string.Equals(target.DisplayName, "MAINFRAME", StringComparison.OrdinalIgnoreCase)) { return true; } if (CctvCommandTargetBridge.TryDescribeTarget(target.Component, out var info)) { if (string.Equals(info.CommandHint, "hack", StringComparison.OrdinalIgnoreCase)) { return true; } if (string.Equals(info.DisplayName, "MAINFRAME", StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } private static void OpenHackingOverlayForCurrent() { if (_contextTarget != null && !((Object)(object)_contextTarget.Component == (Object)null)) { PrepareInteractiveOverlayDock(); _hackingOverlay?.Open(_contextTarget.Component); RefreshFocusDockLayout(); } } private static void OpenMainframeOverlayForCurrent() { if (_mainframeOverlay == null) { return; } Component val = ((_hackingOverlay != null) ? _hackingOverlay.ActiveMainframe : null); if ((Object)(object)val == (Object)null && _contextTarget != null) { val = _contextTarget.Component; } if (!((Object)(object)val == (Object)null)) { _hackingOverlay?.Close("hack-solved-to-mainframe"); PrepareInteractiveOverlayDock(); _mainframeOverlay.Open(val); RefreshFocusDockLayout(); PlayInteractSfx(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV][MainframeControl] Opened mainframe control menu after hack success."); } } } private static bool TryExecuteCommand(string raw, out string status, out Color color) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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_00bb: 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_017d: 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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) status = "INVALID COMMAND"; color = OVERLAY_SCAN_RED; if (_contextTarget == null || (Object)(object)_contextTarget.Component == (Object)null) { status = "TARGET LOST"; return false; } string text = (raw ?? string.Empty).Trim().ToLowerInvariant(); if (string.IsNullOrEmpty(text)) { return false; } Component component = _contextTarget.Component; Turret val = (Turret)(object)((component is Turret) ? component : null); if (val != null) { if (IsDisableCommand(text)) { if (!TrySpendCommandPower(out status, out color)) { return false; } val.ToggleTurretEnabled(false); status = "TURRET DISABLE"; color = OVERLAY_ACTIVE_GREEN; return true; } if (IsEnableCommand(text)) { if (!TrySpendCommandPower(out status, out color)) { return false; } val.ToggleTurretEnabled(true); status = "TURRET ENABLE"; color = OVERLAY_ACTIVE_GREEN; return true; } status = "USE ENABLE / DISABLE"; return false; } Component component2 = _contextTarget.Component; Landmine val2 = (Landmine)(object)((component2 is Landmine) ? component2 : null); if (val2 != null) { if (IsDisableCommand(text)) { if (!TrySpendCommandPower(out status, out color)) { return false; } val2.ToggleMine(false); status = "MINE DISABLE"; color = OVERLAY_ACTIVE_GREEN; return true; } if (IsEnableCommand(text)) { if (!TrySpendCommandPower(out status, out color)) { return false; } val2.ToggleMine(true); status = "MINE ENABLE"; color = OVERLAY_ACTIVE_GREEN; return true; } status = "USE ENABLE / DISABLE"; return false; } Component component3 = _contextTarget.Component; TerminalAccessibleObject val3 = (TerminalAccessibleObject)(object)((component3 is TerminalAccessibleObject) ? component3 : null); if (val3 != null) { if (IsOpenCommand(text)) { if (!TrySpendCommandPower(out status, out color)) { return false; } val3.SetDoorLocalClient(true); status = "DOOR OPEN"; color = OVERLAY_ACTIVE_GREEN; return true; } if (IsCloseCommand(text)) { if (!TrySpendCommandPower(out status, out color)) { return false; } val3.SetDoorLocalClient(false); status = "DOOR CLOSE"; color = OVERLAY_ACTIVE_GREEN; return true; } status = "USE OPEN / CLOSE"; return false; } Component component4 = _contextTarget.Component; DoorLock val4 = (DoorLock)(object)((component4 is DoorLock) ? component4 : null); if (val4 != null) { if (IsOpenCommand(text)) { if (!TrySpendCommandPower(out status, out color)) { return false; } val4.OpenDoorAsEnemyServerRpc(); status = "DOOR OPEN"; color = OVERLAY_ACTIVE_GREEN; return true; } if (IsCloseCommand(text)) { if (!TrySpendCommandPower(out status, out color)) { return false; } val4.CloseDoorNonPlayerServerRpc(); status = "DOOR CLOSE"; color = OVERLAY_ACTIVE_GREEN; return true; } status = "USE OPEN / CLOSE"; return false; } if (CctvCommandTargetBridge.TryDescribeTarget(_contextTarget.Component, out var _)) { bool flag = CctvCommandTargetBridge.TryExecuteCommand(_contextTarget.Component, text, out status); color = (flag ? OVERLAY_ACTIVE_GREEN : OVERLAY_SCAN_RED); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] CCTV support command target='{_contextTarget.DisplayName}' command='{text}' success={flag} status='{status}'."); } return flag; } status = "UNSUPPORTED TARGET"; return false; } private static bool TrySpendCommandPower(out string status, out Color color) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) status = "INSUFFICIENT POWER"; color = OVERLAY_SCAN_RED; return CCTVShipSystemsBridge.TrySpendRemoteOperationPower(); } private static bool IsDisableCommand(string command) { if (!(command == "disable") && !(command == "off")) { return command == "deactivate"; } return true; } private static bool IsEnableCommand(string command) { if (!(command == "enable") && !(command == "on")) { return command == "activate"; } return true; } private static bool IsOpenCommand(string command) { return command == "open"; } private static bool IsCloseCommand(string command) { if (!(command == "close")) { return command == "shut"; } return true; } private static string CleanTargetName(string name) { if (string.IsNullOrEmpty(name)) { return "CCTV TARGET"; } return name.Replace("(Clone)", string.Empty).Trim().ToUpperInvariant(); } internal static void ClearZoomState() { _zoomByCamera.Clear(); } internal static void NotifyCameraRotated(float deltaMagnitude) { if (IsFocused && !(deltaMagnitude <= 0.0001f)) { BoostStationCameraRenderCadence(); if (!(Time.unscaledTime < _nextRotateSfxTime)) { _nextRotateSfxTime = Time.unscaledTime + 0.16f; PlayFocusSfx(_rotateSfx, Mathf.Clamp(0.2f + deltaMagnitude * 0.025f, 0.2f, 0.38f)); } } } private static void ApplyZoomToActiveCamera() { CCTVCamera activeCamera = GetActiveCamera(); if (!((Object)(object)activeCamera == (Object)null) && !((Object)(object)activeCamera.Cam == (Object)null)) { ApplyZoom(activeCamera); } } private static float GetZoom(CCTVCamera camera) { if ((Object)(object)camera == (Object)null) { return 0f; } if (!_zoomByCamera.TryGetValue(camera, out var value)) { return 0f; } return value; } private static void ApplyZoom(CCTVCamera camera) { if (!((Object)(object)camera?.Cam == (Object)null)) { float num = ((SurveillanceBootstrap.Config != null) ? SurveillanceBootstrap.Config.FieldOfView.Value : camera.Cam.fieldOfView); float num2 = Mathf.Clamp(22f, 8f, Mathf.Max(8f, num - 1f)); float zoom = GetZoom(camera); camera.Cam.fieldOfView = Mathf.Lerp(num, num2, zoom); } } private static string FormatZoom(CCTVCamera camera) { if ((Object)(object)camera?.Cam == (Object)null) { return "1.0X"; } float num = Mathf.Max(1f, (SurveillanceBootstrap.Config != null) ? SurveillanceBootstrap.Config.FieldOfView.Value : camera.Cam.fieldOfView); float num2 = Mathf.Max(1f, camera.Cam.fieldOfView); return (num / num2).ToString("0.0") + "X"; } private static void TickPlacementEditorInput() { Keyboard current = Keyboard.current; if (current == null) { return; } if (((ButtonControl)current.f2Key).wasPressedThisFrame) { ToggleCameraPlacementEditMode(); } else { if (_stationEditMenuOpen || Y4NGZPlayerAnimationBridge.IsFirstPersonHandEditModeActive || CCTVOperatorStation.IsDebugPlacementActive) { return; } if (_placementEditorOpen) { TickOpenPlacementEditor(current); } else { if (_reviewMenuOpen || (_hackingOverlay != null && _hackingOverlay.IsOpen) || !_cameraPlacementEditModeOpen) { return; } if (((ButtonControl)current.f5Key).wasPressedThisFrame || ((ButtonControl)current.digit1Key).wasPressedThisFrame || ((ButtonControl)current.numpad1Key).wasPressedThisFrame) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] PLACEMENT_EDITOR_F5 activeSlot={ActiveSlot} active='{DescribeCameraForLog(GetActiveCamera())}'"); } OpenPlacementEditor(); } else if (((ButtonControl)current.f6Key).wasPressedThisFrame || ((ButtonControl)current.digit2Key).wasPressedThisFrame || ((ButtonControl)current.numpad2Key).wasPressedThisFrame) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV] PLACEMENT_EDITOR_F6 activeSlot={ActiveSlot} active='{DescribeCameraForLog(GetActiveCamera())}'"); } CreateManualCameraAndEdit(); } else if (((ButtonControl)current.f4Key).wasPressedThisFrame) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)$"[LethalCCTV] CAMERA_REVIEW_OPEN_KEY activeSlot={ActiveSlot} active='{DescribeCameraForLog(GetActiveCamera())}'"); } OpenCameraReviewMenu(); } else if (((ButtonControl)current.deleteKey).wasPressedThisFrame || ((ButtonControl)current.backspaceKey).wasPressedThisFrame) { ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogInfo((object)$"[LethalCCTV] PLACEMENT_EDITOR_DELETE_KEY activeSlot={ActiveSlot} active='{DescribeCameraForLog(GetActiveCamera())}'"); } DeleteActiveCamera(); } } } } private static void ToggleCameraPlacementEditMode() { //IL_007d: 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_002f: Unknown result type (might be due to invalid IL or missing references) if (_stationEditMenuOpen || Y4NGZPlayerAnimationBridge.IsFirstPersonHandEditModeActive || CCTVOperatorStation.IsDebugPlacementActive) { return; } if (_cameraPlacementEditModeOpen) { if (_placementEditorOpen) { CancelPlacementEditor(restore: true); ShowTimedScanStatus("PLACEMENT CANCELED", OVERLAY_SCAN_RED, 1.2f); } CloseCameraReviewMenu(); _cameraPlacementEditModeOpen = false; ShowTimedScanStatus("CAMERA EDIT OFF", OVERLAY_SCAN_BLUE, 1f); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Camera placement edit mode closed."); } } else { _cameraPlacementEditModeOpen = true; ShowTimedScanStatus("CAMERA EDIT", OVERLAY_ACTIVE_GREEN, 1f); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV] Camera placement edit mode opened activeSlot={ActiveSlot} active='{DescribeCameraForLog(GetActiveCamera())}'."); } } } private static void TickOpenPlacementEditor(Keyboard keyboard) { //IL_0024: 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) if ((Object)(object)_placementEditSession?.Transform == (Object)null) { CancelPlacementEditor(restore: false); ShowTimedScanStatus("PLACEMENT TARGET LOST", OVERLAY_SCAN_RED, 1.4f); } else if (((ButtonControl)keyboard.escapeKey).wasPressedThisFrame || ((ButtonControl)keyboard.digit0Key).wasPressedThisFrame || ((ButtonControl)keyboard.numpad0Key).wasPressedThisFrame) { CancelPlacementEditor(restore: true); ShowTimedScanStatus("PLACEMENT CANCELED", OVERLAY_SCAN_RED, 1.4f); } else if (((ButtonControl)keyboard.enterKey).wasPressedThisFrame || ((ButtonControl)keyboard.numpadEnterKey).wasPressedThisFrame) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] PLACEMENT_EDITOR_ENTER label='{_placementEditSession.Label}' kind={_placementEditSession.ObjectKind} activeSlot={ActiveSlot} active='{DescribeCameraForLog(GetActiveCamera())}'"); } SavePlacementEditor(); } else if (ApplyPlacementEditorInput(keyboard)) { RefreshPlacementEditorText(); } } private static void OpenPlacementEditor() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) if (!TryResolvePlacementEditSession(out var session, out var reason)) { ShowTimedScanStatus(reason, OVERLAY_SCAN_RED, 1.4f); return; } CloseCameraReviewMenu(); _hackingOverlay?.Close(); _placementEditSession = session; _placementEditorOpen = true; _cameraPlacementEditModeOpen = true; GameObject placementEditorRoot = _placementEditorRoot; if (placementEditorRoot != null) { placementEditorRoot.SetActive(true); } HideScanLabels(); RefreshPlacementEditorText(); ShowTimedScanStatus("PLACEMENT EDIT", OVERLAY_ACTIVE_GREEN, 1f); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { object[] obj = new object[7] { session.ObjectKind, session.Label, null, null, null, null, null }; Tile tile = session.Tile; obj[2] = ((tile != null) ? ((Object)tile).name : null); obj[3] = session.StartPosition.x; obj[4] = session.StartPosition.y; obj[5] = session.StartPosition.z; obj[6] = ((Quaternion)(ref session.StartRotation)).eulerAngles.y; log.LogInfo((object)string.Format("[LethalCCTV] PLACEMENT_EDITOR_OPEN kind={0} label='{1}' tile='{2}' pos=({3:F2},{4:F2},{5:F2}) yaw={6:F1}", obj)); } } private static void CreateManualCameraAndEdit() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0104: 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_015f: Unknown result type (might be due to invalid IL or missing references) CCTVCamera activeCamera = GetActiveCamera(); if ((Object)(object)activeCamera == (Object)null || (Object)(object)((Component)activeCamera).transform == (Object)null || (Object)(object)activeCamera.OwningTile == (Object)null) { ShowTimedScanStatus("NO CAMERA TO CLONE", OVERLAY_SCAN_RED, 1.4f); return; } int currentPage = QuadCameraAssignment.CurrentPage; int activeSlot = ActiveSlot; activeCamera.ResetOffsets(); activeCamera.ApplyOffsets(); CCTVCamera cCTVCamera = CreateManualCamera(activeCamera); if ((Object)(object)cCTVCamera == (Object)null) { ShowTimedScanStatus("CAMERA ADD FAILED", OVERLAY_SCAN_RED, 1.4f); return; } QuadCameraAssignment.RegisterSupplementaryCamera(cCTVCamera); bool flag = FocusCamera(cCTVCamera, "manual-camera-created"); CloseCameraReviewMenu(); _hackingOverlay?.Close(); _placementEditSession = new PlacementEditSession { Transform = ((Component)cCTVCamera).transform, Camera = cCTVCamera, Tile = cCTVCamera.OwningTile, ObjectKind = "camera", ObjectId = cCTVCamera.AuthoredPlacementId, Label = cCTVCamera.ResolvedLabel, StartPosition = ((Component)cCTVCamera).transform.position, StartRotation = ((Component)cCTVCamera).transform.rotation, CreatedDuringEdit = true, PreviousPage = currentPage, PreviousSlot = activeSlot }; _placementEditorOpen = true; _cameraPlacementEditModeOpen = true; GameObject placementEditorRoot = _placementEditorRoot; if (placementEditorRoot != null) { placementEditorRoot.SetActive(true); } HideScanLabels(); RefreshPlacementEditorText(); ShowTimedScanStatus(flag ? "NEW CAMERA SELECTED" : "NEW CAMERA", OVERLAY_ACTIVE_GREEN, 1f); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { object[] obj = new object[8] { cCTVCamera.ResolvedLabel, cCTVCamera.AuthoredPlacementId, null, null, null, null, null, null }; Tile owningTile = cCTVCamera.OwningTile; obj[2] = ((owningTile != null) ? ((Object)owningTile).name : null); obj[3] = currentPage + 1; obj[4] = activeSlot; obj[5] = flag; obj[6] = ActiveSlot; obj[7] = DescribeCameraForLog(GetActiveCamera()); log.LogInfo((object)string.Format("[LethalCCTV] PLACEMENT_EDITOR_ADD_CAMERA label='{0}' id='{1}' tile='{2}' previousPage={3} previousSlot={4} focusedNewCamera={5} activeSlot={6} active='{7}'", obj)); } } private static CCTVCamera CreateManualCamera(CCTVCamera source) { //IL_004a: 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_0067: 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) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null || (Object)(object)source.OwningTile == (Object)null || (Object)(object)((Component)source).transform == (Object)null) { return null; } Tile owningTile = source.OwningTile; int num = NextCameraIndex(); GameObject val = new GameObject($"LethalCCTVCamera_{num}_Manual_{((Object)owningTile).name}"); val.transform.SetParent(((Component)owningTile).transform, false); Vector3 val2 = ((Component)source).transform.right * 0.25f; val.transform.SetPositionAndRotation(((Component)source).transform.position + val2, ((Component)source).transform.rotation); Camera cam = val.AddComponent(); CCTVCamera cCTVCamera = val.AddComponent(); cCTVCamera.CameraIndex = num; cCTVCamera.DisplayLabel = BuildUniqueManualCameraLabel(num); cCTVCamera.OwningTile = owningTile; cCTVCamera.Cam = cam; cCTVCamera.HdrpData = null; cCTVCamera.PlacementCornerLocal = Vector3.zero; cCTVCamera.PlacementCornerId = 888; cCTVCamera.MountMode = source.MountMode; cCTVCamera.DrivingRoomHeightM = source.DrivingRoomHeightM; cCTVCamera.PlacementSource = "manual-unsaved"; cCTVCamera.PlacementSurfaceKind = "manual"; cCTVCamera.AuthoredPlacementId = "manual-" + DateTime.UtcNow.ToString("yyyyMMddHHmmssfff"); cCTVCamera.ConfigureDisabled(); cCTVCamera.CaptureBaseline(); CCTVCameraVisual.AttachTo(cCTVCamera); return cCTVCamera; } private static string BuildUniqueManualCameraLabel(int cameraIndex) { int num = Mathf.Max(0, cameraIndex + 1); for (int i = 0; i < 200; i++) { string text = "CAM_" + (num + i).ToString("D2") + "M"; if (!CameraLabelExists(text)) { return text; } } return "CAM_" + cameraIndex.ToString("D2") + "M"; } private static bool CameraLabelExists(string label) { if (string.IsNullOrWhiteSpace(label)) { return false; } CCTVCamera[] array = Object.FindObjectsOfType(true); foreach (CCTVCamera cCTVCamera in array) { if (!((Object)(object)cCTVCamera == (Object)null) && string.Equals(cCTVCamera.ResolvedLabel, label, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } private static int NextCameraIndex() { CCTVCamera[] array = Object.FindObjectsOfType(true); int num = -1; for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null && array[i].CameraIndex > num) { num = array[i].CameraIndex; } } return num + 1; } private static void DeleteActiveCamera() { //IL_0022: 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_0041: Unknown result type (might be due to invalid IL or missing references) CCTVCamera activeCamera = GetActiveCamera(); if ((Object)(object)activeCamera == (Object)null || (Object)(object)activeCamera.OwningTile == (Object)null) { ShowTimedScanStatus("NO CAMERA TO DELETE", OVERLAY_SCAN_RED, 1.4f); return; } if (!InteriorAuthoredPlacementStore.RecordCameraDeletion(activeCamera, out var message)) { ShowTimedScanStatus("DELETE SAVE FAILED", OVERLAY_SCAN_RED, 1.6f); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] PLACEMENT_EDITOR_DELETE_FAILED message='" + message + "'")); } return; } string resolvedLabel = activeCamera.ResolvedLabel; CancelPlacementEditor(restore: false); QuadCameraAssignment.RemoveCamera(activeCamera); Object.Destroy((Object)(object)((Component)activeCamera).gameObject); ShowTimedScanStatus("CAMERA DELETED", OVERLAY_ACTIVE_GREEN, 1.6f); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] PLACEMENT_EDITOR_DELETE_CAMERA label='" + resolvedLabel + "' message='" + message + "'")); } } private static bool TryResolvePlacementEditSession(out PlacementEditSession session, out string reason) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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_0117: Unknown result type (might be due to invalid IL or missing references) session = null; reason = "NO EDIT TARGET"; if (_contextTarget != null && _contextTarget.Commandable && (Object)(object)_contextTarget.Component != (Object)null && Time.unscaledTime <= _contextTarget.ExpiresAt + 3f && CctvCommandTargetBridge.TryDescribeTarget(_contextTarget.Component, out var info)) { Transform val = (((Object)(object)info.Component != (Object)null) ? info.Component.transform : _contextTarget.Component.transform); Tile val2 = FindTileForWorldPosition(val.position); if ((Object)(object)val2 == (Object)null) { reason = "NO TILE FOR TARGET"; return false; } string text = PlacementKindForSupportTarget(info.DisplayName); session = new PlacementEditSession { Transform = val, Tile = val2, ObjectKind = text, ObjectId = text, Label = (info.DisplayName ?? _contextTarget.DisplayName ?? "SUPPORT"), StartPosition = val.position, StartRotation = val.rotation }; return true; } CCTVCamera activeCamera = GetActiveCamera(); if ((Object)(object)activeCamera != (Object)null && (Object)(object)((Component)activeCamera).transform != (Object)null && (Object)(object)activeCamera.OwningTile != (Object)null) { activeCamera.ResetOffsets(); activeCamera.ApplyOffsets(); session = new PlacementEditSession { Transform = ((Component)activeCamera).transform, Camera = activeCamera, Tile = activeCamera.OwningTile, ObjectKind = "camera", ObjectId = ((!string.IsNullOrWhiteSpace(activeCamera.AuthoredPlacementId)) ? activeCamera.AuthoredPlacementId : ("manual-" + DateTime.UtcNow.ToString("yyyyMMddHHmmssfff"))), Label = activeCamera.ResolvedLabel, StartPosition = ((Component)activeCamera).transform.position, StartRotation = ((Component)activeCamera).transform.rotation }; return true; } reason = "NO ACTIVE CAMERA"; return false; } private static bool ApplyPlacementEditorInput(Keyboard keyboard) { //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) //IL_0092: 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_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_00b7: 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_00bb: 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_00dc: 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_00e0: 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_0101: 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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) PlacementEditSession placementEditSession = _placementEditSession; if ((Object)(object)placementEditSession?.Transform == (Object)null) { return false; } bool num = ((ButtonControl)keyboard.leftShiftKey).isPressed || ((ButtonControl)keyboard.rightShiftKey).isPressed; float num2 = Mathf.Max(Time.unscaledDeltaTime, 0.001f); float num3 = (num ? 8f : 0.75f); float num4 = (num ? 180f : 32f); ResolvePlacementEditorAxes(out var forward, out var right); Vector3 val = Vector3.zero; if (((ButtonControl)keyboard.wKey).isPressed || ((ButtonControl)keyboard.upArrowKey).isPressed) { val += forward; } if (((ButtonControl)keyboard.sKey).isPressed || ((ButtonControl)keyboard.downArrowKey).isPressed) { val -= forward; } if (((ButtonControl)keyboard.dKey).isPressed || ((ButtonControl)keyboard.rightArrowKey).isPressed) { val += right; } if (((ButtonControl)keyboard.aKey).isPressed || ((ButtonControl)keyboard.leftArrowKey).isPressed) { val -= right; } if (((ButtonControl)keyboard.rKey).isPressed || ((ButtonControl)keyboard.pageUpKey).isPressed) { val += Vector3.up; } if (((ButtonControl)keyboard.fKey).isPressed || ((ButtonControl)keyboard.pageDownKey).isPressed) { val -= Vector3.up; } bool flag = false; if (((Vector3)(ref val)).sqrMagnitude > 1E-06f) { Transform transform = placementEditSession.Transform; transform.position += ((Vector3)(ref val)).normalized * num3 * num2; flag = true; } float num5 = 0f; if (((ButtonControl)keyboard.qKey).isPressed) { num5 -= num4 * num2; } if (((ButtonControl)keyboard.eKey).isPressed) { num5 += num4 * num2; } if (Mathf.Abs(num5) > 0.001f) { placementEditSession.Transform.rotation = Quaternion.AngleAxis(num5, Vector3.up) * placementEditSession.Transform.rotation; flag = true; } if (flag && (Object)(object)placementEditSession.Camera != (Object)null) { placementEditSession.Camera.ResetOffsets(); placementEditSession.Camera.CaptureBaseline(); } return flag; } private static void ResolvePlacementEditorAxes(out Vector3 forward, out Vector3 right) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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) Transform val = (((Object)(object)GetActiveCamera()?.Cam != (Object)null) ? ((Component)GetActiveCamera().Cam).transform : _placementEditSession?.Transform); forward = (((Object)(object)val != (Object)null) ? val.forward : Vector3.forward); forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 1E-06f) { forward = Vector3.forward; } ((Vector3)(ref forward)).Normalize(); right = (((Object)(object)val != (Object)null) ? val.right : Vector3.right); right.y = 0f; if (((Vector3)(ref right)).sqrMagnitude < 1E-06f) { right = Vector3.Cross(Vector3.up, forward); } ((Vector3)(ref right)).Normalize(); } private static void SavePlacementEditor() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_00ef: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_024f: 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) PlacementEditSession placementEditSession = _placementEditSession; if ((Object)(object)placementEditSession?.Transform == (Object)null || (Object)(object)placementEditSession.Tile == (Object)null) { CancelPlacementEditor(restore: false); ShowTimedScanStatus("PLACEMENT SAVE FAILED", OVERLAY_SCAN_RED, 1.6f); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] PLACEMENT_EDITOR_SAVE_ABORT reason=missing-session-or-tile."); } return; } if ((Object)(object)placementEditSession.Camera != (Object)null) { placementEditSession.Camera.ResetOffsets(); placementEditSession.Camera.CaptureBaseline(); Tile val = FindTileForWorldPosition(placementEditSession.Transform.position); if ((Object)(object)val == (Object)null) { ShowTimedScanStatus("NO TILE AT CAMERA", OVERLAY_SCAN_RED, 1.6f); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)$"[LethalCCTV] PLACEMENT_EDITOR_SAVE_ABORT label='{placementEditSession.Label}' reason=no-tile-at-camera pos=({placementEditSession.Transform.position.x:F2},{placementEditSession.Transform.position.y:F2},{placementEditSession.Transform.position.z:F2})."); } return; } if (!placementEditSession.CreatedDuringEdit && TileHasCamera(val, placementEditSession.Camera)) { ShowTimedScanStatus("TILE ALREADY HAS CAMERA", OVERLAY_SCAN_RED, 1.6f); ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV] PLACEMENT_EDITOR_SAVE_ABORT label='" + placementEditSession.Label + "' reason=tile-already-has-camera tile='" + ((Object)val).name + "'.")); } return; } placementEditSession.Tile = val; placementEditSession.Camera.OwningTile = val; } string message; bool flag = InteriorAuthoredPlacementStore.RecordPlacement(placementEditSession.Transform, placementEditSession.Tile, placementEditSession.ObjectKind, placementEditSession.ObjectId, out message); if (flag && (Object)(object)placementEditSession.Camera != (Object)null) { placementEditSession.Camera.AuthoredPlacementId = placementEditSession.ObjectId; placementEditSession.Camera.PlacementSource = "authored-local"; placementEditSession.Camera.PlacementSurfaceKind = "authored"; } if ((Object)(object)placementEditSession.Camera != (Object)null) { FocusCamera(placementEditSession.Camera, "placement-save"); } string label = placementEditSession.Label; CancelPlacementEditor(restore: false); ShowTimedScanStatus(flag ? "PLACEMENT SAVED" : "PLACEMENT SAVE FAILED", flag ? OVERLAY_ACTIVE_GREEN : OVERLAY_SCAN_RED, 1.8f); ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogInfo((object)$"[LethalCCTV] PLACEMENT_EDITOR_SAVE label='{label}' saved={flag} message='{message}' activeSlot={ActiveSlot} active='{DescribeCameraForLog(GetActiveCamera())}'"); } } private static bool TileHasCamera(Tile tile, CCTVCamera ignore) { if ((Object)(object)tile == (Object)null) { return false; } CCTVCamera[] array = Object.FindObjectsOfType(true); foreach (CCTVCamera cCTVCamera in array) { if (!((Object)(object)cCTVCamera == (Object)null) && cCTVCamera != ignore) { if (cCTVCamera.OwningTile == tile) { return true; } if ((Object)(object)((Component)cCTVCamera).transform != (Object)null && (Object)(object)((Component)tile).transform != (Object)null && ((Component)cCTVCamera).transform.IsChildOf(((Component)tile).transform)) { return true; } } } return false; } private static void CancelPlacementEditor(bool restore) { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) PlacementEditSession placementEditSession = _placementEditSession; if (restore) { PlacementEditSession placementEditSession2 = _placementEditSession; if (placementEditSession2 != null && placementEditSession2.CreatedDuringEdit && (Object)(object)_placementEditSession.Camera != (Object)null) { CCTVCamera camera = _placementEditSession.Camera; int previousPage = _placementEditSession.PreviousPage; int previousSlot = _placementEditSession.PreviousSlot; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] PLACEMENT_EDITOR_CANCEL_NEW_CAMERA camera='{DescribeCameraForLog(camera)}' restorePage={previousPage + 1} restoreSlot={previousSlot}."); } QuadCameraAssignment.RemoveCamera(camera); if ((Object)(object)camera != (Object)null && (Object)(object)((Component)camera).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)camera).gameObject); } if (QuadCameraAssignment.TotalPages > 0) { QuadCameraAssignment.GoToPage(previousPage); } SetActiveSlot(previousSlot); goto IL_01ba; } } if (restore && (Object)(object)_placementEditSession?.Transform != (Object)null) { _placementEditSession.Transform.SetPositionAndRotation(_placementEditSession.StartPosition, _placementEditSession.StartRotation); if ((Object)(object)_placementEditSession.Camera != (Object)null) { _placementEditSession.Camera.ResetOffsets(); _placementEditSession.Camera.CaptureBaseline(); } ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] PLACEMENT_EDITOR_CANCEL_RESTORE label='" + _placementEditSession.Label + "' kind=" + _placementEditSession.ObjectKind + ".")); } } else if (placementEditSession != null) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)$"[LethalCCTV] PLACEMENT_EDITOR_CLOSE label='{placementEditSession.Label}' kind={placementEditSession.ObjectKind} restore={restore}."); } } goto IL_01ba; IL_01ba: _placementEditorOpen = false; GameObject placementEditorRoot = _placementEditorRoot; if (placementEditorRoot != null) { placementEditorRoot.SetActive(false); } _placementEditSession = null; } private static void RefreshPlacementEditorText() { if (!((Object)(object)_placementEditorText == (Object)null)) { ((TMP_Text)_placementEditorText).text = BuildPlacementEditorOverlayText(); } } private static string BuildPlacementEditorOverlayText() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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) PlacementEditSession placementEditSession = _placementEditSession; if ((Object)(object)placementEditSession?.Transform == (Object)null) { return "PLACEMENT TARGET LOST"; } Vector3 position = placementEditSession.Transform.position; Quaternion rotation = placementEditSession.Transform.rotation; Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles; return "PLACEMENT EDIT\n" + placementEditSession.Label + " [" + placementEditSession.ObjectKind + "]\n" + (((Object)(object)placementEditSession.Tile != (Object)null) ? ((Object)placementEditSession.Tile).name : "NO TILE") + "\n\n" + $"POS {position.x:F2}, {position.y:F2}, {position.z:F2}\n" + $"ROT {eulerAngles.x:F1}, {eulerAngles.y:F1}, {eulerAngles.z:F1}\n\n" + "WASD/ARROWS MOVE R/F HEIGHT Q/E ROTATE\nSHIFT FAST ENTER SAVE ESC/0 CANCEL F2 CLOSE"; } private static string PlacementKindForSupportTarget(string displayName) { string text = (displayName ?? string.Empty).Trim().ToLowerInvariant(); if (text.Contains("mainframe")) { return "mainframe"; } if (text.Contains("alarm")) { return "alarm"; } if (text.Contains("vault")) { return "vault"; } return "support"; } private static Tile FindTileForWorldPosition(Vector3 worldPosition) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00ae: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_0148: 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) RoundManager instance = RoundManager.Instance; object obj; if (instance == null) { obj = null; } else { RuntimeDungeon dungeonGenerator = instance.dungeonGenerator; if (dungeonGenerator == null) { obj = null; } else { DungeonGenerator generator = dungeonGenerator.Generator; obj = ((generator != null) ? generator.CurrentDungeon : null); } } Dungeon val = (Dungeon)obj; if (((val != null) ? val.AllTiles : null) == null || val.AllTiles.Count == 0) { return null; } Tile result = null; float num = float.PositiveInfinity; for (int i = 0; i < val.AllTiles.Count; i++) { Tile val2 = val.AllTiles[i]; if ((Object)(object)val2 == (Object)null) { continue; } Bounds bounds = val2.Bounds; if (worldPosition.x >= ((Bounds)(ref bounds)).min.x - 0.25f && worldPosition.x <= ((Bounds)(ref bounds)).max.x + 0.25f && worldPosition.z >= ((Bounds)(ref bounds)).min.z - 0.25f && worldPosition.z <= ((Bounds)(ref bounds)).max.z + 0.25f) { float num2 = ((worldPosition.y < ((Bounds)(ref bounds)).min.y - 4f || worldPosition.y > ((Bounds)(ref bounds)).max.y + 6f) ? 1000f : 0f) + Vector3.Distance(new Vector3(((Bounds)(ref bounds)).center.x, worldPosition.y, ((Bounds)(ref bounds)).center.z), worldPosition); if (!(num2 >= num)) { num = num2; result = val2; } } } return result; } private static void TickCameraReviewInput() { Keyboard current = Keyboard.current; if (current != null && !_placementEditorOpen) { if (_reviewMenuOpen) { TickOpenCameraReviewMenu(current); } else if ((_hackingOverlay == null || !_hackingOverlay.IsOpen) && _cameraPlacementEditModeOpen && ((ButtonControl)current.f4Key).wasPressedThisFrame) { OpenCameraReviewMenu(); } } } private static void TickOpenCameraReviewMenu(Keyboard keyboard) { if (((ButtonControl)keyboard.tabKey).wasPressedThisFrame) { _reviewMenuTagMode = !_reviewMenuTagMode; _reviewMenuSelectedIndex = 0; RefreshCameraReviewMenuText(); return; } if (((ButtonControl)keyboard.upArrowKey).wasPressedThisFrame || ((ButtonControl)keyboard.wKey).wasPressedThisFrame) { MoveCameraReviewSelection(-1); } else if (((ButtonControl)keyboard.downArrowKey).wasPressedThisFrame || ((ButtonControl)keyboard.sKey).wasPressedThisFrame) { MoveCameraReviewSelection(1); } int num = ReadCameraReviewNumberSelection(keyboard); if (num >= 0) { SelectCameraReviewIndex(num); } else if (((ButtonControl)keyboard.digit0Key).wasPressedThisFrame || ((ButtonControl)keyboard.numpad0Key).wasPressedThisFrame) { CloseCameraReviewMenu(); } else if (_reviewMenuTagMode && ((ButtonControl)keyboard.spaceKey).wasPressedThisFrame) { ToggleCameraReviewTag(_reviewMenuSelectedIndex); } else if (((ButtonControl)keyboard.enterKey).wasPressedThisFrame || ((ButtonControl)keyboard.numpadEnterKey).wasPressedThisFrame) { if (_reviewMenuTagMode) { _reviewMenuTagMode = false; _reviewMenuSelectedIndex = 0; RefreshCameraReviewMenuText(); } else { SelectCameraReviewIndex(_reviewMenuSelectedIndex); } } } private static int ReadCameraReviewNumberSelection(Keyboard keyboard) { if (((ButtonControl)keyboard.digit1Key).wasPressedThisFrame || ((ButtonControl)keyboard.numpad1Key).wasPressedThisFrame) { return 0; } if (((ButtonControl)keyboard.digit2Key).wasPressedThisFrame || ((ButtonControl)keyboard.numpad2Key).wasPressedThisFrame) { return 1; } if (((ButtonControl)keyboard.digit3Key).wasPressedThisFrame || ((ButtonControl)keyboard.numpad3Key).wasPressedThisFrame) { return 2; } if (((ButtonControl)keyboard.digit4Key).wasPressedThisFrame || ((ButtonControl)keyboard.numpad4Key).wasPressedThisFrame) { return 3; } if (((ButtonControl)keyboard.digit5Key).wasPressedThisFrame || ((ButtonControl)keyboard.numpad5Key).wasPressedThisFrame) { return 4; } if (((ButtonControl)keyboard.digit6Key).wasPressedThisFrame || ((ButtonControl)keyboard.numpad6Key).wasPressedThisFrame) { return 5; } if (((ButtonControl)keyboard.digit7Key).wasPressedThisFrame || ((ButtonControl)keyboard.numpad7Key).wasPressedThisFrame) { return 6; } if (((ButtonControl)keyboard.digit8Key).wasPressedThisFrame || ((ButtonControl)keyboard.numpad8Key).wasPressedThisFrame) { return 7; } if (((ButtonControl)keyboard.digit9Key).wasPressedThisFrame || ((ButtonControl)keyboard.numpad9Key).wasPressedThisFrame) { return 8; } return -1; } private static void MoveCameraReviewSelection(int delta) { int num = (_reviewMenuTagMode ? ReviewTagValues.Length : ReviewMenuRatings.Length); if (num > 0) { _reviewMenuSelectedIndex = ((_reviewMenuSelectedIndex + delta) % num + num) % num; RefreshCameraReviewMenuText(); } } private static void ToggleCameraReviewTag(int index) { if (index < 0 || index >= ReviewTagValues.Length) { return; } string text = ReviewTagValues[index]; for (int i = 0; i < _reviewSelectedTags.Count; i++) { if (string.Equals(_reviewSelectedTags[i], text, StringComparison.OrdinalIgnoreCase)) { _reviewSelectedTags.RemoveAt(i); RefreshCameraReviewMenuText(); return; } } _reviewSelectedTags.Add(text); RefreshCameraReviewMenuText(); } private static void SelectCameraReviewIndex(int index) { if (index >= 0 && index < ReviewMenuRatings.Length) { CameraPlacementReviewRating rating = ReviewMenuRatings[index]; string label = ReviewMenuLabels[index]; RecordActiveCameraReview(rating, label); CloseCameraReviewMenu(); } } private static void OpenCameraReviewMenu() { _cameraPlacementEditModeOpen = true; _reviewMenuSelectedIndex = 0; _reviewSelectedTags.Clear(); _reviewMenuTagMode = false; _reviewMenuOpen = true; if ((Object)(object)_reviewMenuRoot != (Object)null) { _reviewMenuRoot.SetActive(true); } RefreshCameraReviewMenuText(); _scanVisibleUntil = 0f; HideScanLabels(); } private static void CloseCameraReviewMenu() { _reviewMenuOpen = false; _reviewSelectedTags.Clear(); _reviewMenuTagMode = false; if ((Object)(object)_reviewMenuRoot != (Object)null) { _reviewMenuRoot.SetActive(false); } } private static void RefreshCameraReviewMenuText() { if (!((Object)(object)_reviewMenuText == (Object)null)) { ((TMP_Text)_reviewMenuText).text = BuildCameraReviewMenuOverlayText(); } } private static string BuildCameraReviewMenuOverlayText() { CCTVCamera activeCamera = GetActiveCamera(); string text = (((Object)(object)activeCamera != (Object)null) ? activeCamera.ResolvedLabel : "NO CAMERA"); string text2 = "CAMERA REVIEW\n" + text + "\n\n"; if (_reviewMenuTagMode) { text2 += "TAB RATINGS SPACE TOGGLE TAG ENTER RATINGS\n"; for (int i = 0; i < ReviewTagLabels.Length; i++) { bool num = i == _reviewMenuSelectedIndex; string text3 = (num ? ">" : " "); string text4 = (num ? "#33ff66" : "#ffffff"); string text5 = (ReviewTagSelected(ReviewTagValues[i]) ? "[x]" : "[ ]"); text2 = text2 + "" + text3 + " " + text5 + " " + ReviewTagLabels[i] + "\n"; } } else { text2 += "TAB TAGS ENTER SAVE RATING\n"; for (int j = 0; j < ReviewMenuLabels.Length; j++) { bool num2 = j == _reviewMenuSelectedIndex; string text6 = (num2 ? ">" : " "); string text7 = (num2 ? "#33ff66" : "#ffffff"); string text8 = ((j < 9) ? $"{j + 1}." : " "); text2 = text2 + "" + text6 + " " + text8 + " " + ReviewMenuLabels[j] + "\n"; } } text2 = text2 + "\nSELECTED TAGS " + FormatSelectedReviewTags() + ""; return text2 + "\n1-9 RATING 0 CANCEL F2 CLOSE"; } private static bool ReviewTagSelected(string tag) { for (int i = 0; i < _reviewSelectedTags.Count; i++) { if (string.Equals(_reviewSelectedTags[i], tag, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } private static string FormatSelectedReviewTags() { if (_reviewSelectedTags.Count <= 0) { return "<none>"; } return string.Join(",", _reviewSelectedTags.ToArray()); } private static void RecordActiveCameraReview(CameraPlacementReviewRating rating, string label) { //IL_0047: 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) string message; bool flag = CameraPlacementReviewStore.RecordReview(GetActiveCamera(), rating, _reviewSelectedTags, out message); _scanVisibleUntil = Time.unscaledTime + 1.6f; ShowScanStatus(flag ? ("REVIEW " + label + " SAVED") : "REVIEW FAILED", flag ? OVERLAY_ACTIVE_GREEN : OVERLAY_SCAN_RED); UpdateCameraScanOverlay(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] CAMERA_REVIEW_INPUT rating={rating} saved={flag} message={message}"); } } private static bool BeginEntryPerfFrame() { if (_entryPerfCapturing) { return false; } int num; int num2; if (_stationPoseSettleActive) { num = ((!IsFocused) ? 1 : 0); if (num != 0) { num2 = 0; goto IL_0029; } } else { num = 0; } num2 = ((_entryPerfFollowupFramesRemaining > 0) ? 1 : 0); goto IL_0029; IL_0029: bool flag = (byte)num2 != 0; if (num == 0 && !flag) { return false; } _entryPerfCapturing = true; _entryPerfFollowupFrame = flag; _entryPerfWasFocusedAtFrameStart = IsFocused; _entryPerfStepCount = 0; _entryPerfOverflowTicks = 0L; _entryPerfOverflowSteps = 0; _entryPerfFrameStartedAt = Stopwatch.GetTimestamp(); _entryPerfLastMarkAt = _entryPerfFrameStartedAt; return true; } private static void EntryPerfMark(string stepName) { if (_entryPerfCapturing) { long timestamp = Stopwatch.GetTimestamp(); long num = timestamp - _entryPerfLastMarkAt; _entryPerfLastMarkAt = timestamp; if (_entryPerfStepCount < 96) { _entryPerfStepNames[_entryPerfStepCount] = stepName; _entryPerfStepTicks[_entryPerfStepCount] = num; _entryPerfStepCount++; } else { _entryPerfOverflowTicks += num; _entryPerfOverflowSteps++; } } } private static void EndEntryPerfFrame() { if (!_entryPerfCapturing) { return; } EntryPerfMark("tick-tail"); _entryPerfCapturing = false; bool flag = !_entryPerfWasFocusedAtFrameStart && IsFocused; bool entryPerfFollowupFrame = _entryPerfFollowupFrame; _entryPerfFollowupFrame = false; if (entryPerfFollowupFrame && _entryPerfFollowupFramesRemaining > 0) { _entryPerfFollowupFramesRemaining--; } if (flag) { _entryPerfFollowupFramesRemaining = 1; } else if (!entryPerfFollowupFrame) { return; } try { LogEntryPerfFrame(flag ? "entry" : "entry+1"); } catch { } } private static void LogEntryPerfFrame(string phase) { double num = 1000.0 / (double)Stopwatch.Frequency; double num2 = (double)(_entryPerfLastMarkAt - _entryPerfFrameStartedAt) * num; _entryPerfBuilder.Length = 0; _entryPerfBuilder.Append("[LethalCCTV][EntryPerf] phase=").Append(phase).Append(" frame=") .Append(Time.frameCount) .Append(" total=") .Append(num2.ToString("F1")) .Append("ms"); double num3 = 0.0; for (int i = 0; i < _entryPerfStepCount; i++) { double num4 = (double)_entryPerfStepTicks[i] * num; if (num4 < 0.05) { num3 += num4; } else { _entryPerfBuilder.Append(' ').Append(_entryPerfStepNames[i]).Append('=') .Append(num4.ToString("F2")); } } if (_entryPerfOverflowSteps > 0) { _entryPerfBuilder.Append(" overflow(").Append(_entryPerfOverflowSteps).Append(" steps)=") .Append(((double)_entryPerfOverflowTicks * num).ToString("F2")); } if (num3 >= 0.05) { _entryPerfBuilder.Append(" sub-floor-steps=").Append(num3.ToString("F2")); } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)_entryPerfBuilder.ToString()); } } private static bool TryEnterFocusPreflight(bool allowPoseSettleOwner, out PlayerControllerB player, out string failureReason) { player = null; failureReason = null; if (IsFocused) { failureReason = "already-focused"; return false; } if ((Object)(object)QuadMonitor.MonitorRoot == (Object)null || QuadMonitor.QuadRTs == null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] MonitorFocus.EnterFocus: monitor not spawned, ignoring."); } failureReason = "monitor-not-spawned"; return false; } player = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)player == (Object)null) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)"[LethalCCTV] MonitorFocus.EnterFocus: local player not resolvable, ignoring."); } failureReason = "local-player-unavailable"; return false; } if (player.inTerminalMenu) { failureReason = "terminal-menu-open"; return false; } if ((Object)(object)player.quickMenuManager != (Object)null && player.quickMenuManager.isMenuOpen) { failureReason = "quick-menu-open"; return false; } if (player.isTypingChat) { failureReason = "chat-open"; return false; } int num; if (allowPoseSettleOwner && _stationPoseSettleActive && _stationPoseSettleTransferToFocus) { num = ((player == _stationPoseSettlePlayer) ? 1 : 0); if (num != 0) { goto IL_010e; } } else { num = 0; } RecoverStaleFocusInputLock(player, "enter-focus-preflight"); ClearResidualFocusAnimation(player, "enter-focus-preflight"); goto IL_010e; IL_010e: if (num == 0 && (player.inSpecialInteractAnimation || player.enteringSpecialAnimation)) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)"[LethalCCTV] MonitorFocus.EnterFocus ignored while the player is already in a special animation."); } failureReason = "special-animation-active"; return false; } return true; } internal static bool BeginEntryPoseSettle(PlayerControllerB requestedPlayer) { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) long timestamp = Stopwatch.GetTimestamp(); if (_stationPoseSettleActive) { return RejectEntryPoseSettle(requestedPlayer, "already-settling"); } if (!TryEnterFocusPreflight(allowPoseSettleOwner: false, out var player, out var failureReason)) { return RejectEntryPoseSettle(requestedPlayer, "preflight-" + failureReason); } if ((Object)(object)requestedPlayer != (Object)null && requestedPlayer != player) { return RejectEntryPoseSettle(requestedPlayer, "local-player-changed"); } if (player.isPlayerDead || !player.isPlayerControlled) { return RejectEntryPoseSettle(player, "player-invalid"); } if (!CCTVMonitorFeedSync.IsShipLandedForCctv()) { return RejectEntryPoseSettle(player, "round-not-landed"); } if (!CCTVMonitorFeedSync.IsLocalOperator) { return RejectEntryPoseSettle(player, "entry-claim-not-owned"); } Transform playerRootAnchor = CCTVOperatorStation.PlayerRootAnchor; if (!CCTVOperatorStation.IsReady || (Object)(object)playerRootAnchor == (Object)null) { return RejectEntryPoseSettle(player, "operator-anchor-unavailable"); } if ((Object)(object)player.gameplayCamera == (Object)null) { return RejectEntryPoseSettle(player, "gameplay-camera-unavailable"); } _introCameraRenderedFramesLogged = 0; _introCameraLastRenderedFrame = -1; Transform transform = ((Component)player.gameplayCamera).transform; _stationPoseSettleEntryCameraPoseCaptured = true; _stationPoseSettleEntryCameraWorldPosition = transform.position; _stationPoseSettleEntryCameraWorldRotation = transform.rotation; Y4NGZPlayerAnimationBridge.CaptureInteractionBeginPresentation(player); LogIntroCameraPose("interaction-begin/pre-root-snap", _stationPoseSettleEntryCameraWorldPosition, _stationPoseSettleEntryCameraWorldRotation); long timestamp2 = Stopwatch.GetTimestamp(); StationPlayerPoseSnapshot stationPoseSettleSnapshot = CaptureStationPlayerPoseSnapshot(player); double num = (double)(Stopwatch.GetTimestamp() - timestamp2) * 1000.0 / (double)Stopwatch.Frequency; if (!stationPoseSettleSnapshot.Valid) { Y4NGZPlayerAnimationBridge.AbortInteractionBeginPresentation(player, "pose-settle-pose-snapshot-failed"); return RejectEntryPoseSettle(player, "pose-snapshot-failed"); } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(playerRootAnchor.position.x, stationPoseSettleSnapshot.Position.y, playerRootAnchor.position.z); Quaternion stationPoseSettleTargetRotation = FlattenToYaw(_stationPoseSettleEntryCameraWorldRotation); float signedCameraPitchDegrees = GetSignedCameraPitchDegrees(_stationPoseSettleEntryCameraWorldRotation); string text = "live-look-preserved"; string arg = ((playerRootAnchor == CCTVOperatorStation.OperatorPoseAnchor) ? "operator-pose-fallback" : "player-root"); string arg2 = (((Object)(object)player.thisController == (Object)null) ? "unknown" : (player.thisController.isGrounded ? "false" : "true")); _stationPoseSettleActive = true; _stationPoseSettleTransferToFocus = false; _stationPoseSettlePlayer = player; _stationPoseSettleAnchor = playerRootAnchor; _stationPoseSettleTargetPosition = val; _stationPoseSettleTargetRotation = stationPoseSettleTargetRotation; _stationPoseSettleTargetCameraUp = signedCameraPitchDegrees; _stationPoseSettleSnapshot = stationPoseSettleSnapshot; _stationPoseSettleStartedAt = Time.unscaledTime; _stationPoseSettleFrames = 0; _stationPoseSettleHardSetFrame = -1; _settleViewFramingLogPending = false; _arrivalViewFramingLogPending = false; try { float num2 = Vector3.Distance(((Component)player).transform.position, val); float num3 = AbsAngleDelta(((Component)player).transform.eulerAngles.y, ((Quaternion)(ref stationPoseSettleTargetRotation)).eulerAngles.y); Vector3 localEulerAngles = ((Component)player.gameplayCamera).transform.localEulerAngles; ApplyEntryPoseSettleFlags(player, playerRootAnchor, notifyRemote: true); _localObstructorCallLogs.Clear(); _boundaryInputRecoveryLogs.Clear(); _visorSnapProbeLogsRemaining = 3; long timestamp3 = Stopwatch.GetTimestamp(); SuppressLocalPlayerObstructors(player, "pose-settle-start"); double num4 = (double)(Stopwatch.GetTimestamp() - timestamp3) * 1000.0 / (double)Stopwatch.Frequency; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][PoseSettle] start " + $"savedWorld={FormatDebugVector(stationPoseSettleSnapshot.Position)}/yaw={((Quaternion)(ref stationPoseSettleSnapshot.Rotation)).eulerAngles.y:F2} " + $"anchorWorld={FormatDebugVector(playerRootAnchor.position)}/yaw={playerRootAnchor.eulerAngles.y:F2} " + $"settleY={val.y:F3} anchorKind={arg} airborneAtStart={arg2} " + "cameraTargetKind=" + text + " targetCamLocalEuler=" + FormatDebugVector(new Vector3(signedCameraPitchDegrees, 0f, 0f)) + " " + $"startDistance={num2:F4} startYawDelta={num3:F3} " + "camLocalEuler=" + FormatDebugVector(localEulerAngles) + ".")); } double num5 = (double)(Stopwatch.GetTimestamp() - timestamp) * 1000.0 / (double)Stopwatch.Frequency; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV][PoseSettle] startCost=" + $"total={num5:F3}ms suppression={num4:F3}ms " + $"snapshot={num:F3}ms.")); } return true; } catch (Exception ex) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV] Pose settle start failed: " + ex.Message)); } AbortEntryPoseSettle("start-failed"); return false; } } private static bool RejectEntryPoseSettle(PlayerControllerB player, string reason) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][PoseSettle] abort reason=" + reason + ".")); } CCTVMonitorFeedSync.ReleaseLocalEntryClaim(player, "pose-settle-" + reason); return false; } private static StationPlayerPoseSnapshot CaptureStationPlayerPoseSnapshot(PlayerControllerB player) { //IL_004d: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0162: 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_014a: 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) if ((Object)(object)player == (Object)null) { return default(StationPlayerPoseSnapshot); } bool flag = (Object)(object)player.thisController != (Object)null; bool flag2 = (Object)(object)player.gameplayCamera != (Object)null; return new StationPlayerPoseSnapshot { Valid = true, Player = player, Position = ((Component)player).transform.position, Rotation = ((Component)player).transform.rotation, ServerPosition = player.serverPlayerPosition, SnapToServerPosition = player.snapToServerPosition, DisableSyncInAnimation = player.disableSyncInAnimation, DisableLookInput = player.disableLookInput, FreeRotationInInteractAnimation = player.freeRotationInInteractAnimation, ClampLooking = player.clampLooking, MinVerticalClamp = player.minVerticalClamp, MaxVerticalClamp = player.maxVerticalClamp, HorizontalClamp = player.horizontalClamp, InSpecialInteractAnimation = player.inSpecialInteractAnimation, EnteringSpecialAnimation = player.enteringSpecialAnimation, HadController = flag, ControllerDetectCollisions = (flag && player.thisController.detectCollisions), ControllerEnabled = (flag && ((Collider)player.thisController).enabled), WasCrouching = player.isCrouching, CameraBaselineCaptured = flag2, CameraPlayerLocalPosition = (flag2 ? ((Component)player).transform.InverseTransformPoint(((Component)player.gameplayCamera).transform.position) : Vector3.zero) }; } private static void ApplyEntryPoseSettleFlags(PlayerControllerB player, Transform anchor, bool notifyRemote) { //IL_0023: 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_0006: Unknown result type (might be due to invalid IL or missing references) if (notifyRemote) { player.UpdateSpecialAnimationValue(true, (short)anchor.eulerAngles.y, 0f, false); } player.serverPlayerPosition = ((Component)player).transform.localPosition; player.snapToServerPosition = false; player.disableSyncInAnimation = true; player.disableLookInput = true; player.freeRotationInInteractAnimation = false; player.clampLooking = true; player.minVerticalClamp = _stationPoseSettleTargetCameraUp; player.maxVerticalClamp = _stationPoseSettleTargetCameraUp; player.horizontalClamp = 0f; player.inSpecialInteractAnimation = true; player.enteringSpecialAnimation = false; if (player.isCrouching) { player.Crouch(false); } player.ResetFallGravity(); } private static void TickEntryPoseSettle() { //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) if (!_stationPoseSettleActive) { return; } string entryPoseSettleAbortReason = GetEntryPoseSettleAbortReason(); if (entryPoseSettleAbortReason != null) { AbortEntryPoseSettle(entryPoseSettleAbortReason); return; } PlayerControllerB stationPoseSettlePlayer = _stationPoseSettlePlayer; Transform stationPoseSettleAnchor = _stationPoseSettleAnchor; Transform transform = ((Component)stationPoseSettlePlayer.gameplayCamera).transform; ReleaseEntryPoseSettleCameraRenderPin(transform); if (_stationPoseSettleHardSetFrame >= 0) { HardSetEntryPose(stationPoseSettlePlayer, stationPoseSettleAnchor, transform); EntryPerfMark("PoseSettle.hard-set"); if (Time.frameCount <= _stationPoseSettleHardSetFrame) { ApplyEntryPoseSettleCameraRenderPin(transform); return; } RestoreEntryPoseSettleLookState(stationPoseSettlePlayer, _stationPoseSettleSnapshot); _stationPoseSettleTransferToFocus = true; EntryPerfMark("PoseSettle.handoff-prep"); try { EnterFocus(stationPoseSettlePlayer); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Pose settle handoff to EnterFocus failed: " + ex.Message)); } } EntryPerfMark("EnterFocus.log-tail"); if (IsFocused) { ResetEntryPoseSettleState(); ApplyPhysicalFocusView(); EntryPerfMark("PoseSettle.post-enter-view"); } else { _stationPoseSettleTransferToFocus = false; AbortEntryPoseSettle("enter-focus-rejected"); } return; } _stationPoseSettleFrames++; float num = Time.deltaTime * 20f; Transform transform2 = ((Component)stationPoseSettlePlayer).transform; Transform parent = transform2.parent; if ((Object)(object)parent != (Object)null) { Vector3 val = parent.InverseTransformPoint(_stationPoseSettleTargetPosition); transform2.localPosition = Vector3.Lerp(transform2.localPosition, val, num); } else { transform2.position = Vector3.Lerp(transform2.position, _stationPoseSettleTargetPosition, num); } ApplyEntryPosePreservedLook(stationPoseSettlePlayer, transform); stationPoseSettlePlayer.serverPlayerPosition = transform2.localPosition; stationPoseSettlePlayer.snapToServerPosition = false; float num2 = Vector3.Distance(transform2.position, _stationPoseSettleTargetPosition); float num3 = AbsAngleDelta(transform2.eulerAngles.y, ((Quaternion)(ref _stationPoseSettleTargetRotation)).eulerAngles.y); Vector3 localEulerAngles = transform.localEulerAngles; float num4 = AbsAngleDelta(localEulerAngles.x, _stationPoseSettleTargetCameraUp); float num5 = AbsAngleDelta(localEulerAngles.y, 0f); float num6 = AbsAngleDelta(localEulerAngles.z, 0f); bool flag = num4 <= 0.5f && num5 <= 0.5f && num6 <= 0.5f; float num7 = Time.unscaledTime - _stationPoseSettleStartedAt; bool flag2 = num7 >= 1.5f; bool num8 = num2 <= 0.01f && num3 <= 0.5f && flag; if (_stationPoseSettleFrames > 60 && _stationPoseSettleFrames % 30 == 0) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV][PoseSettle] fight " + $"frames={_stationPoseSettleFrames} elapsed={num7:F3} " + $"rootYawDelta={num3:F4} camPitchDelta={num4:F4}.")); } } if (!num8 && !flag2) { ApplyEntryPoseSettleCameraRenderPin(transform); return; } HardSetEntryPose(stationPoseSettlePlayer, stationPoseSettleAnchor, transform); LogIntroCameraPose("post-root-snap", transform.position, transform.rotation); _stationPoseSettleHardSetFrame = Time.frameCount; float num9 = Vector3.Distance(transform2.position, _stationPoseSettleTargetPosition); float num10 = AbsAngleDelta(transform2.eulerAngles.y, ((Quaternion)(ref _stationPoseSettleTargetRotation)).eulerAngles.y); ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)("[LethalCCTV][PoseSettle] complete " + $"frames={_stationPoseSettleFrames} elapsed={num7:F3} " + $"finalPosDelta={num9:F5} finalYawDelta={num10:F4} " + $"finalRootY={transform2.position.y:F3} " + "finalCamLocalEuler=" + FormatDebugVector(transform.localEulerAngles) + " timedOut=" + (flag2 ? "true" : "false") + ".")); } _settleViewFramingLogPending = true; ApplyEntryPoseSettleCameraRenderPin(transform); } private static void ApplyEntryPoseSettleCameraRenderPin(Transform cameraTransform) { //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_001d: Unknown result type (might be due to invalid IL or missing references) if (_stationPoseSettleEntryCameraPoseCaptured && !((Object)(object)cameraTransform == (Object)null)) { _stationPoseSettleCameraRenderPinSavedPosition = cameraTransform.position; cameraTransform.position = _stationPoseSettleEntryCameraWorldPosition; _stationPoseSettleCameraRenderPinActive = true; SnapLocalVisorToCameraTarget("settle-render-pin"); } } private static void ReleaseEntryPoseSettleCameraRenderPin(Transform cameraTransform) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (_stationPoseSettleCameraRenderPinActive) { if ((Object)(object)cameraTransform != (Object)null) { cameraTransform.position = _stationPoseSettleCameraRenderPinSavedPosition; } _stationPoseSettleCameraRenderPinActive = false; } } private static void SnapLocalVisorToCameraTarget(string phase) { //IL_0061: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) if (!KeepLocalVisorDuringSessionEnabled || (Object)(object)_focusHiddenLocalVisor != (Object)null) { return; } PlayerControllerB val = (((Object)(object)_focusedPlayer != (Object)null) ? _focusedPlayer : _stationPoseSettlePlayer); if ((Object)(object)val == (Object)null) { return; } try { Transform localVisor = val.localVisor; Transform localVisorTargetPoint = val.localVisorTargetPoint; if ((Object)(object)localVisor == (Object)null || (Object)(object)localVisorTargetPoint == (Object)null) { return; } Vector3 position = localVisorTargetPoint.position; float num = Vector3.Distance(localVisor.position, position); if (num > 2f) { if (_visorSnapProbeLogsRemaining > 0) { _visorSnapProbeLogsRemaining--; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][VisorGlue] phase={phase} frame={Time.frameCount} " + $"skipped=parked positionDelta={num:F2}m (visor parked elsewhere; not snapping).")); } } return; } if (_visorSnapProbeLogsRemaining > 0) { _visorSnapProbeLogsRemaining--; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)($"[LethalCCTV][VisorGlue] phase={phase} frame={Time.frameCount} " + $"preSnapPositionDelta={num:F4}m " + $"preSnapRotationDelta={Quaternion.Angle(localVisor.rotation, localVisorTargetPoint.rotation):F2}deg.")); } } localVisor.SetPositionAndRotation(position, localVisorTargetPoint.rotation); } catch { } } private static string GetEntryPoseSettleAbortReason() { PlayerControllerB stationPoseSettlePlayer = _stationPoseSettlePlayer; if ((Object)(object)stationPoseSettlePlayer == (Object)null) { return "player-destroyed"; } if (stationPoseSettlePlayer.isPlayerDead || !stationPoseSettlePlayer.isPlayerControlled) { return "player-invalid"; } if ((((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null) != stationPoseSettlePlayer) { return "local-player-changed"; } if (stationPoseSettlePlayer.teleportedLastFrame) { return "player-teleported"; } if (!CCTVMonitorFeedSync.IsShipLandedForCctv()) { return "round-ended"; } if (!CCTVMonitorFeedSync.IsLocalOperator) { return "entry-claim-lost"; } if (!CCTVOperatorStation.IsReady || (Object)(object)_stationPoseSettleAnchor == (Object)null || CCTVOperatorStation.PlayerRootAnchor != _stationPoseSettleAnchor) { return "operator-station-changed"; } if ((Object)(object)stationPoseSettlePlayer.gameplayCamera == (Object)null) { return "gameplay-camera-lost"; } if (stationPoseSettlePlayer.inTerminalMenu) { return "terminal-menu-opened"; } if ((Object)(object)stationPoseSettlePlayer.quickMenuManager != (Object)null && stationPoseSettlePlayer.quickMenuManager.isMenuOpen) { return "quick-menu-opened"; } if (stationPoseSettlePlayer.isTypingChat) { return "chat-opened"; } if (!stationPoseSettlePlayer.inSpecialInteractAnimation || stationPoseSettlePlayer.enteringSpecialAnimation) { return "special-animation-state-lost"; } return null; } private static void HardSetEntryPose(PlayerControllerB player, Transform anchor, Transform cameraTransform) { //IL_0006: 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) ((Component)player).transform.SetPositionAndRotation(_stationPoseSettleTargetPosition, _stationPoseSettleTargetRotation); ApplyEntryPosePreservedLook(player, cameraTransform); ApplyEntryPoseSettleFlags(player, anchor, notifyRemote: false); } private static void ApplyEntryPosePreservedLook(PlayerControllerB player, Transform cameraTransform) { //IL_0006: 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_0035: 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_004b: 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_0075: 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_009f: Unknown result type (might be due to invalid IL or missing references) ((Component)player).transform.rotation = _stationPoseSettleTargetRotation; player.cameraUp = _stationPoseSettleTargetCameraUp; cameraTransform.localEulerAngles = new Vector3(_stationPoseSettleTargetCameraUp, 0f, 0f); float planarYaw = GetPlanarYaw(_stationPoseSettleEntryCameraWorldRotation * Vector3.forward); float num = Mathf.DeltaAngle(GetPlanarYaw(cameraTransform.forward), planarYaw); if (Mathf.Abs(num) > 0.0001f) { ((Component)player).transform.rotation = Quaternion.AngleAxis(num, Vector3.up) * ((Component)player).transform.rotation; cameraTransform.localEulerAngles = new Vector3(_stationPoseSettleTargetCameraUp, 0f, 0f); } } private static void RestoreEntryPoseSettleLookState(PlayerControllerB player, StationPlayerPoseSnapshot snapshot) { if (!((Object)(object)player == (Object)null) && snapshot.Valid && snapshot.Player == player) { player.disableLookInput = snapshot.DisableLookInput; player.freeRotationInInteractAnimation = snapshot.FreeRotationInInteractAnimation; player.clampLooking = snapshot.ClampLooking; player.minVerticalClamp = snapshot.MinVerticalClamp; player.maxVerticalClamp = snapshot.MaxVerticalClamp; player.horizontalClamp = snapshot.HorizontalClamp; } } private static void AbortEntryPoseSettle(string reason) { //IL_00ac: 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) if (!_stationPoseSettleActive) { return; } PlayerControllerB stationPoseSettlePlayer = _stationPoseSettlePlayer; if ((Object)(object)stationPoseSettlePlayer != (Object)null && (Object)(object)stationPoseSettlePlayer.gameplayCamera != (Object)null) { ReleaseEntryPoseSettleCameraRenderPin(((Component)stationPoseSettlePlayer.gameplayCamera).transform); } Y4NGZPlayerAnimationBridge.AbortInteractionBeginPresentation(stationPoseSettlePlayer, "pose-settle-" + reason); StationPlayerPoseSnapshot stationPoseSettleSnapshot = _stationPoseSettleSnapshot; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][PoseSettle] abort reason=" + reason + ".")); } if ((Object)(object)stationPoseSettlePlayer != (Object)null && stationPoseSettleSnapshot.Valid && stationPoseSettleSnapshot.Player == stationPoseSettlePlayer) { try { if (!stationPoseSettleSnapshot.InSpecialInteractAnimation) { stationPoseSettlePlayer.UpdateSpecialAnimationValue(false, (short)0, 0f, false); } stationPoseSettlePlayer.serverPlayerPosition = ((Component)stationPoseSettlePlayer).transform.localPosition; stationPoseSettlePlayer.snapToServerPosition = stationPoseSettleSnapshot.SnapToServerPosition; stationPoseSettlePlayer.disableSyncInAnimation = stationPoseSettleSnapshot.DisableSyncInAnimation; RestoreEntryPoseSettleLookState(stationPoseSettlePlayer, stationPoseSettleSnapshot); stationPoseSettlePlayer.inSpecialInteractAnimation = stationPoseSettleSnapshot.InSpecialInteractAnimation; stationPoseSettlePlayer.enteringSpecialAnimation = stationPoseSettleSnapshot.EnteringSpecialAnimation; if (stationPoseSettlePlayer.isCrouching != stationPoseSettleSnapshot.WasCrouching) { stationPoseSettlePlayer.Crouch(stationPoseSettleSnapshot.WasCrouching); } stationPoseSettlePlayer.ResetFallGravity(); } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Pose settle abort flag cleanup failed: " + ex.Message)); } } } RestoreLocalPlayerObstructors("pose-settle-abort"); ResetEntryPoseSettleState(); CCTVMonitorFeedSync.ReleaseLocalEntryClaim(stationPoseSettlePlayer, "pose-settle-" + reason); } private static void ResetEntryPoseSettleState() { //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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) _stationPoseSettleActive = false; _stationPoseSettleTransferToFocus = false; _stationPoseSettlePlayer = null; _stationPoseSettleAnchor = null; _stationPoseSettleTargetPosition = Vector3.zero; _stationPoseSettleTargetRotation = Quaternion.identity; _stationPoseSettleTargetCameraUp = 0f; _stationPoseSettleEntryCameraPoseCaptured = false; _stationPoseSettleEntryCameraWorldPosition = Vector3.zero; _stationPoseSettleEntryCameraWorldRotation = Quaternion.identity; _stationPoseSettleSnapshot = default(StationPlayerPoseSnapshot); _stationPoseSettleStartedAt = 0f; _stationPoseSettleFrames = 0; _stationPoseSettleHardSetFrame = -1; _stationPoseSettleCameraRenderPinActive = false; } private static float AbsAngleDelta(float a, float b) { return Mathf.Abs(Mathf.DeltaAngle(a, b)); } internal static void PrewarmFocusHudScan() { if (_focusHudSceneScanCompleted) { return; } try { long timestamp = Stopwatch.GetTimestamp(); CollectFocusHudDimTargets(includeSceneScans: true); _focusHudSceneScanCompleted = true; double num = (double)(Stopwatch.GetTimestamp() - timestamp) * 1000.0 / (double)Stopwatch.Frequency; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)($"[LethalCCTV][EntryPerf] PrewarmFocusHudScan total={num:F1}ms " + $"hudFields={_hudScanFieldsMs:F1} canvasSiblings={_hudScanCanvasSiblingsMs:F1} " + $"cursor={_hudScanCursorMs:F1} prompts={_hudScanPromptsMs:F1} " + $"namedChrome={_hudScanNamedChromeMs:F1} screenSpace={_hudScanScreenSpaceMs:F1} " + $"(groups={_focusHudDimTargets.Count} graphics={_focusHudGraphicTargets.Count}).")); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogDebug((object)("[LethalCCTV] Focus HUD scan prewarm failed (will scan on first focus): " + ex.Message)); } } } private static void ApplyFocusHudDimming(bool force) { float unscaledTime = Time.unscaledTime; bool flag = _focusHudDimTargets.Count > 0 || _focusHudGraphicTargets.Count > 0; if (!force && flag && unscaledTime < _nextFocusHudDimRefreshAt) { ApplyStoredFocusHudDimTargets(); EntryPerfMark("HudDim.apply-stored"); return; } bool num = force && !_focusHudSceneScanCompleted; _nextFocusHudDimRefreshAt = unscaledTime + 8f; CollectFocusHudDimTargets(num); if (num) { _focusHudSceneScanCompleted = true; } ApplyStoredFocusHudDimTargets(); EntryPerfMark("HudDim.apply-stored"); _focusHudDimActive = _focusHudDimTargets.Count > 0 || _focusHudGraphicTargets.Count > 0; } private static double HudScanStepMs(ref long lastAt) { long timestamp = Stopwatch.GetTimestamp(); double result = (double)(timestamp - lastAt) * 1000.0 / (double)Stopwatch.Frequency; lastAt = timestamp; return result; } private static void CollectFocusHudDimTargets(bool includeSceneScans) { long lastAt = Stopwatch.GetTimestamp(); _hudScanFieldsMs = 0.0; _hudScanCanvasSiblingsMs = 0.0; _hudScanCursorMs = 0.0; _hudScanPromptsMs = 0.0; _hudScanNamedChromeMs = 0.0; _hudScanScreenSpaceMs = 0.0; HUDManager instance = HUDManager.Instance; if ((Object)(object)instance != (Object)null) { AddHudFieldTargets(instance, "weightCounter"); AddHudFieldTargets(instance, "healthText"); AddHudFieldTargets(instance, "batteryInventoryNumber"); AddHudFieldTargets(instance, "utilitySlotKeyText"); AddHudFieldTargets(instance, "holdingTwoHandedItem"); AddHudFieldTargets(instance, "totalValueText"); AddHudFieldTargets(instance, "statusEffectText"); AddHudFieldTargets(instance, "clockNumber"); AddHudFieldTargets(instance, "buildModeControlTip"); AddHudFieldTargets(instance, "healthMeter"); AddHudFieldTargets(instance, "sprintMeterUI"); AddHudFieldTargets(instance, "batteryIcon"); AddHudFieldTargets(instance, "batteryMeter"); AddHudFieldTargets(instance, "PTTIcon"); AddHudFieldTargets(instance, "holdInteractionFillAmount"); AddHudFieldTargets(instance, "itemOnlySlotIconFrame", preferParent: true); AddHudFieldTargets(instance, "itemOnlySlotIcon", preferParent: true); AddHudFieldTargets(instance, "itemSlotIconFrames", preferParent: true); AddHudFieldTargets(instance, "itemSlotIcons", preferParent: true); AddHudFieldTargets(instance, "itemSlotNumbers", preferParent: true); AddHudFieldTargets(instance, "inventorySlotIcons", preferParent: true); AddHudFieldTargets(instance, "HUDContainer"); if (instance.controlTipLines != null) { for (int i = 0; i < instance.controlTipLines.Length; i++) { AddFocusHudDimTarget((Component)(object)instance.controlTipLines[i], preferParent: false); } } } _hudScanFieldsMs = HudScanStepMs(ref lastAt); EntryPerfMark("HudScan.hud-fields"); AddHudCanvasSiblingTargets(instance); _hudScanCanvasSiblingsMs = HudScanStepMs(ref lastAt); EntryPerfMark("HudScan.canvas-siblings"); PlayerControllerB val = (((Object)(object)_focusedPlayer != (Object)null) ? _focusedPlayer : (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null)); if ((Object)(object)val != (Object)null) { AddFocusHudDimTarget((Component)(object)val.cursorTip, preferParent: false); AddFocusHudDimTarget((Component)(object)val.cursorIcon, preferParent: false); } _hudScanCursorMs = HudScanStepMs(ref lastAt); EntryPerfMark("HudScan.cursor"); if (includeSceneScans) { AddY4ngzPromptOverlayTargets(); _hudScanPromptsMs = HudScanStepMs(ref lastAt); EntryPerfMark("HudScan.prompt-overlays"); AddNamedHudChromeTargets(instance); _hudScanNamedChromeMs = HudScanStepMs(ref lastAt); EntryPerfMark("HudScan.named-chrome"); AddScreenSpaceHudOverlayTargets(); _hudScanScreenSpaceMs = HudScanStepMs(ref lastAt); EntryPerfMark("HudScan.screen-space"); } } private static void AddHudCanvasSiblingTargets(HUDManager hud) { if ((Object)(object)hud == (Object)null) { return; } Transform val = ResolveHudTransform(hud, "HUDContainer"); Transform val2 = (((Object)(object)val != (Object)null && (Object)(object)val.parent != (Object)null) ? val.parent : (((Object)(object)hud.playerScreenTexture != (Object)null && (Object)(object)((Graphic)hud.playerScreenTexture).canvas != (Object)null) ? ((Component)((Graphic)hud.playerScreenTexture).canvas).transform : null)); if (!((Object)(object)val2 == (Object)null)) { int childCount = val2.childCount; for (int i = 0; i < childCount; i++) { AddFocusHudDimTarget(val2.GetChild(i), preferParent: false); } } } private static void AddHudFieldTargets(HUDManager hud, string fieldName, bool preferParent = false) { if ((Object)(object)hud == (Object)null || string.IsNullOrEmpty(fieldName)) { return; } try { FieldInfo field = ((object)hud).GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { AddFocusHudDimValue(field.GetValue(hud), preferParent); return; } PropertyInfo property = ((object)hud).GetType().GetProperty(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.GetIndexParameters().Length == 0) { AddFocusHudDimValue(property.GetValue(hud), preferParent); } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Focus HUD dim field '" + fieldName + "' skipped: " + ex.Message)); } } } private static void AddFocusHudDimValue(object value, bool preferParent) { if (value == null) { return; } Component val = (Component)((value is Component) ? value : null); if (val != null) { AddFocusHudDimTarget(val, preferParent); return; } GameObject val2 = (GameObject)((value is GameObject) ? value : null); if (val2 != null) { AddFocusHudDimTarget(val2.transform, preferParent); } else { if (!(value is IEnumerable enumerable) || value is string) { return; } foreach (object item in enumerable) { AddFocusHudDimValue(item, preferParent); } } } private static void AddY4ngzPromptOverlayTargets() { try { Canvas[] array = Resources.FindObjectsOfTypeAll(); foreach (Canvas val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null) && ((Component)val).gameObject.activeInHierarchy && ((Object)((Component)val).gameObject).name.IndexOf("Y4NGZInteractive_PromptOverlayCanvas", StringComparison.OrdinalIgnoreCase) >= 0) { AddFocusHudDimTarget(((Component)val).transform, preferParent: false); } } TextMeshProUGUI[] array2 = Resources.FindObjectsOfTypeAll(); foreach (TextMeshProUGUI val2 in array2) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Component)val2).gameObject == (Object)null) && ((Component)val2).gameObject.activeInHierarchy) { Transform val3 = FindNamedAncestor(((TMP_Text)val2).transform, "Y4NGZInteractive_PromptOverlayCanvas"); if ((Object)(object)val3 != (Object)null) { AddFocusHudDimTarget(val3, preferParent: false); } } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Focus HUD prompt dim scan skipped: " + ex.Message)); } } } private static void AddNamedHudChromeTargets(HUDManager hud) { if (!((Object)(object)hud == (Object)null)) { AddNamedHudChromeTargetsUnder(ResolveHudTransform(hud, "HUDContainer")); AddNamedHudChromeTargetsUnder(((Object)(object)hud.playerScreenTexture != (Object)null && (Object)(object)((Graphic)hud.playerScreenTexture).canvas != (Object)null) ? ((Component)((Graphic)hud.playerScreenTexture).canvas).transform : null); } } private static void AddNamedHudChromeTargetsUnder(Transform root) { if ((Object)(object)root == (Object)null) { return; } try { Graphic[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Graphic val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null)) { Transform transform = ((Component)val).transform; if (!((Object)(object)transform == (Object)null) && !ShouldSkipFocusHudDimTarget(transform) && ContainsFocusHudNameToken(BuildTransformPath(transform))) { AddFocusHudDimTarget(transform, preferParent: false); } } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Focus HUD named chrome scan skipped: " + ex.Message)); } } } private static void AddScreenSpaceHudOverlayTargets() { //IL_0033: 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_0041: Invalid comparison between Unknown and I4 try { Canvas[] array = Resources.FindObjectsOfTypeAll(); foreach (Canvas val in array) { if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null || !((Component)val).gameObject.activeInHierarchy || ((int)val.renderMode != 0 && (int)val.renderMode != 1)) { continue; } Transform transform = ((Component)val).transform; if (!ShouldSkipFocusHudDimTarget(transform)) { AddFocusHudDimTarget(transform, preferParent: false); continue; } Graphic[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren.Length; j++) { AddFocusHudGraphicTarget(componentsInChildren[j]); } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Focus HUD screen-space scan skipped: " + ex.Message)); } } } private static Transform ResolveHudTransform(HUDManager hud, string fieldName) { if ((Object)(object)hud == (Object)null || string.IsNullOrEmpty(fieldName)) { return null; } try { FieldInfo field = ((object)hud).GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); object obj = ((field != null) ? field.GetValue(hud) : null); if (obj == null) { PropertyInfo property = ((object)hud).GetType().GetProperty(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.GetIndexParameters().Length == 0) { obj = property.GetValue(hud); } } Transform val = (Transform)((obj is Transform) ? obj : null); if (val != null) { return val; } Component val2 = (Component)((obj is Component) ? obj : null); if (val2 != null) { return val2.transform; } GameObject val3 = (GameObject)((obj is GameObject) ? obj : null); if (val3 != null) { return val3.transform; } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Focus HUD transform '" + fieldName + "' skipped: " + ex.Message)); } } return null; } private static string BuildTransformPath(Transform transform) { if ((Object)(object)transform == (Object)null) { return string.Empty; } string text = ((Object)transform).name ?? string.Empty; Transform parent = transform.parent; while ((Object)(object)parent != (Object)null) { text = (((Object)parent).name ?? string.Empty) + "/" + text; parent = parent.parent; } return text; } private static bool ContainsFocusHudNameToken(string hierarchy) { if (string.IsNullOrEmpty(hierarchy)) { return false; } for (int i = 0; i < FocusHudNameTokens.Length; i++) { if (hierarchy.IndexOf(FocusHudNameTokens[i], StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } private static Transform FindNamedAncestor(Transform transform, string nameToken) { Transform val = transform; while ((Object)(object)val != (Object)null) { if ((((Object)(object)((Component)val).gameObject != (Object)null) ? ((Object)((Component)val).gameObject).name : string.Empty).IndexOf(nameToken, StringComparison.OrdinalIgnoreCase) >= 0) { return val; } val = val.parent; } return null; } private static void AddFocusHudDimTarget(Component component, bool preferParent) { if (!((Object)(object)component == (Object)null)) { AddFocusHudDimTarget(component.transform, preferParent); } } private static void AddFocusHudDimTarget(Transform transform, bool preferParent) { if ((Object)(object)transform == (Object)null) { return; } Transform val = ((preferParent && (Object)(object)transform.parent != (Object)null) ? transform.parent : transform); if (WouldDimPlayerScreenTexture(val) && !WouldDimPlayerScreenTexture(transform)) { val = transform; } if (ShouldSkipFocusHudDimTarget(val) || HasRegisteredFocusHudAncestor(val)) { return; } CanvasGroup val2 = ((Component)val).GetComponent(); bool addedByUs = false; if ((Object)(object)val2 == (Object)null) { val2 = ((Component)val).gameObject.AddComponent(); addedByUs = true; } if (!((Object)(object)val2 == (Object)null)) { int instanceID = ((Object)val2).GetInstanceID(); if (_focusHudDimTargetIds.Add(instanceID)) { _focusHudDimTargets.Add(new FocusHudDimTarget { Group = val2, OriginalAlpha = val2.alpha, InstanceId = instanceID, AddedByUs = addedByUs }); } } } private static void AddFocusHudGraphicTarget(Graphic graphic) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)graphic == (Object)null || (Object)(object)((Component)graphic).gameObject == (Object)null) { return; } Transform transform = ((Component)graphic).transform; if (!ShouldSkipFocusHudDimTarget(transform) && !HasRegisteredFocusHudAncestor(transform)) { int instanceID = ((Object)graphic).GetInstanceID(); if (_focusHudGraphicTargetIds.Add(instanceID)) { _focusHudGraphicTargets.Add(new FocusHudGraphicTarget { Graphic = graphic, OriginalAlpha = graphic.color.a, InstanceId = instanceID }); } } } private static bool HasRegisteredFocusHudAncestor(Transform transform) { if ((Object)(object)transform == (Object)null) { return true; } for (int i = 0; i < _focusHudDimTargets.Count; i++) { CanvasGroup val = _focusHudDimTargets[i]?.Group; if (!((Object)(object)val == (Object)null)) { Transform transform2 = ((Component)val).transform; if ((Object)(object)transform2 != (Object)null && (Object)(object)transform != (Object)(object)transform2 && transform.IsChildOf(transform2)) { return true; } } } return false; } private static bool ShouldSkipFocusHudDimTarget(Transform transform) { if ((Object)(object)transform == (Object)null || (Object)(object)((Component)transform).gameObject == (Object)null) { return true; } if ((Object)(object)_overlayRoot != (Object)null) { Transform transform2 = _overlayRoot.transform; if (WouldDimProtectedTransform(transform, transform2)) { return true; } } Transform rootTransform = CCTVFocusControlsOverlay.RootTransform; if (WouldDimProtectedTransform(transform, rootTransform)) { return true; } return WouldDimPlayerScreenTexture(transform); } private static bool WouldDimProtectedTransform(Transform candidate, Transform protectedRoot) { if ((Object)(object)candidate == (Object)null || (Object)(object)protectedRoot == (Object)null) { return false; } if (!((Object)(object)candidate == (Object)(object)protectedRoot) && !candidate.IsChildOf(protectedRoot)) { return protectedRoot.IsChildOf(candidate); } return true; } private static bool WouldDimPlayerScreenTexture(Transform transform) { if ((Object)(object)transform == (Object)null) { return false; } HUDManager instance = HUDManager.Instance; Transform val = (((Object)(object)instance != (Object)null && (Object)(object)instance.playerScreenTexture != (Object)null) ? ((Component)instance.playerScreenTexture).transform : null); if ((Object)(object)val != (Object)null) { if (!((Object)(object)transform == (Object)(object)val) && !val.IsChildOf(transform)) { return transform.IsChildOf(val); } return true; } return false; } private static void ApplyStoredFocusHudDimTargets() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) for (int num = _focusHudGraphicTargets.Count - 1; num >= 0; num--) { FocusHudGraphicTarget focusHudGraphicTarget = _focusHudGraphicTargets[num]; Graphic val = focusHudGraphicTarget?.Graphic; if ((Object)(object)val == (Object)null) { if (focusHudGraphicTarget != null) { _focusHudGraphicTargetIds.Remove(focusHudGraphicTarget.InstanceId); } _focusHudGraphicTargets.RemoveAt(num); } else { float num2 = Mathf.Clamp01(focusHudGraphicTarget.OriginalAlpha * 0.01f); Color color = val.color; if (color.a > num2) { color.a = num2; val.color = color; } } } for (int num3 = _focusHudDimTargets.Count - 1; num3 >= 0; num3--) { FocusHudDimTarget focusHudDimTarget = _focusHudDimTargets[num3]; if ((Object)(object)focusHudDimTarget?.Group == (Object)null) { if (focusHudDimTarget != null) { _focusHudDimTargetIds.Remove(focusHudDimTarget.InstanceId); } _focusHudDimTargets.RemoveAt(num3); } else { float num4 = Mathf.Clamp01(focusHudDimTarget.OriginalAlpha * 0.01f); if (focusHudDimTarget.AddedByUs || focusHudDimTarget.Group.alpha > num4) { focusHudDimTarget.Group.alpha = num4; } } } } private static void RestoreFocusHudDimming() { //IL_0047: 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_005b: Unknown result type (might be due to invalid IL or missing references) if (!_focusHudDimActive) { return; } if (_focusHudGraphicTargets.Count > 0) { for (int num = _focusHudGraphicTargets.Count - 1; num >= 0; num--) { FocusHudGraphicTarget focusHudGraphicTarget = _focusHudGraphicTargets[num]; Graphic val = focusHudGraphicTarget?.Graphic; if (!((Object)(object)val == (Object)null)) { Color color = val.color; color.a = focusHudGraphicTarget.OriginalAlpha; val.color = color; } } } if (_focusHudDimTargets.Count > 0) { for (int num2 = _focusHudDimTargets.Count - 1; num2 >= 0; num2--) { FocusHudDimTarget focusHudDimTarget = _focusHudDimTargets[num2]; CanvasGroup val2 = focusHudDimTarget?.Group; if (!((Object)(object)val2 == (Object)null)) { if (focusHudDimTarget.AddedByUs) { Object.Destroy((Object)(object)val2); } else { val2.alpha = focusHudDimTarget.OriginalAlpha; } } } } _focusHudDimTargets.Clear(); _focusHudDimTargetIds.Clear(); _focusHudGraphicTargets.Clear(); _focusHudGraphicTargetIds.Clear(); _nextFocusHudDimRefreshAt = 0f; _focusHudDimActive = false; _focusHudSceneScanCompleted = false; _focusHudScanRearmAt = Time.unscaledTime + 1f; } private static void TickFocusHudScanRearm() { if (!(_focusHudScanRearmAt <= 0f) && !(Time.unscaledTime < _focusHudScanRearmAt)) { _focusHudScanRearmAt = 0f; PrewarmFocusHudScan(); } } internal static bool IsWalkiePushToTalkHeld() { if (!InputBindingsUnavailable) { InputAction val = TryGetWalkiePushToTalkAction(); if (val != null) { return val.IsPressed(); } } Keyboard current = Keyboard.current; if (current != null) { return ((ButtonControl)current.vKey).isPressed; } return false; } private static void OnCycleActivePrevPerformed(CallbackContext _) { if (!IsFocused || IsStationEditInputActive()) { return; } if (IsHackingOverlayOpen) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV][CCTVHackTerminal] Focus action LEFT received."); } _hackingOverlay.NavigateLeft("action-left"); } else if (IsMainframeOverlayOpen) { _mainframeOverlay.NavigateLeft("action-left"); } else if (!_placementEditorOpen && !_reviewMenuOpen) { NavigateHorizontal(-1); } } private static void OnCameraPreCull(Camera camera) { if (IsFocused && !_isExitingFocus && !_focusViewExitPending && !_focusViewAnimating && !_stationThirdPersonPreviewActive && !((Object)(object)_physicalFocusCamera == (Object)null) && !((Object)(object)_physicalFocusCameraTransform == (Object)null) && !((Object)(object)camera != (Object)(object)_physicalFocusCamera)) { ApplyStationPhysicalFocusView(); } } private static void OnCycleActiveNextPerformed(CallbackContext _) { if (!IsFocused || IsStationEditInputActive()) { return; } if (IsHackingOverlayOpen) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV][CCTVHackTerminal] Focus action RIGHT received."); } _hackingOverlay.NavigateRight("action-right"); } else if (IsMainframeOverlayOpen) { _mainframeOverlay.NavigateRight("action-right"); } else if (!_placementEditorOpen && !_reviewMenuOpen) { NavigateHorizontal(1); } } private static void OnPagePrevPerformed(CallbackContext _) { if (!IsFocused || IsStationEditInputActive()) { return; } if (IsHackingOverlayOpen) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV][CCTVHackTerminal] Focus action UP received."); } _hackingOverlay.NavigateUp("action-up"); } else if (IsMainframeOverlayOpen) { _mainframeOverlay.NavigateUp("action-up"); } else if (!_placementEditorOpen && !_reviewMenuOpen) { NavigateVertical(-1); } } private static void OnPageNextPerformed(CallbackContext _) { if (!IsFocused || IsStationEditInputActive()) { return; } if (IsHackingOverlayOpen) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV][CCTVHackTerminal] Focus action DOWN received."); } _hackingOverlay.NavigateDown("action-down"); } else if (IsMainframeOverlayOpen) { _mainframeOverlay.NavigateDown("action-down"); } else if (!_placementEditorOpen && !_reviewMenuOpen) { NavigateVertical(1); } } private static void OnHackSubmitPerformed(CallbackContext _) { if (!IsFocused || IsStationEditInputActive()) { return; } if (IsMainframeOverlayOpen) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV][MainframeControl] Focus action ENTER received."); } PlayInteractSfx(); _mainframeOverlay.Submit("action-enter"); } else if (IsHackingOverlayOpen) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)"[LethalCCTV][CCTVHackTerminal] Focus action ENTER received."); } PlayInteractSfx(); _hackingOverlay.Submit("action-enter"); } } private static void OnPingMarkerPerformed(CallbackContext _) { if (IsFocused && !IsStationEditInputActive() && !_placementEditorOpen && !_reviewMenuOpen && !IsHackingOverlayOpen) { if (IsTurretPageActive) { ResetStationRadarLookView(); CCTVStationEvents.RaiseActionButtonPressed("turret-fire"); ShipTurretController.TryFire(); } else { ResetStationRadarLookView(); CCTVStationEvents.RaiseActionButtonPressed("station-action"); PlayInteractSfx(); TriggerCameraPing(); } } } private static void OnWalkiePushToTalkPerformed(CallbackContext _) { if (IsFocused && !IsStationEditInputActive()) { if (IsMainframeOverlayOpen) { _mainframeOverlay.SetPushToTalk(held: true); RefreshOperatorStats(force: true); } else if (!_placementEditorOpen && !_reviewMenuOpen && !IsHackingOverlayOpen) { CCTVWalkieTalkieBridge.SetLocalSpeaking(speaking: true); RefreshOperatorStats(force: true); } } } private static void OnWalkiePushToTalkCanceled(CallbackContext _) { if (IsMainframeOverlayOpen) { _mainframeOverlay.SetPushToTalk(held: false); RefreshOperatorStats(force: true); } else { CCTVWalkieTalkieBridge.SetLocalSpeaking(speaking: false); RefreshOperatorStats(force: true); } } private static void OnToggleControlsOverlayPerformed(CallbackContext _) { if (!IsFocused || !IsOperatorDebugToolsEnabled || IsStationEditInputActive() || IsHackingOverlayOpen || IsMainframeOverlayOpen || _placementEditorOpen || _reviewMenuOpen) { return; } ConfigEntry val = SurveillanceBootstrap.Config?.ShowOperatorControlsOverlay; if (val != null) { val.Value = !val.Value; PlayInteractSfx(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Operator controls overlay toggled " + (val.Value ? "on" : "off") + " by keybind.")); } } } private static void NavigateHorizontal(int delta) { NavigateSingleCamera(delta); } private static void PlayPageChangeSfxIfPageChanged(int previousPage) { if (IsFocused && QuadCameraAssignment.CurrentPage != previousPage) { PlayPageSfx(); CCTVStationEvents.RaiseActionButtonPressed("camera-page"); CCTVStationEvents.RaiseCameraSelected(ActiveSlot); } } private static void NavigateVertical(int delta) { NavigateSingleCamera(delta); } private static void LeaveTurretPage(bool forward) { int totalPages = QuadCameraAssignment.TotalPages; if (totalPages > 0) { QuadCameraAssignment.GoToPage((!forward) ? (totalPages - 1) : 0); ActiveSlot = ((!forward) ? 3 : 0); SetTurretPageActive(active: false); SetActiveSlot(ActiveSlot); PlayPageSfx(); CCTVStationEvents.RaiseActionButtonPressed("camera-page"); } } private static void SetTurretPageActive(bool active) { bool flag = active && ShipTurretController.IsUnlocked; if (_turretPageActive == flag) { RefreshTurretFocusPage(); RefreshFocusDockLayout(); UpdatePageIndicator(QuadCameraAssignment.CurrentPage, QuadCameraAssignment.TotalPages); return; } _turretPageActive = flag; if (_turretPageActive) { ActiveSlot = 0; CCTVMonitorFeedSync.NotifyLocalActiveSlotChanged(ActiveSlot); } if (IsFocused) { CCTVStationEvents.RaiseActionButtonPressed("camera-page"); } HideCameraScanOverlay(); ApplyActivePaneLayout(); RefreshTurretFocusPage(); RefreshFocusDockLayout(); UpdatePageIndicator(QuadCameraAssignment.CurrentPage, QuadCameraAssignment.TotalPages); PaneHighlight.SetActive(ActiveSlot); SyncCameraAudioProxy(); UpdateActivePaneReticle(); RefreshOperatorStats(force: true); if (!_turretPageActive) { QuadCameraAssignment.WakeRender(); } } private static void SetActiveSlot(int slot) { int activeSlot = ActiveSlot; ActiveSlot = 0; PaneHighlight.SetActive(ActiveSlot); ApplyActivePaneLayout(); HideCameraScanOverlay(); UpdateActivePaneReticle(); SyncCameraAudioProxy(); ApplyZoomToActiveCamera(); if (IsFocused && activeSlot != ActiveSlot) { PlaySwitchCameraSfx(); QuadCameraAssignment.RequestWakeAllSlots(); CCTVStationEvents.RaiseCameraSelected(ActiveSlot); } CCTVMonitorFeedSync.NotifyLocalActiveSlotChanged(ActiveSlot); } private static void NavigateSingleCamera(int delta) { if (IsTurretPageActive) { LeaveTurretPage(delta >= 0); return; } int totalPages = QuadCameraAssignment.TotalPages; if (ShipTurretController.IsUnlocked && totalPages > 0) { bool flag = QuadCameraAssignment.CurrentPage <= 0; bool flag2 = QuadCameraAssignment.CurrentPage >= totalPages - 1; if (delta < 0 && flag) { SetTurretPageActive(active: true); return; } if (delta > 0 && flag2) { SetTurretPageActive(active: true); return; } } int currentPage = QuadCameraAssignment.CurrentPage; QuadCameraAssignment.GoToPage(QuadCameraAssignment.CurrentPage + delta); SetActiveSlot(0); BoostStationCameraRenderCadence(0.25f); PlayPageChangeSfxIfPageChanged(currentPage); if (IsFocused && QuadCameraAssignment.CurrentPage != currentPage) { QuadCameraAssignment.RequestWakeAllSlots(); SyncCameraAudioProxy(); UpdateActivePaneReticle(); RefreshOperatorStats(force: true); } } internal static void UpdateCameraLabel(int slot, string labelText) { if (_overlayCameraLabels == null || slot < 0 || slot >= _overlayCameraLabels.Length) { return; } TextMeshProUGUI val = _overlayCameraLabels[slot]; Image val2 = ((_overlayCameraLabelBackgrounds != null && slot < _overlayCameraLabelBackgrounds.Length) ? _overlayCameraLabelBackgrounds[slot] : null); if ((Object)(object)val == (Object)null) { return; } if (!string.IsNullOrEmpty(labelText)) { ((TMP_Text)val).text = labelText; ((Behaviour)val).enabled = true; if ((Object)(object)val2 != (Object)null) { ((Behaviour)val2).enabled = true; } } else { ((TMP_Text)val).text = "CAM_--"; ((Behaviour)val).enabled = false; if ((Object)(object)val2 != (Object)null) { ((Behaviour)val2).enabled = false; } } UpdateActiveSlotLabel(ActiveSlot); } internal static void UpdatePageIndicator(int currentPageZeroIndexed, int totalPages) { if (!((Object)(object)_overlayPageText == (Object)null)) { if (ShipTurretController.IsUnlocked) { int num = Mathf.Max(1, totalPages + 1); ((TMP_Text)_overlayPageText).text = (IsTurretPageActive ? $"PAGE 1/{num} // TURRET" : $"PAGE {Mathf.Clamp(currentPageZeroIndexed + 2, 2, num)}/{num}"); } else { ((TMP_Text)_overlayPageText).text = ((totalPages > 0) ? $"PAGE {currentPageZeroIndexed + 1}/{totalPages}" : "NO CAMERAS"); } } } internal static void UpdateActiveSlotLabel(int activeSlot) { //IL_0028: 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) if (_overlayCameraLabels != null) { for (int i = 0; i < _overlayCameraLabels.Length; i++) { TextMeshProUGUI val = _overlayCameraLabels[i]; if (!((Object)(object)val == (Object)null)) { ((Graphic)val).color = ((i == activeSlot) ? OVERLAY_ACTIVE_GREEN : Color.white); } } } if ((Object)(object)_overlayActiveText != (Object)null) { if (IsTurretPageActive) { ((TMP_Text)_overlayActiveText).text = "ACTIVE TURRET"; } else if (OpenBodyCamsCompat.IsFocusSlot(activeSlot) && OpenBodyCamsCompat.ShouldShowFocusSlot()) { ((TMP_Text)_overlayActiveText).text = "ACTIVE BODYCAM"; } else { CCTVCamera boundCamera = QuadCameraAssignment.GetBoundCamera(activeSlot); ((TMP_Text)_overlayActiveText).text = (((Object)(object)boundCamera != (Object)null) ? ("ACTIVE " + boundCamera.ResolvedLabel) : "ACTIVE EMPTY"); } } RadarOverlay.UpdateHighlights(); UpdateActivePaneReticle(); SyncCameraAudioProxy(); } private static void RefreshBodycamFocusSlot() { if ((Object)(object)_overlayRoot == (Object)null || !_overlayRoot.activeInHierarchy || !OpenBodyCamsCompat.IsLoaded || _overlayRawImages == null) { return; } int num = 3; if (num < 0 || num >= _overlayRawImages.Length) { return; } RawImage val = _overlayRawImages[num]; if (!((Object)(object)val == (Object)null)) { if (OpenBodyCamsCompat.TryGetFocusTexture(out var texture)) { val.texture = texture; UpdateCameraLabel(num, "BODYCAM"); } else { val.texture = QuadMonitor.GetCurrentDisplayTexture(num); CCTVCamera boundCamera = QuadCameraAssignment.GetBoundCamera(num); UpdateCameraLabel(num, ((Object)(object)boundCamera != (Object)null) ? boundCamera.ResolvedLabel : null); } } } private static void RefreshTurretFocusPage() { if ((Object)(object)_overlayRoot == (Object)null || !_overlayRoot.activeInHierarchy || _overlayRawImages == null) { return; } if (!IsTurretPageActive) { for (int i = 0; i < _overlayRawImages.Length; i++) { if ((Object)(object)_overlayRawImages[i] != (Object)null && !((Component)_overlayRawImages[i]).gameObject.activeSelf) { ((Component)_overlayRawImages[i]).gameObject.SetActive(true); } if (OverlayOutlines != null && i < OverlayOutlines.Length && (Object)(object)OverlayOutlines[i] != (Object)null && !((Component)OverlayOutlines[i]).gameObject.activeSelf) { ((Component)OverlayOutlines[i]).gameObject.SetActive(true); } if (_overlayCameraLabelBackgrounds != null && i < _overlayCameraLabelBackgrounds.Length && (Object)(object)_overlayCameraLabelBackgrounds[i] != (Object)null && !((Component)_overlayCameraLabelBackgrounds[i]).gameObject.activeSelf) { ((Component)_overlayCameraLabelBackgrounds[i]).gameObject.SetActive(true); } Texture currentDisplayTexture = QuadMonitor.GetCurrentDisplayTexture(i); if ((Object)(object)_overlayRawImages[i] != (Object)null && (Object)(object)currentDisplayTexture != (Object)null) { _overlayRawImages[i].texture = currentDisplayTexture; } if (!OpenBodyCamsCompat.IsFocusSlot(i)) { CCTVCamera boundCamera = QuadCameraAssignment.GetBoundCamera(i); UpdateCameraLabel(i, ((Object)(object)boundCamera != (Object)null) ? boundCamera.ResolvedLabel : null); } } return; } for (int j = 0; j < _overlayRawImages.Length; j++) { bool active = j == 0; if ((Object)(object)_overlayRawImages[j] != (Object)null) { ((Component)_overlayRawImages[j]).gameObject.SetActive(active); } if (OverlayOutlines != null && j < OverlayOutlines.Length && (Object)(object)OverlayOutlines[j] != (Object)null) { ((Component)OverlayOutlines[j]).gameObject.SetActive(active); } if (_overlayCameraLabelBackgrounds != null && j < _overlayCameraLabelBackgrounds.Length && (Object)(object)_overlayCameraLabelBackgrounds[j] != (Object)null) { ((Component)_overlayCameraLabelBackgrounds[j]).gameObject.SetActive(active); } } if ((Object)(object)_overlayRawImages[0] != (Object)null) { _overlayRawImages[0].texture = (Texture)(((object)ShipTurretController.ViewTexture) ?? ((object)Texture2D.blackTexture)); } UpdateCameraLabel(0, "TURRET"); } private static void TickStationRadarZoomInput() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (IsStationEditInputActive() || !IsStationRadarLookHeld() || CCTVOperatorStation.IsDebugPlacementActive) { return; } Mouse current = Mouse.current; if (current != null) { float y = ((InputControl)(object)current.scroll).ReadValue().y; if (!(Mathf.Abs(y) < 0.01f)) { VanillaRadarFeed.AdjustZoom(y / 120f); } } } private static bool TryBindInputActions() { try { BindInputActionsCore(); InputBindingsUnavailable = false; return true; } catch (Exception arg) { InputBindingsUnavailable = true; _inputActions = null; string text = DependencyVersionAudit.DescribeOutdated("com.rune580.LethalCompanyInputUtils") ?? "the installed LethalCompanyInputUtils does not provide the key bindings this build was compiled against"; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogError((object)("[LethalCCTV] CCTV monitor keyboard controls are disabled: " + text + ". Update it in your mod manager; another installed mod may be pinning an old version (e.g. LethalPhones pins LethalLib 0.16.2 / InputUtils 0.6.3). The monitor itself still works, but exiting with E/Escape, pane cycling, paging, hack entry, marker pings, the walkie key and the controls overlay will not respond. " + $"Underlying error: {arg}")); } return false; } } private static void UnbindInputActions() { if (_inputActions == null) { return; } try { UnbindInputActionsCore(); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Failed to unbind CCTV monitor keyboard controls: " + ex.Message)); } } _inputActions = null; } [MethodImpl(MethodImplOptions.NoInlining)] private static void UnbindInputActionsCore() { _inputActions.ExitFocusKeyE.performed -= OnExitFocusPerformed; _inputActions.ExitFocusKeyEscape.performed -= OnExitFocusPerformed; _inputActions.CycleActivePrev.performed -= OnCycleActivePrevPerformed; _inputActions.CycleActiveNext.performed -= OnCycleActiveNextPerformed; _inputActions.PagePrev.performed -= OnPagePrevPerformed; _inputActions.PageNext.performed -= OnPageNextPerformed; _inputActions.HackSubmitEnter.performed -= OnHackSubmitPerformed; _inputActions.HackSubmitNumpadEnter.performed -= OnHackSubmitPerformed; _inputActions.PingMarker.performed -= OnPingMarkerPerformed; _inputActions.WalkiePushToTalk.performed -= OnWalkiePushToTalkPerformed; _inputActions.WalkiePushToTalk.canceled -= OnWalkiePushToTalkCanceled; _inputActions.ToggleControlsOverlayKey.performed -= OnToggleControlsOverlayPerformed; } [MethodImpl(MethodImplOptions.NoInlining)] private static InputAction TryGetWalkiePushToTalkAction() { return _inputActions?.WalkiePushToTalk; } [MethodImpl(MethodImplOptions.NoInlining)] private static void BindInputActionsCore() { _inputActions = new LethalCCTVInputActions(); _inputActions.ExitFocusKeyE.performed += OnExitFocusPerformed; _inputActions.ExitFocusKeyEscape.performed += OnExitFocusPerformed; _inputActions.CycleActivePrev.performed += OnCycleActivePrevPerformed; _inputActions.CycleActiveNext.performed += OnCycleActiveNextPerformed; _inputActions.PagePrev.performed += OnPagePrevPerformed; _inputActions.PageNext.performed += OnPageNextPerformed; _inputActions.HackSubmitEnter.performed += OnHackSubmitPerformed; _inputActions.HackSubmitNumpadEnter.performed += OnHackSubmitPerformed; _inputActions.PingMarker.performed += OnPingMarkerPerformed; _inputActions.WalkiePushToTalk.performed += OnWalkiePushToTalkPerformed; _inputActions.WalkiePushToTalk.canceled += OnWalkiePushToTalkCanceled; _inputActions.ToggleControlsOverlayKey.performed += OnToggleControlsOverlayPerformed; } internal static void Initialize() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Expected O, but got Unknown //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_044b: Expected O, but got Unknown //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0489: Expected O, but got Unknown //IL_046f: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_047a: Expected O, but got Unknown SurveillanceBootstrap.Log.LogInfo((object)"[LethalCCTV] MonitorFocus.Initialize: starting."); if ((Object)(object)_overlayRoot != (Object)null) { SurveillanceBootstrap.Log.LogInfo((object)"[LethalCCTV] MonitorFocus.Initialize: already initialized — skipping."); return; } try { _overlayRoot = new GameObject("LethalCCTV_PhysicalFocusOverlay", new Type[1] { typeof(RectTransform) }); if ((Object)(object)SurveillanceBootstrap.Instance != (Object)null) { _overlayRoot.transform.SetParent(((Component)SurveillanceBootstrap.Instance).transform, false); } else { Object.DontDestroyOnLoad((Object)(object)_overlayRoot); SurveillanceBootstrap.Log.LogWarning((object)"[LethalCCTV] MonitorFocus.Initialize: SurveillanceBootstrap.Instance null — fell back to self-DDOL."); } ManualLogSource log = SurveillanceBootstrap.Log; string[] obj = new string[5] { "[LethalCCTV] MonitorFocus.Initialize: overlay parent='", ((Object)(object)_overlayRoot.transform.parent != (Object)null) ? ((Object)_overlayRoot.transform.parent).name : "", "' scene='", null, null }; Scene scene = _overlayRoot.scene; obj[3] = ((Scene)(ref scene)).name; obj[4] = "'."; log.LogInfo((object)string.Concat(obj)); EnsurePhysicalFocusRenderRig(); if ((Object)(object)_physicalFocusRenderRigRoot != (Object)null) { _overlayRoot.transform.SetParent(_physicalFocusRenderRigRoot.transform, false); SurveillanceBootstrap.Log.LogInfo((object)$"[LethalCCTV] MonitorFocus.Initialize: physical overlay parent='{((Object)_overlayRoot.transform.parent).name}' renderTexture={1920}x{1440}."); } Canvas obj2 = _overlayRoot.AddComponent(); obj2.renderMode = (RenderMode)2; obj2.worldCamera = _physicalFocusUiCamera; obj2.sortingOrder = 0; RectTransform component = _overlayRoot.GetComponent(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(960f, 720f); ((Transform)component).localPosition = Vector3.zero; ((Transform)component).localRotation = Quaternion.identity; ((Transform)component).localScale = Vector3.one; CanvasScaler obj3 = _overlayRoot.AddComponent(); obj3.uiScaleMode = (ScaleMode)0; obj3.scaleFactor = 1f; CreateOverlayBackground(_overlayRoot.transform); CreateOverlayWorkstationBackplate(_overlayRoot.transform); _overlayRawImages = (RawImage[])(object)new RawImage[4]; _overlayPaneRects = (RectTransform[])(object)new RectTransform[4]; _overlayOutlineRects = (RectTransform[])(object)new RectTransform[4]; _overlayPaneFrames = new PaneFrame[4]; Image[] array = (Image[])(object)new Image[4]; _overlayCameraLabels = (TextMeshProUGUI[])(object)new TextMeshProUGUI[4]; _overlayCameraLabelBackgrounds = (Image[])(object)new Image[4]; _overlayCameraLabelRects = (RectTransform[])(object)new RectTransform[4]; for (int i = 0; i < 4; i++) { _overlayRawImages[i] = CreateOverlayQuadrant(_overlayRoot.transform, i); array[i] = CreateOverlayOutline(_overlayRoot.transform, i); _overlayCameraLabelBackgrounds[i] = CreateOverlayCameraLabel(_overlayRoot.transform, i, out _overlayCameraLabels[i]); } OverlayOutlines = array; CctvScreenOutlineOverlay.Initialize(_overlayRoot.transform); for (int j = 0; j < _overlayCameraLabelBackgrounds.Length; j++) { if ((Object)(object)_overlayCameraLabelBackgrounds[j] != (Object)null) { ((Component)_overlayCameraLabelBackgrounds[j]).transform.SetAsLastSibling(); } } CreateOverlayChrome(_overlayRoot.transform); CreateSignalLogPanel(_overlayRoot.transform); CreateRadarInset(_overlayRoot.transform); CreateOperatorStatsPanel(_overlayRoot.transform); CreateCameraScanOverlay(_overlayRoot.transform); CreateCameraReviewMenu(_overlayRoot.transform); CreatePlacementEditorMenu(_overlayRoot.transform); CreateActivePaneReticle(_overlayRoot.transform); EnsureFocusSfx(); EnsureProvidedFocusAudioLoading(); EnsureFocusMachineLoopSource(); EnsureCameraAudioProxy(); _hackingOverlay = new HackingOverlay(_overlayRoot.transform); _hackingOverlay.EnsureBuilt(); _mainframeOverlay = new MainframeControlOverlay(_overlayRoot.transform); _mainframeOverlay.EnsureBuilt(); CctvOutlineManager.Initialize(); SetLayerRecursive(_overlayRoot, 29); _overlayRoot.SetActive(false); TryBindInputActions(); FocusMouselook.Initialize(); CameraCallback onPreCull = Camera.onPreCull; object obj4 = <>O.<10>__OnCameraPreCull; if (obj4 == null) { CameraCallback val = OnCameraPreCull; <>O.<10>__OnCameraPreCull = val; obj4 = (object)val; } Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)onPreCull, (Delegate?)obj4); CameraCallback onPreCull2 = Camera.onPreCull; object obj5 = <>O.<10>__OnCameraPreCull; if (obj5 == null) { CameraCallback val2 = OnCameraPreCull; <>O.<10>__OnCameraPreCull = val2; obj5 = (object)val2; } Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)onPreCull2, (Delegate?)obj5); SurveillanceBootstrap.Log.LogInfo((object)"[LethalCCTV] MonitorFocus initialized."); } catch (Exception arg) { SurveillanceBootstrap.Log.LogError((object)$"[LethalCCTV] MonitorFocus.Initialize threw: {arg}"); } } private static void EnsurePhysicalFocusRenderRig() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0151: 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_017b: 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_007f: 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) if ((Object)(object)_physicalFocusRenderRigRoot == (Object)null) { _physicalFocusRenderRigRoot = new GameObject("LethalCCTV_PhysicalFocusRenderRig"); if ((Object)(object)SurveillanceBootstrap.Instance != (Object)null) { _physicalFocusRenderRigRoot.transform.SetParent(((Component)SurveillanceBootstrap.Instance).transform, false); } else { Object.DontDestroyOnLoad((Object)(object)_physicalFocusRenderRigRoot); } _physicalFocusRenderRigRoot.transform.localPosition = new Vector3(12000f, -22000f, 6000f); _physicalFocusRenderRigRoot.transform.localRotation = Quaternion.identity; _physicalFocusRenderRigRoot.transform.localScale = Vector3.one; } if ((Object)(object)_physicalFocusRenderTexture == (Object)null) { _physicalFocusRenderTexture = new RenderTexture(1920, 1440, 0, (RenderTextureFormat)0) { name = "LethalCCTV_PhysicalFocusRT", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1, autoGenerateMips = false, useDynamicScale = false }; _physicalFocusRenderTexture.Create(); } if ((Object)(object)_physicalFocusUiCamera == (Object)null) { GameObject val = new GameObject("PhysicalFocusUICamera"); val.transform.SetParent(_physicalFocusRenderRigRoot.transform, false); val.transform.localPosition = new Vector3(0f, 0f, -10f); val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; _physicalFocusUiCamera = val.AddComponent(); _physicalFocusUiCamera.clearFlags = (CameraClearFlags)3; _physicalFocusUiCamera.backgroundColor = Color.clear; _physicalFocusUiCamera.orthographic = true; _physicalFocusUiCamera.orthographicSize = 360f; _physicalFocusUiCamera.aspect = 1.3333334f; _physicalFocusUiCamera.nearClipPlane = 0.1f; _physicalFocusUiCamera.farClipPlane = 30f; _physicalFocusUiCamera.cullingMask = 536870912; _physicalFocusUiCamera.targetTexture = _physicalFocusRenderTexture; _physicalFocusUiCamera.allowHDR = false; _physicalFocusUiCamera.allowMSAA = false; ((Behaviour)_physicalFocusUiCamera).enabled = false; } } private static void SetLayerRecursive(GameObject root, int layer) { if ((Object)(object)root == (Object)null) { return; } root.layer = layer; Transform transform = root.transform; for (int i = 0; i < transform.childCount; i++) { Transform child = transform.GetChild(i); if ((Object)(object)child != (Object)null) { SetLayerRecursive(((Component)child).gameObject, layer); } } } internal static void Shutdown() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) ForceExit("shutdown"); CloseStationEditMenu("shutdown"); SetStationThirdPersonDebugPersistent(active: false); RestoreStationGlobalThirdPersonDebugView(); RestoreLocalPlayerVisualStateAtControllerRestore(_controllerRestorePlayer); EndStationPlayerPoseTracking(); RestoreAudioListenerToPlayer(); _exitCameraInvariantPlayer = null; _exitCameraInvariantScheduledFrame = -1; CameraCallback onPreCull = Camera.onPreCull; object obj = <>O.<10>__OnCameraPreCull; if (obj == null) { CameraCallback val = OnCameraPreCull; <>O.<10>__OnCameraPreCull = val; obj = (object)val; } Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)onPreCull, (Delegate?)obj); UnbindInputActions(); if ((Object)(object)_overlayRoot != (Object)null) { Object.Destroy((Object)(object)_overlayRoot); _overlayRoot = null; } if ((Object)(object)_physicalFocusRenderTexture != (Object)null) { if ((Object)(object)_physicalFocusUiCamera != (Object)null) { _physicalFocusUiCamera.targetTexture = null; } _physicalFocusRenderTexture.Release(); Object.Destroy((Object)(object)_physicalFocusRenderTexture); _physicalFocusRenderTexture = null; } if ((Object)(object)_physicalFocusRenderRigRoot != (Object)null) { Object.Destroy((Object)(object)_physicalFocusRenderRigRoot); _physicalFocusRenderRigRoot = null; } if ((Object)(object)_crtScanlineSprite != (Object)null) { Object.Destroy((Object)(object)_crtScanlineSprite); _crtScanlineSprite = null; } if ((Object)(object)_crtScanlineTexture != (Object)null) { Object.Destroy((Object)(object)_crtScanlineTexture); _crtScanlineTexture = null; } if ((Object)(object)_terminalBackdropSprite != (Object)null) { Object.Destroy((Object)(object)_terminalBackdropSprite); _terminalBackdropSprite = null; } if ((Object)(object)_terminalBackdropTexture != (Object)null) { Object.Destroy((Object)(object)_terminalBackdropTexture); _terminalBackdropTexture = null; } _physicalFocusUiCamera = null; RestoreStationFocusRenderBudget(); if ((Object)(object)_cameraAudioProxyRoot != (Object)null) { Object.Destroy((Object)(object)_cameraAudioProxyRoot); _cameraAudioProxyRoot = null; _cameraAudioProxyListener = null; } StopFocusMachineLoop(); if ((Object)(object)_focusMachineLoopRoot != (Object)null) { Object.Destroy((Object)(object)_focusMachineLoopRoot); _focusMachineLoopRoot = null; _focusMachineLoopSource = null; } FocusMouselook.Shutdown(); RestoreFocusHudDimming(); _overlayRawImages = null; _overlayPaneRects = null; _overlayOutlineRects = null; _overlayPaneFrames = null; OverlayOutlines = null; _overlayCameraLabels = null; _overlayCameraLabelBackgrounds = null; _overlayCameraLabelRects = null; _overlayHeaderText = null; _overlayPageText = null; _overlayClockText = null; _overlayRecText = null; _overlayRecDot = null; _overlayActiveText = null; _radarInsetImage = null; _radarInsetRect = null; _radarImageRect = null; _radarInsetStatus = null; _operatorStatsRect = null; _operatorStatsText = null; _signalLogRect = null; _signalLogTitleText = null; _signalLogText = null; _scanStatusText = null; _reviewMenuRoot = null; _reviewMenuText = null; _placementEditorRoot = null; _placementEditorText = null; _centerReticle = null; _scanLabels = null; _scanVisibleUntil = 0f; CctvOutlineManager.Shutdown(); CctvScreenOutlineOverlay.Shutdown(); _audioListenerPlayer = null; _focusedPlayer = null; _exitPostureLogPending = false; _exitPosturePlayer = null; _exitPostureRestoredAt = 0f; _exitPostureLogAt = 0f; _priorDisableLook = false; _priorDisableMove = false; _priorDisableInteract = false; _focusViewAnimating = false; _focusViewExitPending = false; _focusViewAnimationDelayUntil = 0f; _physicalFocusViewActive = false; _stationPoseTrackingLogged = false; _stationPlayerPoseLockActive = false; _stationPlayerPosePlayer = null; _stationPlayerPoseSavedPosition = Vector3.zero; _stationPlayerPoseSavedRotation = Quaternion.identity; _stationPlayerPoseHandbackRotation = Quaternion.identity; _stationPlayerPoseHandbackCameraPitch = 0f; _stationPlayerPoseSavedServerPosition = Vector3.zero; _stationPlayerPoseSavedSnapToServerPosition = false; _stationPlayerPoseSavedDisableSyncInAnimation = false; _stationPlayerPoseSavedFreeRotationInInteractAnimation = false; _stationPlayerPoseSavedInSpecialInteractAnimation = false; _stationPlayerPoseSavedEnteringSpecialAnimation = false; _stationPlayerPoseHadController = false; _stationPlayerPoseSavedControllerDetectCollisions = false; _stationPlayerCameraBaselineCaptured = false; _stationPlayerCameraPlayerLocalPosition = Vector3.zero; if ((Object)(object)_stationPlayerCameraPositionStabilizer != (Object)null) { Object.Destroy((Object)(object)_stationPlayerCameraPositionStabilizer); } _stationPlayerCameraPositionStabilizer = null; _stationRadarLookBlend = 0f; _stationRadarLookSuppressedUntil = 0f; _stationFocusAnchorForcedUntil = 0f; _nextStationFocusOverlayRefreshAt = 0f; _radarLookEventState = false; _holdLocalObstructorsForInteractionsApiRestore = false; _localObstructorCallLogs.Clear(); _boundaryInputRecoveryLogs.Clear(); _stationCameraControlActive = false; _stationCameraControlEnablePending = false; _stationCameraControlEnableAt = 0f; _cameraPlacementEditModeOpen = false; _reviewMenuOpen = false; _reviewMenuSelectedIndex = 0; _placementEditorOpen = false; _placementEditSession = null; _nextStatsRefreshTime = 0f; _nextRadarInsetRefreshTime = 0f; _nextSignalLogRefreshTime = 0f; _nextOverlayHeaderRefreshTime = 0f; _overlayRecOn = false; _lastHackDockState = false; _lastDockTurretState = false; _focusDockLayoutInitialized = false; _hackingOverlay = null; _mainframeOverlay = null; _turretPageActive = false; _turretHitmarkerUntil = 0f; _turretHitmarkerEnemy = false; IsFocused = false; _isExitingFocus = false; ActiveSlot = 0; } internal static CCTVCamera GetActiveCamera() { if (IsTurretPageActive) { return null; } if (OpenBodyCamsCompat.IsFocusSlot(ActiveSlot) && OpenBodyCamsCompat.ShouldShowFocusSlot()) { return null; } return QuadCameraAssignment.GetBoundCamera(ActiveSlot); } internal static bool IsCameraControlActiveForCamera(CCTVCamera camera) { if ((Object)(object)camera == (Object)null || (Object)(object)camera.Cam == (Object)null || !camera.AllowsOperatorRotation) { return false; } if (!CctvSupportApi.IsMainframeHacked) { return false; } if (!IsFocused || IsReviewMenuOpen) { return false; } if (IsStationEditMenuOpen && !IsStationEditThirdPersonDebugActive) { return false; } if (Y4NGZPlayerAnimationBridge.IsFirstPersonHandEditModeActive) { return false; } if (IsHackingOverlayOpen || IsMainframeOverlayOpen) { return false; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null || val.isPlayerDead) { return false; } if (CCTVOperatorStation.IsDebugPlacementActive) { return false; } if (IsStationThirdPersonDebugViewActive) { return false; } if (!IsStationCameraControlActive) { return false; } if (IsTurretPageActive) { return false; } if (OpenBodyCamsCompat.IsFocusSlot(ActiveSlot) && OpenBodyCamsCompat.ShouldShowFocusSlot()) { return false; } return QuadCameraAssignment.GetBoundCamera(ActiveSlot) == camera; } internal static bool ShouldSuppressPlayerInput(PlayerControllerB player) { if (!IsFocused || _isExitingFocus || (Object)(object)player == (Object)null) { return false; } if ((Object)(object)_focusedPlayer != (Object)null && player == _focusedPlayer) { return true; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val != (Object)null) { return player == val; } return false; } internal static void ApplyFocusInputLock(PlayerControllerB player) { if (!((Object)(object)player == (Object)null)) { player.disableLookInput = true; player.disableMoveInput = true; player.disableInteract = true; } } private static void EnforceFocusInputLock() { if (!_isExitingFocus) { PlayerControllerB player = (((Object)(object)_focusedPlayer != (Object)null) ? _focusedPlayer : (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null)); if (ShouldSuppressPlayerInput(player)) { ApplyFocusInputLock(player); } } } private static bool HasFocusCleanupState() { if (!IsFocused && !((Object)(object)_focusedPlayer != (Object)null) && !_physicalFocusViewActive && !_focusViewAnimating && !_focusViewExitPending && !_stationPlayerPoseLockActive && !_stationPoseSettleActive && !_focusHudDimActive && !_stationThirdPersonPreviewActive && !_stationGlobalThirdPersonCameraActive && _focusHiddenLocalRenderers.Count <= 0 && _focusForcedLocalRenderers.Count <= 0 && _previewForcedLocalRenderers.Count <= 0 && !((Object)(object)_focusHiddenLocalVisor != (Object)null) && (!((Object)(object)_overlayRoot != (Object)null) || !_overlayRoot.activeSelf)) { if ((Object)(object)_physicalFocusUiCamera != (Object)null) { return ((Behaviour)_physicalFocusUiCamera).enabled; } return false; } return true; } private static bool LooksLikeStaleFocusInputLock(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return false; } if (player.inTerminalMenu) { return false; } if ((Object)(object)player.quickMenuManager != (Object)null && player.quickMenuManager.isMenuOpen) { return false; } if (player.isTypingChat) { return false; } if (player.disableLookInput && player.disableMoveInput) { return player.disableInteract; } return false; } private static void ClearResidualFocusAnimation(PlayerControllerB player, string reason) { if ((Object)(object)player == (Object)null || player.inTerminalMenu || ((Object)(object)player.quickMenuManager != (Object)null && player.quickMenuManager.isMenuOpen) || player.isTypingChat || (!player.inSpecialInteractAnimation && !player.enteringSpecialAnimation)) { return; } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] MonitorFocus clearing residual special-animation state (" + reason + ").")); } try { player.UpdateSpecialAnimationValue(false, (short)0, 0f, false); } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] MonitorFocus special-animation reset failed (" + reason + "): " + ex.Message)); } } try { player.inSpecialInteractAnimation = false; player.enteringSpecialAnimation = false; } catch (Exception ex2) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV] MonitorFocus special-animation flag clear failed (" + reason + "): " + ex2.Message)); } } } private static void RecoverStaleFocusInputLock(PlayerControllerB player, string reason) { if (LooksLikeStaleFocusInputLock(player)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] MonitorFocus recovered stale local-player input flags (" + reason + ").")); } ClearResidualFocusAnimation(player, reason); player.disableLookInput = false; player.disableMoveInput = false; player.disableInteract = false; } } private static void RecoverStaleFocusInputLockAtBoundary(string reason) { PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); bool flag = LooksLikeStaleFocusInputLock(val); bool flag2 = flag && (val.inSpecialInteractAnimation || val.enteringSpecialAnimation); if (flag) { RecoverStaleFocusInputLock(val, reason); } if (_boundaryInputRecoveryLogs.Add(reason)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][FocusInputRecovery] boundary={reason} frame={Time.frameCount} " + $"player={(Object)(object)val != (Object)null} clearedInputLock={flag} clearedAnimation={flag2}.")); } } } private static void RestoreFocusInputState() { PlayerControllerB focusedPlayer = _focusedPlayer; if ((Object)(object)focusedPlayer != (Object)null) { ClearResidualFocusAnimation(focusedPlayer, "exit-focus-stashed"); focusedPlayer.disableLookInput = _priorDisableLook; focusedPlayer.disableMoveInput = _priorDisableMove; focusedPlayer.disableInteract = _priorDisableInteract; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val != (Object)null && val != focusedPlayer) { RecoverStaleFocusInputLock(val, "exit-focus-local"); } _focusedPlayer = null; _priorDisableLook = false; _priorDisableMove = false; _priorDisableInteract = false; } internal static void EnterFocus(PlayerControllerB requestedPlayer) { //IL_0247: Unknown result type (might be due to invalid IL or missing references) long enterPerfPrev; long num = (enterPerfPrev = Stopwatch.GetTimestamp()); StringBuilder enterPerfPhases = new StringBuilder(256); if ((Object)(object)_overlayRoot == (Object)null) { bool flag = _overlayRoot != null; SurveillanceBootstrap.Log.LogWarning((object)$"[LethalCCTV] MonitorFocus.EnterFocus: overlay not initialized (refSet={flag}); continuing with physical focus view only."); } if (!TryEnterFocusPreflight(allowPoseSettleOwner: true, out var player, out var _)) { return; } if (_overlayRawImages != null) { for (int i = 0; i < _overlayRawImages.Length; i++) { if ((Object)(object)_overlayRawImages[i] != (Object)null) { _overlayRawImages[i].texture = QuadMonitor.GetCurrentDisplayTexture(i); } } } _turretPageActive = ShipTurretController.IsUnlocked; ActiveSlot = 0; _stationCameraControlActive = false; _stationCameraControlEnablePending = false; _stationCameraControlEnableAt = 0f; _stationCameraRenderBoostUntil = 0f; _stationRadarLookBlend = 0f; _stationRadarLookSuppressedUntil = 0f; _stationFocusAnchorForcedUntil = 0f; _radarLookEventState = false; RefreshRadarInsetTexture(); MarkEnterPhase("radar-inset"); RefreshOverlayFonts(); MarkEnterPhase("overlay-fonts"); UpdatePageIndicator(QuadCameraAssignment.CurrentPage, QuadCameraAssignment.TotalPages); UpdateActiveSlotLabel(ActiveSlot); RefreshBodycamFocusSlot(); RefreshTurretFocusPage(); MarkEnterPhase("overlay-prep"); QuadMonitor.SetPhysicalDisplayBlanked(blanked: false); if ((Object)(object)_overlayRoot != (Object)null) { SetLayerRecursive(_overlayRoot, 29); _overlayRoot.SetActive(false); } MarkEnterPhase("overlay-layer+activate"); if ((Object)(object)_physicalFocusUiCamera != (Object)null) { ((Behaviour)_physicalFocusUiCamera).enabled = false; } QuadMonitor.SetFocusScreenTexture(null, active: false); MarkEnterPhase("display"); _focusedPlayer = player; _priorDisableLook = player.disableLookInput; _priorDisableMove = player.disableMoveInput; _priorDisableInteract = player.disableInteract; player.disableLookInput = true; player.disableMoveInput = true; player.disableInteract = true; CCTVOperatorStation.EnsureFocusAnchorAimed(force: true); MarkEnterPhase("focus-anchor-aim"); CCTVOperatorStation.EnsureRadarAnchorAimed(force: true); MarkEnterPhase("radar-anchor-aim"); ScheduleStationFeedFlip(); MarkEnterPhase("anchors+lock"); BeginPhysicalFocusView(player); MarkEnterPhase("BeginPhysicalFocusView.rest"); if (_stationPoseSettleTransferToFocus && _stationPoseSettlePlayer == player) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][PoseSettle] captured head=" + FormatDebugVector(_priorFocusCameraWorldPosition) + ".")); } } BeginStationPlayerPoseTracking(player); MarkEnterPhase("BeginStationPlayerPoseTracking"); ApplyStationFocusRenderBudget(player.gameplayCamera); MarkEnterPhase("ApplyStationFocusRenderBudget"); ApplyFocusHudDimming(force: true); MarkEnterPhase("hud-dim#1.rest"); EnsureProvidedFocusAudioLoading(); MarkEnterPhase("focus-audio-load"); Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; IsFocused = true; CctvTargetCache.Invalidate(); CCTVMonitorFeedSync.NotifyLocalActiveSlotChanged(ActiveSlot); MarkEnterPhase("cctv-mode-activate"); _chairEventActive = true; CCTVStationEvents.RaiseChairEntered(player); MarkEnterPhase("chair-event"); ScheduleStationCameraControlActivation(); BoostStationCameraRenderCadence(0.35f); MarkEnterPhase("render-cadence+boot-sfx"); StartFocusMachineLoop(); MarkEnterPhase("StartFocusMachineLoop"); LogFocusRenderDiagnostics(); MarkEnterPhase("LogFocusRenderDiagnostics"); RefreshBodycamFocusSlot(); RefreshTurretFocusPage(); MarkEnterPhase("bodycam+turret-page"); CCTVWalkieTalkieBridge.EnterFocus(player); MarkEnterPhase("walkie-bridge"); PaneHighlight.SetActive(ActiveSlot); ApplyActivePaneLayout(); RefreshFocusDockLayout(); MarkEnterPhase("pane-layout+dock"); ApplyPhysicalFocusView(); SyncCameraAudioProxy(); UpdateActivePaneReticle(); MarkEnterPhase("focus-view+audio+reticle"); RefreshOperatorStats(force: true); MarkEnterPhase("RefreshOperatorStats"); ApplyFocusHudDimming(force: true); MarkEnterPhase("hud-dim#2.rest"); QuadCameraAssignment.RequestWakeAllSlots(); MarkEnterPhase("RequestWakeAllSlots"); MarkEnterPhase("wake-render"); double num2 = (double)(Stopwatch.GetTimestamp() - num) * 1000.0 / (double)Stopwatch.Frequency; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV][EnterPerf] EnterFocus frame {Time.frameCount}: total={num2:F1}ms | {enterPerfPhases}"); } _enterPerfLogPending = true; _enterPerfFrame = Time.frameCount; void MarkEnterPhase(string phaseName) { long timestamp = Stopwatch.GetTimestamp(); double num3 = (double)(timestamp - enterPerfPrev) * 1000.0 / (double)Stopwatch.Frequency; enterPerfPrev = timestamp; enterPerfPhases.Append(phaseName).Append('=').Append(num3.ToString("F1")) .Append("ms "); EntryPerfMark("Enter." + phaseName); } } private static void ScheduleStationFeedFlip() { _stationFeedFlipPending = true; _stationFeedFlipAt = Time.unscaledTime + 0.6f; } private static void TickPendingStationFeedFlip() { if (_stationFeedFlipPending && !(Time.unscaledTime < _stationFeedFlipAt)) { CompleteStationFeedFlip(playFeedback: true); } } internal static void CompleteStationFeedFlipAtPressContact() { if (_stationFeedFlipPending) { CompleteStationFeedFlip(playFeedback: true); } } private static void CompleteStationFeedFlip(bool playFeedback) { if (!_stationFeedFlipPending) { return; } _stationFeedFlipPending = false; _stationFeedFlipAt = 0f; CCTVVanillaMonitorDisplay.SetCctvModeActive(active: true, announce: false); CCTVVanillaMonitorDisplay.PrimeMonitorOwnershipNow(); if (playFeedback) { if (CCTVAccessButton.IsAvailable) { CCTVAccessButton.PlayPressAnimation(); } else { CCTVVanillaMonitorButtons.PlayRedButtonPressSfx(); } PlayBootSfx(); } } internal static void ExitFocus() { if (HasFocusCleanupState() && !_focusViewExitPending) { if (!_stationThirdPersonDebugPersistent) { SetStationThirdPersonPreview(active: false); } DisableStationCameraControl(); bool num = BeginPhysicalFocusExitAnimation(); CCTVStationEvents.RaiseActionButtonPressed("stand-up"); if (!num) { CompleteExitFocusCleanup(); } } } private static void CompleteExitFocusCleanup() { if (!HasFocusCleanupState()) { return; } CompleteStationFeedFlip(playFeedback: false); PlayerControllerB focusedPlayer = _focusedPlayer; CloseStationEditMenu("focus-cleanup"); _cameraPlacementEditModeOpen = false; SetStationThirdPersonPreview(active: false, _stationThirdPersonDebugPersistent); _isExitingFocus = true; try { RestoreFocusInputState(); RestoreFocusHudDimming(); EndPhysicalFocusView(); ScheduleExitPostureDiagnostic(focusedPlayer); if (_hackingOverlay != null && _hackingOverlay.IsOpen) { _hackingOverlay.Close(); RefreshFocusDockLayout(); } if (_mainframeOverlay != null && _mainframeOverlay.IsOpen) { _mainframeOverlay.Close("exit-focus"); RefreshFocusDockLayout(); } CancelPlacementEditor(restore: true); CloseCameraReviewMenu(); RestoreAudioListenerToPlayer(); CCTVWalkieTalkieBridge.ExitFocus(); StopFocusMachineLoop(); if ((Object)(object)_overlayRoot != (Object)null) { _overlayRoot.SetActive(false); } if ((Object)(object)_physicalFocusUiCamera != (Object)null) { ((Behaviour)_physicalFocusUiCamera).enabled = false; } QuadMonitor.SetFocusScreenTexture(null, active: false); QuadMonitor.SetPhysicalDisplayBlanked(QuadCameraAssignment.TotalCameraCount == 0); Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; PaneHighlight.ClearAll(); HideCameraScanOverlay(); if ((Object)(object)_centerReticle != (Object)null) { ((Component)_centerReticle).gameObject.SetActive(false); } _turretPageActive = false; _stationCameraControlActive = false; _stationCameraControlEnablePending = false; _stationCameraControlEnableAt = 0f; _stationRadarLookBlend = 0f; _stationRadarLookSuppressedUntil = 0f; _stationFocusAnchorForcedUntil = 0f; _nextStationFocusOverlayRefreshAt = 0f; if (_radarLookEventState) { _radarLookEventState = false; CCTVStationEvents.RaiseRadarViewChanged(lookingAtRadar: false); } RefreshTurretFocusPage(); OpenBodyCamsCompat.SetFocusRenderingActive(active: false); } finally { if (_physicalFocusViewActive) { try { EndPhysicalFocusView(); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] EndPhysicalFocusView failed during exit cleanup fallback: " + ex.Message)); } } } IsFocused = false; _isExitingFocus = false; if (_chairEventActive) { _chairEventActive = false; CCTVStationEvents.RaiseChairExited(focusedPlayer); } } } internal static void ForceExit(string reason) { if (_stationPoseSettleActive) { AbortEntryPoseSettle(reason); } if (!IsFocused && !_physicalFocusViewActive && _stationGlobalThirdPersonCameraActive) { SetStationThirdPersonDebugPersistent(active: false); RestoreLocalPlayerObstructors("force-exit-third-person:" + reason); EndStationPlayerPoseTracking(); RecoverStaleFocusInputLockAtBoundary("force-exit-third-person:" + reason); return; } if (!HasFocusCleanupState()) { RestoreLocalPlayerObstructors("force-exit-no-cleanup:" + reason); EndStationPlayerPoseTracking(); RecoverStaleFocusInputLockAtBoundary("force-exit-no-cleanup:" + reason); return; } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] MonitorFocus.ForceExit: reason=" + reason)); } _focusViewAnimating = false; _focusViewExitPending = false; _focusViewAnimationDelayUntil = 0f; CompleteExitFocusCleanup(); } private static void OnExitFocusPerformed(CallbackContext context) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if (!IsFocused) { return; } bool flag = ((CallbackContext)(ref context)).action == _inputActions?.ExitFocusKeyEscape; WasActiveThisFrame = true; _wasActiveSetFrame = Time.frameCount; if (Y4NGZPlayerAnimationBridge.IsFirstPersonHandEditModeActive) { if (flag) { CloseStationEditMenu("focus-escape-action"); } } else if (_stationEditMenuOpen) { if (flag) { CloseStationEditMenu("focus-escape-action"); } } else if (_reviewMenuOpen) { CloseCameraReviewMenu(); } else if (_placementEditorOpen) { CancelPlacementEditor(restore: true); ShowTimedScanStatus("PLACEMENT CANCELED", OVERLAY_SCAN_RED, 1.4f); } else if (_hackingOverlay != null && _hackingOverlay.IsOpen) { if (flag) { _hackingOverlay.Close("escape-action"); RefreshFocusDockLayout(); ShowScanStatus("HACK CANCELED", OVERLAY_SCAN_RED); return; } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV][CCTVHackTerminal] Ignored E exit while hack terminal is open; use ESC to close."); } } else if (_mainframeOverlay != null && _mainframeOverlay.IsOpen) { if (flag) { _mainframeOverlay.ConsumeEscapeIfOpen(); RefreshFocusDockLayout(); return; } ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)"[LethalCCTV][MainframeControl] Ignored E exit while mainframe menu is open; use ESC."); } } else if (CCTVOperatorStation.IsDebugPlacementActive) { if (flag) { CCTVOperatorStation.CancelDebugPlacement(); } } else { ExitFocus(); } } private static void LogLocalObstructorCallOnce(string operation, string reason) { string text = (string.IsNullOrWhiteSpace(reason) ? "unspecified" : reason); string item = operation + ":" + text; if (_localObstructorCallLogs.Add(item)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][ObstructorMask] call={operation} reason={text} frame={Time.frameCount} " + $"hidden={_focusHiddenLocalRenderers.Count} forced={_focusForcedLocalRenderers.Count} " + $"visor={(Object)(object)_focusHiddenLocalVisor != (Object)null} apiHold={_holdLocalObstructorsForInteractionsApiRestore}.")); } } } private static bool HasActiveLocalPlayerObstructors() { if (_focusHiddenLocalRenderers.Count <= 0 && _focusForcedLocalRenderers.Count <= 0) { return (Object)(object)_focusHiddenLocalVisor != (Object)null; } return true; } private static void SuppressLocalPlayerObstructors(PlayerControllerB player, string reason) { //IL_012b: 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_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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: 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_0181: 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_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) if (string.Equals(reason, "focus-view-begin", StringComparison.Ordinal) && HasActiveLocalPlayerObstructors()) { ReassertLocalPlayerObstructors(); LethalPhonesCompat.SuppressLocalPhone(player, reason); LogLocalObstructorCallOnce("suppress", reason); return; } RestoreLocalPlayerObstructors("suppress-preclear:" + reason); if ((Object)(object)player == (Object)null) { LogLocalObstructorCallOnce("suppress", reason); return; } string details; bool flag = ShouldShowRealLocalFirstPersonArms(player, out details); bool flag2 = flag && !_physicalFocusViewActive; AddLocalObstructorRenderer((Renderer)(object)player.thisPlayerModel); AddLocalObstructorRenderer((Renderer)(object)player.thisPlayerModelLOD1); AddLocalObstructorRenderer((Renderer)(object)player.thisPlayerModelLOD2); if (!flag || flag2) { AddLocalObstructorRenderer((Renderer)(object)player.thisPlayerModelArms); } if ((Object)(object)player.playerBodyAnimator != (Object)null) { Renderer[] componentsInChildren = ((Component)player.playerBodyAnimator).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (!flag || flag2 || !IsRealLocalFirstPersonArmRenderer(player, componentsInChildren[i])) { AddLocalObstructorRenderer(componentsInChildren[i]); } } } LogLocalFirstPersonArmsState(flag, flag2 ? (details + " [held hidden until the enter path owns the frame]") : details); if ((Object)(object)player.localVisor != (Object)null && !KeepLocalVisorDuringSessionEnabled) { _focusHiddenLocalVisor = player.localVisor; _focusHiddenLocalVisorLocalPosition = player.localVisor.localPosition; _focusHiddenLocalVisorLocalRotation = player.localVisor.localRotation; _focusHiddenLocalVisorLocalScale = player.localVisor.localScale; try { Transform val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.notSpawnedPosition : null); _focusHiddenLocalVisorHiddenWorldPosition = (((Object)(object)val != (Object)null) ? val.position : (player.localVisor.position + Vector3.down * 5000f)); player.localVisor.position = _focusHiddenLocalVisorHiddenWorldPosition; } catch { } } LethalPhonesCompat.SuppressLocalPhone(player, reason); LogLocalObstructorCallOnce("suppress", reason); } private static void ArmLocalFirstPersonArmsPresentation(PlayerControllerB player) { if (!ShouldShowRealLocalFirstPersonArms(player, out var _)) { return; } ForceLocalRendererVisible(player, (Renderer)(object)player.thisPlayerModelArms); if ((Object)(object)player.playerBodyAnimator == (Object)null) { return; } Renderer[] componentsInChildren = ((Component)player.playerBodyAnimator).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (IsRealLocalFirstPersonArmRenderer(player, componentsInChildren[i])) { ForceLocalRendererVisible(player, componentsInChildren[i]); } } } internal static void RefreshLocalOperatorFirstPersonVisibility() { if (IsFocused && !((Object)(object)_focusedPlayer == (Object)null)) { SuppressLocalPlayerObstructors(_focusedPlayer, "visibility-refresh"); ArmLocalFirstPersonArmsPresentation(_focusedPlayer); } } private static bool ShouldShowRealLocalFirstPersonArms(PlayerControllerB player, out string details) { details = "disabled"; if (!Y4NGZPlayerAnimationBridge.ShouldShowAuthoredFirstPersonArms) { return false; } if (IsStationThirdPersonDebugViewActive) { details = "third-person-debug-active"; return false; } if ((Object)(object)player == (Object)null) { details = "player-null"; return false; } Renderer thisPlayerModelArms = (Renderer)(object)player.thisPlayerModelArms; if (!IsUsableLocalFirstPersonArmsRenderer(thisPlayerModelArms, out var reason)) { details = reason; return false; } details = "renderer='" + ((Object)thisPlayerModelArms).name + "', path='" + GetTransformPath(((Component)thisPlayerModelArms).transform) + "', " + $"mesh='{GetRendererMeshName(thisPlayerModelArms)}', materials={GetRendererMaterialCount(thisPlayerModelArms)}"; return true; } private static bool IsUsableLocalFirstPersonArmsRenderer(Renderer renderer, out string reason) { if ((Object)(object)renderer == (Object)null) { reason = "thisPlayerModelArms-null"; return false; } if ((Object)(object)((Component)renderer).gameObject == (Object)null) { reason = "thisPlayerModelArms-gameObject-null"; return false; } if (renderer.sharedMaterials == null || renderer.sharedMaterials.Length == 0) { reason = "thisPlayerModelArms-has-no-materials"; return false; } reason = "ok"; return true; } private static bool IsRealLocalFirstPersonArmRenderer(PlayerControllerB player, Renderer renderer) { if ((Object)(object)player == (Object)null || (Object)(object)renderer == (Object)null) { return false; } if ((Object)(object)renderer == (Object)(object)player.thisPlayerModelArms) { return true; } return GetTransformPath(((Component)renderer).transform).IndexOf("ScavengerModelArmsOnly", StringComparison.OrdinalIgnoreCase) >= 0; } private static void LogLocalFirstPersonArmsState(bool active, string details) { if (active) { if (!_localFirstPersonArmsActiveLogged) { _localFirstPersonArmsActiveLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Local first-person CCTV arms active with real vanilla renderer only: " + details + ".")); } } } else if (Y4NGZPlayerAnimationBridge.UseLocalAuthoredOperatorAnimations && !_localFirstPersonArmsMissingLogged) { _localFirstPersonArmsMissingLogged = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Local first-person CCTV arms requested, but no usable real vanilla arm renderer was found; arms remain hidden. Reason: " + details + ".")); } } } private static void TickFirstPersonArmsOffsetHotkeys() { //IL_006b: 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_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_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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) Keyboard current = Keyboard.current; if (Y4NGZPlayerAnimationBridge.IsFirstPersonHandTuningHotkeyActive) { FinishFirstPersonArmsOffsetEditing(); return; } if (current == null || !CanEditFirstPersonArmsOffset()) { FinishFirstPersonArmsOffsetEditing(); return; } if (!((ButtonControl)current.leftAltKey).isPressed && !((ButtonControl)current.rightAltKey).isPressed) { FinishFirstPersonArmsOffsetEditing(); return; } EnsureFirstPersonArmsOffsetLoaded(); _firstPersonArmsOffsetEditingLastFrame = true; if (((ButtonControl)current.digit0Key).wasPressedThisFrame || ((ButtonControl)current.numpad0Key).wasPressedThisFrame) { _firstPersonArmsOffset = Vector3.zero; _firstPersonArmsOffsetDirty = true; ApplyFirstPersonArmsOffsetToForcedRenderers(); FlushFirstPersonArmsOffsetConfig(); ShowFirstPersonArmsOffsetStatus(force: true); return; } Vector3 zero = Vector3.zero; if (((ButtonControl)current.aKey).isPressed) { zero.x -= 1f; } if (((ButtonControl)current.dKey).isPressed) { zero.x += 1f; } if (((ButtonControl)current.fKey).isPressed || ((ButtonControl)current.pageDownKey).isPressed) { zero.y -= 1f; } if (((ButtonControl)current.rKey).isPressed || ((ButtonControl)current.pageUpKey).isPressed) { zero.y += 1f; } if (((ButtonControl)current.sKey).isPressed) { zero.z -= 1f; } if (((ButtonControl)current.wKey).isPressed) { zero.z += 1f; } if (!(((Vector3)(ref zero)).sqrMagnitude <= 0.0001f)) { float num = ((((ButtonControl)current.leftShiftKey).isPressed || ((ButtonControl)current.rightShiftKey).isPressed) ? 1.2f : 0.22f); float num2 = Mathf.Max(Time.unscaledDeltaTime, 0.001f); _firstPersonArmsOffset = ClampFirstPersonArmsOffset(_firstPersonArmsOffset + ((Vector3)(ref zero)).normalized * num * num2); _firstPersonArmsOffsetDirty = true; ApplyFirstPersonArmsOffsetToForcedRenderers(); ShowFirstPersonArmsOffsetStatus(force: false); } } private static bool CanEditFirstPersonArmsOffset() { if (!IsFocused) { return false; } if (!Y4NGZPlayerAnimationBridge.UseLocalAuthoredOperatorAnimations) { return false; } if (IsStationThirdPersonDebugViewActive || CCTVOperatorStation.IsDebugPlacementActive) { return false; } for (int i = 0; i < _focusForcedLocalRenderers.Count; i++) { LocalRendererState localRendererState = _focusForcedLocalRenderers[i]; if (localRendererState != null && localRendererState.ApplyFirstPersonArmsOffset && (Object)(object)localRendererState.OffsetTransform != (Object)null) { return true; } } return false; } private static void FinishFirstPersonArmsOffsetEditing() { if (_firstPersonArmsOffsetEditingLastFrame) { _firstPersonArmsOffsetEditingLastFrame = false; FlushFirstPersonArmsOffsetConfig(); } } private static void EnsureFirstPersonArmsOffsetLoaded() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (!_firstPersonArmsOffsetLoaded) { _firstPersonArmsOffset = Vector3.zero; _firstPersonArmsOffsetLoaded = true; } } private static Vector3 GetFirstPersonArmsOffset() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) EnsureFirstPersonArmsOffsetLoaded(); return _firstPersonArmsOffset; } private static Vector3 ClampFirstPersonArmsOffset(Vector3 value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) return new Vector3(Mathf.Clamp(value.x, -2.5f, 2.5f), Mathf.Clamp(value.y, -2.5f, 2.5f), Mathf.Clamp(value.z, -2.5f, 2.5f)); } private static void ApplyFirstPersonArmsOffsetToForcedRenderers() { if (Y4NGZPlayerAnimationBridge.ShouldUseLegacyFirstPersonArmsPresentation) { for (int i = 0; i < _focusForcedLocalRenderers.Count; i++) { ApplyFirstPersonArmsOffset(_focusForcedLocalRenderers[i]); } } } private static void CaptureFirstPersonArmsCameraPose(PlayerControllerB player) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) ResetFirstPersonArmsCameraPose(); if (!((Object)(object)player == (Object)null) && !((Object)(object)_physicalFocusCameraTransform == (Object)null)) { _firstPersonArmsCameraPoseRoot = ResolveFirstPersonArmsOffsetRoot(player, (Renderer)(object)player.thisPlayerModelArms); _firstPersonArmsCameraPoseCaptured = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] First-person arms head-frame presentation armed: root='" + (((Object)(object)_firstPersonArmsCameraPoseRoot != (Object)null) ? GetTransformPath(_firstPersonArmsCameraPoseRoot) : "") + "', headWorldPos=" + FormatDebugVector(_priorFocusCameraWorldPosition) + ", headWorldEuler=" + FormatDebugVector(((Quaternion)(ref _priorFocusCameraWorldRotation)).eulerAngles) + ".")); } } } private static void ResetFirstPersonArmsCameraPose() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) _firstPersonArmsCameraPoseCaptured = false; _firstPersonArmsCameraPoseRoot = null; _firstPersonArmsCameraFollowLogged = false; _firstPersonArmsPresentationFrame = -1; _firstPersonArmsPresentationRoot = null; _firstPersonArmsPresentationAnimPosition = Vector3.zero; _firstPersonArmsPresentationAnimRotation = Quaternion.identity; _firstPersonArmsPresentationFinalPosition = Vector3.zero; _firstPersonArmsPresentationFinalRotation = Quaternion.identity; } private static bool TryGetVanillaFocusHeadPose(out Vector3 position, out Quaternion rotation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) position = _priorFocusCameraWorldPosition; rotation = _priorFocusCameraWorldRotation; return _physicalFocusViewActive; } private static Quaternion FlattenToYaw(Quaternion rotation) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) Vector3 val = rotation * Vector3.forward; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = rotation * Vector3.up; val.y = 0f; } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { return Quaternion.identity; } return Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); } internal static bool TryGetFirstPersonArmsPresentationThisFrame(out Transform root, out Vector3 animPosition, out Quaternion animRotation, out Vector3 finalPosition, out Quaternion finalRotation) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //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) root = _firstPersonArmsPresentationRoot; animPosition = _firstPersonArmsPresentationAnimPosition; animRotation = _firstPersonArmsPresentationAnimRotation; finalPosition = _firstPersonArmsPresentationFinalPosition; finalRotation = _firstPersonArmsPresentationFinalRotation; if (_firstPersonArmsPresentationFrame == Time.frameCount) { return (Object)(object)root != (Object)null; } return false; } private static void ApplyFirstPersonArmsOffset(LocalRendererState state) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_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_01ae: 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_00a6: 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_00ae: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_0162: 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_0185: Unknown result type (might be due to invalid IL or missing references) if (state == null || !state.ApplyFirstPersonArmsOffset || (Object)(object)state.OffsetTransform == (Object)null) { return; } try { Vector3 firstPersonArmsOffset = GetFirstPersonArmsOffset(); if (_firstPersonArmsCameraPoseCaptured && (Object)(object)_physicalFocusCameraTransform != (Object)null && ((Object)(object)_firstPersonArmsCameraPoseRoot == (Object)null || (Object)(object)state.OffsetTransform == (Object)(object)_firstPersonArmsCameraPoseRoot) && TryGetVanillaFocusHeadPose(out var position, out var rotation)) { Transform physicalFocusCameraTransform = _physicalFocusCameraTransform; Transform offsetTransform = state.OffsetTransform; Vector3 val; Quaternion val2; if (_firstPersonArmsPresentationFrame == Time.frameCount && (Object)(object)_firstPersonArmsPresentationRoot == (Object)(object)offsetTransform) { val = _firstPersonArmsPresentationAnimPosition; val2 = _firstPersonArmsPresentationAnimRotation; } else { val = offsetTransform.position; val2 = offsetTransform.rotation; } Quaternion val3 = FlattenToYaw(physicalFocusCameraTransform.rotation); Quaternion val4 = val3 * Quaternion.Inverse(FlattenToYaw(rotation)); Vector3 val5 = physicalFocusCameraTransform.position + val4 * (val - position) + val3 * firstPersonArmsOffset; Quaternion val6 = val4 * val2; offsetTransform.SetPositionAndRotation(val5, val6); _firstPersonArmsPresentationFrame = Time.frameCount; _firstPersonArmsPresentationRoot = offsetTransform; _firstPersonArmsPresentationAnimPosition = val; _firstPersonArmsPresentationAnimRotation = val2; _firstPersonArmsPresentationFinalPosition = val5; _firstPersonArmsPresentationFinalRotation = val6; if (!_firstPersonArmsCameraFollowLogged) { _firstPersonArmsCameraFollowLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Camera-relative first-person arms follow active (head-frame yaw glue) camera-local trim " + FormatDebugVector(firstPersonArmsOffset) + " anim=" + FormatDebugVector(val) + " final=" + FormatDebugVector(val5) + ".")); } } } else { state.OffsetTransform.localPosition = state.OffsetLocalPosition + firstPersonArmsOffset; } } catch { } } private static void FlushFirstPersonArmsOffsetConfig() { //IL_0043: 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) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (_firstPersonArmsOffsetLoaded && _firstPersonArmsOffsetDirty) { Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(RoundFirstPersonArmsOffset(_firstPersonArmsOffset.x), RoundFirstPersonArmsOffset(_firstPersonArmsOffset.y), RoundFirstPersonArmsOffset(_firstPersonArmsOffset.z)); _firstPersonArmsOffset = val; _firstPersonArmsOffsetDirty = false; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] First-person CCTV arms offset now " + FormatDebugVector(val) + " (session-local; #575 removed its config keys).")); } } } private static float RoundFirstPersonArmsOffset(float value) { return Mathf.Round(value * 1000f) / 1000f; } private static void ShowFirstPersonArmsOffsetStatus(bool force) { //IL_0020: 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_002b: 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_0041: 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) if (force || !(Time.unscaledTime < _nextFirstPersonArmsOffsetStatusAt)) { _nextFirstPersonArmsOffsetStatusAt = Time.unscaledTime + 0.25f; Vector3 firstPersonArmsOffset = GetFirstPersonArmsOffset(); ShowTimedScanStatus($"ARMS {firstPersonArmsOffset.x:+0.00;-0.00;0.00} {firstPersonArmsOffset.y:+0.00;-0.00;0.00} {firstPersonArmsOffset.z:+0.00;-0.00;0.00}", OVERLAY_ACTIVE_GREEN, 0.35f); } } internal static void ShowOperatorTuningStatus(string text) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrWhiteSpace(text)) { ShowTimedScanStatus(text, OVERLAY_ACTIVE_GREEN, 0.45f); } } private static void SetStationThirdPersonPreview(bool active, bool keepPersistentDebug = false) { if (_stationThirdPersonPreviewActive == active) { if (!active && !keepPersistentDebug && !_stationThirdPersonDebugPersistent) { RestorePreviewForcedLocalRenderers(); } Y4NGZPlayerAnimationBridge.SetLocalThirdPersonPreviewEnabled(active || _stationThirdPersonDebugPersistent); return; } _stationThirdPersonPreviewActive = active; _previewCameraFramingLogged = false; if (active) { ResetStationThirdPersonOrbit(); CCTVOperatorStation.CancelDebugPlacement(); _stationRadarLookBlend = 0f; ForceLocalPlayerThirdPersonPreviewRenderers(_focusedPlayer); } else if (!keepPersistentDebug && !_stationThirdPersonDebugPersistent) { RestorePreviewForcedLocalRenderers(); } Y4NGZPlayerAnimationBridge.SetLocalThirdPersonPreviewEnabled(active || _stationThirdPersonDebugPersistent); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Station third-person operator preview " + (active ? "enabled" : "disabled") + ".")); } } private static Renderer ForceLocalPlayerThirdPersonPreviewRenderers(PlayerControllerB player) { if ((!_stationThirdPersonPreviewActive && !_stationThirdPersonDebugPersistent) || (Object)(object)player == (Object)null) { return null; } string details; Renderer val = SelectThirdPersonPreviewRenderer(player, out details); if ((Object)(object)val == (Object)null) { if (!_previewRendererFailureLogged) { _previewRendererFailureLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Station third-person operator preview has no usable body renderer. " + details)); } } return null; } string transformPath = GetTransformPath(((Component)val).transform); if (_previewForcedLocalRenderers.Count == 1 && (Object)(object)_previewForcedLocalRenderers[0].Renderer == (Object)(object)val) { ReassertPreviewRendererState(val); ForcePreviewCameraCanRender(val); return val; } RestorePreviewForcedLocalRenderers(); _previewCameraFramingLogged = false; ForcePreviewRendererVisible(val); ForcePreviewCameraCanRender(val); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] Station third-person operator preview renderer active: selected='" + ((Object)val).name + "', path='" + transformPath + "', " + $"mesh='{GetRendererMeshName(val)}', materials={GetRendererMaterialCount(val)}, " + FormatPreviewRendererRuntimeState(val) + ". " + details)); } return val; } private static void ForcePreviewRendererVisible(Renderer renderer) { if (!((Object)(object)renderer == (Object)null) && !IsRendererTracked(_previewForcedLocalRenderers, renderer)) { _previewForcedLocalRenderers.Add(CaptureRendererState(renderer)); ReassertPreviewRendererState(renderer); } } private static Renderer SelectThirdPersonPreviewRenderer(PlayerControllerB player, out string details) { List list = new List(3); Renderer currentSelection = null; currentSelection = ConsiderPreviewCandidate((Renderer)(object)player.thisPlayerModel, "thisPlayerModel", currentSelection, list); currentSelection = ConsiderPreviewCandidate((Renderer)(object)player.thisPlayerModelLOD1, "thisPlayerModelLOD1", currentSelection, list); currentSelection = ConsiderPreviewCandidate((Renderer)(object)player.thisPlayerModelLOD2, "thisPlayerModelLOD2", currentSelection, list); details = "candidates=[" + string.Join("; ", list.ToArray()) + "]"; return currentSelection; } private static Renderer ConsiderPreviewCandidate(Renderer renderer, string label, Renderer currentSelection, List diagnostics) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if (diagnostics == null) { diagnostics = new List(); } if (!IsUsableThirdPersonPreviewRenderer(renderer, out var reason)) { diagnostics.Add(label + ":skip:" + reason); return currentSelection; } diagnostics.Add(label + (((Object)(object)currentSelection == (Object)null) ? ":selected:" : ":not-forced:lower-priority:") + "name='" + ((Object)renderer).name + "', path='" + GetTransformPath(((Component)renderer).transform) + "', " + $"active={IsRendererActiveInHierarchy(renderer)}, enabled={renderer.enabled}, " + $"forceOff={GetRendererForceRenderingOff(renderer)}, shadow={renderer.shadowCastingMode}, " + "lodGroup='" + GetLodGroupPath(FindRendererLodGroup(renderer)) + "', " + $"mesh='{GetRendererMeshName(renderer)}', materials={GetRendererMaterialCount(renderer)}"); return currentSelection ?? renderer; } private static bool IsUsableThirdPersonPreviewRenderer(Renderer renderer, out string reason) { reason = null; if ((Object)(object)renderer == (Object)null) { reason = "null"; return false; } if ((Object)(object)((Component)renderer).gameObject == (Object)null) { reason = "missing-gameobject"; return false; } if (IsLikelyLocalArmRenderer(renderer)) { reason = "local-arms"; return false; } string transformPath = GetTransformPath(((Component)renderer).transform); if (ContainsLocalOnlyPreviewBlockerToken(((Object)renderer).name) || ContainsLocalOnlyPreviewBlockerToken(transformPath)) { reason = "local-only-renderer"; return false; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMesh == (Object)null) { reason = "missing-skinned-mesh"; return false; } reason = "ok"; return true; } private static bool ContainsLocalOnlyPreviewBlockerToken(string value) { if (string.IsNullOrEmpty(value)) { return false; } if (value.IndexOf("visor", StringComparison.OrdinalIgnoreCase) < 0 && value.IndexOf("mask", StringComparison.OrdinalIgnoreCase) < 0 && value.IndexOf("arms", StringComparison.OrdinalIgnoreCase) < 0 && value.IndexOf("firstperson", StringComparison.OrdinalIgnoreCase) < 0) { return value.IndexOf("first person", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static string GetRendererMeshName(Renderer renderer) { SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if (val != null) { if (!((Object)(object)val.sharedMesh != (Object)null)) { return ""; } return ((Object)val.sharedMesh).name; } MeshFilter val2 = (((Object)(object)renderer != (Object)null) ? ((Component)renderer).GetComponent() : null); if (!((Object)(object)val2 != (Object)null) || !((Object)(object)val2.sharedMesh != (Object)null)) { return ""; } return ((Object)val2.sharedMesh).name; } private static int GetRendererMaterialCount(Renderer renderer) { Material[] array = (((Object)(object)renderer != (Object)null) ? renderer.sharedMaterials : null); if (array == null) { return 0; } return array.Length; } private static void ReassertPreviewRendererState(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return; } DisablePreviewLodGroupForRenderer(renderer); try { renderer.forceRenderingOff = false; } catch { } try { renderer.allowOcclusionWhenDynamic = false; } catch { } try { renderer.receiveShadows = true; } catch { } try { renderer.enabled = true; } catch { } try { renderer.shadowCastingMode = (ShadowCastingMode)1; } catch { } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if (!((Object)(object)val != (Object)null)) { return; } try { val.updateWhenOffscreen = true; } catch { } } private static void RestorePreviewForcedLocalRenderers() { for (int i = 0; i < _previewForcedLocalRenderers.Count; i++) { RestoreRendererState(_previewForcedLocalRenderers[i]); } _previewForcedLocalRenderers.Clear(); RestorePreviewForcedLodGroups(); RestorePreviewCameraCullingMask(); _previewRendererFailureLogged = false; } private static void AddLocalObstructorRenderer(Renderer renderer) { if ((Object)(object)renderer == (Object)null || IsDedicatedLocalViewmodelRenderer(renderer) || IsRendererTracked(_focusForcedLocalRenderers, renderer) || IsRendererTracked(_focusHiddenLocalRenderers, renderer)) { return; } _focusHiddenLocalRenderers.Add(CaptureRendererState(renderer)); try { renderer.enabled = false; } catch { } } private static bool IsDedicatedLocalViewmodelRenderer(Renderer renderer) { Transform val = (((Object)(object)renderer != (Object)null) ? ((Component)renderer).transform : null); while ((Object)(object)val != (Object)null) { if (((Object)val).name.StartsWith("Y4NGZ_Viewmodel_", StringComparison.Ordinal)) { return true; } val = val.parent; } return false; } private static void ForceLocalRendererVisible(PlayerControllerB player, Renderer renderer) { //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_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) if ((Object)(object)renderer == (Object)null) { return; } LocalRendererState localRendererState = FindRendererState(_focusForcedLocalRenderers, renderer); LocalRendererState localRendererState2 = FindRendererState(_focusHiddenLocalRenderers, renderer); if (localRendererState2 != null) { _focusHiddenLocalRenderers.Remove(localRendererState2); if (localRendererState == null) { localRendererState = localRendererState2; _focusForcedLocalRenderers.Add(localRendererState); } } if (localRendererState == null) { localRendererState = CaptureRendererState(renderer); _focusForcedLocalRenderers.Add(localRendererState); } Transform val = ResolveFirstPersonArmsOffsetRoot(player, renderer); if ((Object)(object)val != (Object)null && (!localRendererState.ApplyFirstPersonArmsOffset || (Object)(object)localRendererState.OffsetTransform != (Object)(object)val) && !IsFirstPersonArmsOffsetRootTracked(val)) { localRendererState.ApplyFirstPersonArmsOffset = true; localRendererState.OffsetTransform = val; try { localRendererState.OffsetLocalPosition = val.localPosition; } catch { } try { localRendererState.OffsetLocalRotation = val.localRotation; } catch { } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] First-person CCTV arms offset target: root='" + GetTransformPath(val) + "', renderer='" + GetTransformPath(((Component)renderer).transform) + "'.")); } } try { renderer.enabled = true; } catch { } ApplyFirstPersonArmsOffset(localRendererState); } private static LocalRendererState FindRendererState(List states, Renderer renderer) { if (states == null || (Object)(object)renderer == (Object)null) { return null; } for (int i = 0; i < states.Count; i++) { if ((Object)(object)states[i]?.Renderer == (Object)(object)renderer) { return states[i]; } } return null; } private static LocalRendererState CaptureRendererState(Renderer renderer) { //IL_00b3: 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_004a: 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) LocalRendererState localRendererState = new LocalRendererState { Renderer = renderer, WasEnabled = ((Object)(object)renderer != (Object)null && renderer.enabled), SharedMaterials = (((Object)(object)renderer != (Object)null) ? renderer.sharedMaterials : null), ShadowCastingMode = (ShadowCastingMode)(((Object)(object)renderer != (Object)null) ? ((int)renderer.shadowCastingMode) : 0), Transform = (((Object)(object)renderer != (Object)null) ? ((Component)renderer).transform : null) }; if ((Object)(object)renderer != (Object)null) { try { localRendererState.ReceiveShadows = renderer.receiveShadows; } catch { } try { localRendererState.ForceRenderingOff = renderer.forceRenderingOff; } catch { } try { localRendererState.AllowOcclusionWhenDynamic = renderer.allowOcclusionWhenDynamic; } catch { } try { localRendererState.LocalPosition = ((Component)renderer).transform.localPosition; } catch { } } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if ((Object)(object)val != (Object)null) { localRendererState.HasUpdateWhenOffscreen = true; localRendererState.UpdateWhenOffscreen = val.updateWhenOffscreen; } return localRendererState; } private static void RestoreRendererState(LocalRendererState state) { //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_0039: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)state?.Renderer == (Object)null) { return; } Renderer renderer = state.Renderer; if (state.ApplyFirstPersonArmsOffset && (Object)(object)state.OffsetTransform != (Object)null) { try { state.OffsetTransform.localPosition = state.OffsetLocalPosition; } catch { } try { state.OffsetTransform.localRotation = state.OffsetLocalRotation; } catch { } } try { renderer.enabled = state.WasEnabled; } catch { } try { renderer.shadowCastingMode = state.ShadowCastingMode; } catch { } try { renderer.receiveShadows = state.ReceiveShadows; } catch { } try { renderer.forceRenderingOff = state.ForceRenderingOff; } catch { } try { renderer.allowOcclusionWhenDynamic = state.AllowOcclusionWhenDynamic; } catch { } try { if (state.SharedMaterials != null) { renderer.sharedMaterials = state.SharedMaterials; } } catch { } if (!state.HasUpdateWhenOffscreen) { return; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if (val == null) { return; } try { val.updateWhenOffscreen = state.UpdateWhenOffscreen; } catch { } } private static bool IsRendererTracked(List states, Renderer renderer) { if (states == null || (Object)(object)renderer == (Object)null) { return false; } for (int i = 0; i < states.Count; i++) { if ((Object)(object)states[i].Renderer == (Object)(object)renderer) { return true; } } return false; } private static Transform ResolveFirstPersonArmsOffsetRoot(PlayerControllerB player, Renderer renderer) { if (!IsRealLocalFirstPersonArmRenderer(player, renderer)) { return null; } Transform val = (((Object)(object)renderer != (Object)null) ? ((Component)renderer).transform : null); while ((Object)(object)val != (Object)null) { if (string.Equals(((Object)val).name, "ScavengerModelArmsOnly", StringComparison.OrdinalIgnoreCase)) { return val; } val = val.parent; } Renderer val2 = (Renderer)(object)(((Object)(object)player != (Object)null) ? player.thisPlayerModelArms : null); val = (((Object)(object)val2 != (Object)null) ? ((Component)val2).transform : null); while ((Object)(object)val != (Object)null) { if (string.Equals(((Object)val).name, "ScavengerModelArmsOnly", StringComparison.OrdinalIgnoreCase)) { return val; } val = val.parent; } if (!((Object)(object)renderer != (Object)null)) { return null; } return ((Component)renderer).transform; } private static bool IsFirstPersonArmsOffsetRootTracked(Transform root) { if ((Object)(object)root == (Object)null) { return true; } for (int i = 0; i < _focusForcedLocalRenderers.Count; i++) { LocalRendererState localRendererState = _focusForcedLocalRenderers[i]; if (localRendererState != null && localRendererState.ApplyFirstPersonArmsOffset && (Object)(object)localRendererState.OffsetTransform == (Object)(object)root) { return true; } } return false; } private static void ForcePreviewCameraCanRender(Renderer renderer) { if ((Object)(object)_physicalFocusCamera == (Object)null || (Object)(object)renderer == (Object)null || (Object)(object)((Component)renderer).gameObject == (Object)null) { return; } int layer = ((Component)renderer).gameObject.layer; if (layer < 0 || layer > 31) { return; } if (!_previewCameraCullingMaskSaved || (Object)(object)_previewForcedCamera != (Object)(object)_physicalFocusCamera) { if (_previewCameraCullingMaskSaved && (Object)(object)_previewForcedCamera != (Object)null) { RestorePreviewCameraCullingMask(); } _previewForcedCamera = _physicalFocusCamera; _previewSavedCameraCullingMask = _physicalFocusCamera.cullingMask; _previewCameraCullingMaskSaved = true; } int num = 1 << layer; try { if ((_physicalFocusCamera.cullingMask & num) == 0) { Camera physicalFocusCamera = _physicalFocusCamera; physicalFocusCamera.cullingMask |= num; } } catch { } } private static void RestorePreviewCameraCullingMask() { if (_previewCameraCullingMaskSaved && (Object)(object)_previewForcedCamera != (Object)null) { try { _previewForcedCamera.cullingMask = _previewSavedCameraCullingMask; } catch { } } _previewForcedCamera = null; _previewSavedCameraCullingMask = 0; _previewCameraCullingMaskSaved = false; } private static LODGroup DisablePreviewLodGroupForRenderer(Renderer renderer) { LODGroup val = FindRendererLodGroup(renderer); if ((Object)(object)val == (Object)null) { return null; } if (!IsLodGroupTracked(_previewForcedLodGroups, val)) { bool wasEnabled = false; try { wasEnabled = val.enabled; } catch { } _previewForcedLodGroups.Add(new LocalLodGroupState { Group = val, WasEnabled = wasEnabled }); } try { if (val.enabled) { val.enabled = false; } } catch { } return val; } private static void RestorePreviewForcedLodGroups() { for (int i = 0; i < _previewForcedLodGroups.Count; i++) { LocalLodGroupState localLodGroupState = _previewForcedLodGroups[i]; if (!((Object)(object)localLodGroupState?.Group == (Object)null)) { try { localLodGroupState.Group.enabled = localLodGroupState.WasEnabled; } catch { } } } _previewForcedLodGroups.Clear(); } private static bool IsLodGroupTracked(List states, LODGroup group) { if (states == null || (Object)(object)group == (Object)null) { return false; } for (int i = 0; i < states.Count; i++) { if ((Object)(object)states[i].Group == (Object)(object)group) { return true; } } return false; } private static LODGroup FindRendererLodGroup(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return null; } try { return ((Component)renderer).GetComponentInParent(); } catch { return null; } } private static string GetLodGroupPath(LODGroup group) { if (!((Object)(object)group != (Object)null)) { return ""; } return GetTransformPath(((Component)group).transform); } private static bool IsRendererActiveInHierarchy(Renderer renderer) { try { return (Object)(object)renderer != (Object)null && (Object)(object)((Component)renderer).gameObject != (Object)null && ((Component)renderer).gameObject.activeInHierarchy; } catch { return false; } } private static bool GetRendererForceRenderingOff(Renderer renderer) { try { return (Object)(object)renderer != (Object)null && renderer.forceRenderingOff; } catch { return false; } } private static bool GetRendererAllowOcclusionWhenDynamic(Renderer renderer) { try { return (Object)(object)renderer != (Object)null && renderer.allowOcclusionWhenDynamic; } catch { return false; } } private static bool GetRendererReceiveShadows(Renderer renderer) { try { return (Object)(object)renderer != (Object)null && renderer.receiveShadows; } catch { return false; } } private static string FormatPreviewRendererRuntimeState(Renderer renderer) { //IL_002a: 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) LODGroup val = FindRendererLodGroup(renderer); Bounds bounds; string text = (TryGetPreviewRendererBounds(renderer, out bounds) ? ("boundsCenter=" + FormatDebugVector(((Bounds)(ref bounds)).center) + ", boundsSize=" + FormatDebugVector(((Bounds)(ref bounds)).size) + ", ") : "bounds=, "); int num = (((Object)(object)renderer != (Object)null && (Object)(object)((Component)renderer).gameObject != (Object)null) ? ((Component)renderer).gameObject.layer : (-1)); return $"active={IsRendererActiveInHierarchy(renderer)}, enabled={(Object)(object)renderer != (Object)null && renderer.enabled}, " + $"layer={num}, " + $"forceOff={GetRendererForceRenderingOff(renderer)}, " + $"receiveShadows={GetRendererReceiveShadows(renderer)}, " + $"occlusion={GetRendererAllowOcclusionWhenDynamic(renderer)}, " + text + $"lodGroup='{GetLodGroupPath(val)}', lodGroupDisabledForPreview={(Object)(object)val != (Object)null}"; } private static bool TryGetPreviewRendererBounds(Renderer renderer, out Bounds bounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); if ((Object)(object)renderer == (Object)null) { return false; } try { bounds = renderer.bounds; } catch { return false; } if (IsFinite(((Bounds)(ref bounds)).center) && IsFinite(((Bounds)(ref bounds)).size)) { Vector3 val = ((Bounds)(ref bounds)).size; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { val = ((Bounds)(ref bounds)).extents; return ((Vector3)(ref val)).sqrMagnitude > 2.5E-05f; } } return false; } private static bool IsFinite(Vector3 value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (IsFinite(value.x) && IsFinite(value.y)) { return IsFinite(value.z); } return false; } private static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private static void LogStationThirdPersonPreviewFraming(Renderer renderer, bool framedRendererBounds, Bounds bounds, Vector3 target, Vector3 cameraPosition) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_00b5: 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_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) if (_previewCameraFramingLogged) { return; } _previewCameraFramingLogged = true; if (!((Object)(object)_physicalFocusCamera == (Object)null) && !((Object)(object)renderer == (Object)null)) { string arg = ""; string arg2 = ""; try { arg = FormatDebugVector(_physicalFocusCamera.WorldToViewportPoint(target)); arg2 = (framedRendererBounds ? GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(_physicalFocusCamera), bounds).ToString() : ""); } catch { } int num = (((Object)(object)((Component)renderer).gameObject != (Object)null) ? ((Component)renderer).gameObject.layer : (-1)); bool flag = num >= 0 && (_physicalFocusCamera.cullingMask & (1 << num)) != 0; string arg3 = (framedRendererBounds ? ("boundsCenter=" + FormatDebugVector(((Bounds)(ref bounds)).center) + " boundsSize=" + FormatDebugVector(((Bounds)(ref bounds)).size)) : "bounds="); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Station third-person operator preview camera framed: renderer='" + ((Object)renderer).name + "', path='" + GetTransformPath(((Component)renderer).transform) + "', " + $"usingRendererBounds={framedRendererBounds}, {arg3}, " + "target=" + FormatDebugVector(target) + ", camera=" + FormatDebugVector(cameraPosition) + ", " + $"distance={Vector3.Distance(cameraPosition, target):F2}, viewport={arg}, " + $"frustumContainsBounds={arg2}, rendererLayer={num}, cameraHasLayer={flag}, " + $"cameraMask=0x{_physicalFocusCamera.cullingMask:X8}, fov={_physicalFocusCamera.fieldOfView:F1}, " + $"near={_physicalFocusCamera.nearClipPlane:F2}, far={_physicalFocusCamera.farClipPlane:F1}")); } } } private static bool IsLikelyLocalArmRenderer(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return false; } string value = ((Object)renderer).name ?? string.Empty; string transformPath = GetTransformPath(((Component)renderer).transform); if (!ContainsArmToken(value)) { return ContainsArmToken(transformPath); } return true; } private static bool ContainsArmToken(string value) { if (string.IsNullOrWhiteSpace(value)) { return false; } string text = value.ToLowerInvariant(); if (text.IndexOf("arm", StringComparison.Ordinal) < 0 && text.IndexOf("hand", StringComparison.Ordinal) < 0 && text.IndexOf("glove", StringComparison.Ordinal) < 0) { return text.IndexOf("sleeve", StringComparison.Ordinal) >= 0; } return true; } private static string GetTransformPath(Transform transform) { if ((Object)(object)transform == (Object)null) { return string.Empty; } string text = ((Object)transform).name ?? string.Empty; Transform parent = transform.parent; int num = 0; while ((Object)(object)parent != (Object)null && num++ < 24) { text = (((Object)parent).name ?? string.Empty) + "/" + text; parent = parent.parent; } return text; } private static string FormatDebugVector(Vector3 value) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"({value.x:F2},{value.y:F2},{value.z:F2})"; } internal static void RetainLocalPlayerVisualStateForControllerRestore(PlayerControllerB player) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && (!((Object)(object)_controllerRestorePlayer == (Object)(object)player) || (_controllerRestoreLocalRenderers.Count <= 0 && !((Object)(object)_controllerRestoreLocalVisor != (Object)null)))) { if (_controllerRestoreLocalRenderers.Count > 0 || (Object)(object)_controllerRestoreLocalVisor != (Object)null) { RestoreRetainedLocalPlayerVisualState(); } _controllerRestorePlayer = player; for (int i = 0; i < _focusHiddenLocalRenderers.Count; i++) { AddControllerRestoreRendererState(_focusHiddenLocalRenderers[i]); } for (int j = 0; j < _focusForcedLocalRenderers.Count; j++) { AddControllerRestoreRendererState(_focusForcedLocalRenderers[j]); } _controllerRestoreLocalVisor = _focusHiddenLocalVisor; _controllerRestoreLocalVisorLocalPosition = _focusHiddenLocalVisorLocalPosition; _controllerRestoreLocalVisorLocalRotation = _focusHiddenLocalVisorLocalRotation; _controllerRestoreLocalVisorLocalScale = _focusHiddenLocalVisorLocalScale; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ExitVisualRestore] Retained focus-start visual state until controller restore: " + $"renderers={_controllerRestoreLocalRenderers.Count}, visor={(Object)(object)_controllerRestoreLocalVisor != (Object)null}.")); } } } internal static void RestoreStationPoseForImmediateControllerRestore(PlayerControllerB player, string reason) { if (_stationPlayerPoseLockActive && !((Object)(object)player == (Object)null) && !((Object)(object)_stationPlayerPosePlayer != (Object)(object)player)) { RestoreStationPlayerPoseTracking("immediate-controller-restore-" + reason); } } internal static void ReassertCameraStabilizerAfterImmediateControllerRestore(PlayerControllerB player, string reason) { if ((Object)(object)player == (Object)null || (Object)(object)player.gameplayCamera == (Object)null) { return; } try { CCTVLocalCameraPositionStabilizer component = ((Component)player.gameplayCamera).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.ApplyNow(); component.ReleaseAfterLateUpdates(2); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Station camera baseline guard reasserted after immediate controller restore (" + reason + ").")); } } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Immediate controller-restore camera guard failed (" + reason + "): " + ex.Message)); } } } internal static void RestoreLocalPlayerVisualStateAtControllerRestore(PlayerControllerB player) { int count = _focusHiddenLocalRenderers.Count; int count2 = _focusForcedLocalRenderers.Count; RestoreLocalPlayerObstructors("controller-restore"); int count3 = _controllerRestoreLocalRenderers.Count; bool flag = (Object)(object)_controllerRestoreLocalVisor != (Object)null; bool flag2 = (Object)(object)player == (Object)null || (Object)(object)_controllerRestorePlayer == (Object)null || (Object)(object)_controllerRestorePlayer == (Object)(object)player; RestoreRetainedLocalPlayerVisualState(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ExitVisualRestore] Controller-restore visual state applied: " + $"activeObstructors={count}, activeForced={count2}, " + $"retainedRenderers={count3}, retainedVisor={flag}, playerMatches={flag2}.")); } } internal static void GetLocalRendererBookkeeping(Renderer renderer, out bool forcedVisible, out bool obstructor) { forcedVisible = IsRendererTracked(_focusForcedLocalRenderers, renderer); obstructor = IsRendererTracked(_focusHiddenLocalRenderers, renderer); } internal static bool TryGetFirstPersonArmsFocusStartRootPose(Transform root, out Vector3 localPosition, out Quaternion localRotation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) localPosition = Vector3.zero; localRotation = Quaternion.identity; if ((Object)(object)root == (Object)null) { return false; } for (int i = 0; i < _focusForcedLocalRenderers.Count; i++) { LocalRendererState localRendererState = _focusForcedLocalRenderers[i]; if (localRendererState != null && localRendererState.ApplyFirstPersonArmsOffset && !((Object)(object)localRendererState.OffsetTransform != (Object)(object)root)) { localPosition = localRendererState.OffsetLocalPosition; localRotation = localRendererState.OffsetLocalRotation; return true; } } return false; } private static void AddControllerRestoreRendererState(LocalRendererState state) { if ((Object)(object)state?.Renderer == (Object)null) { return; } for (int i = 0; i < _controllerRestoreLocalRenderers.Count; i++) { if ((Object)(object)_controllerRestoreLocalRenderers[i]?.Renderer == (Object)(object)state.Renderer) { return; } } _controllerRestoreLocalRenderers.Add(state); } private static void RestoreRetainedLocalPlayerVisualState() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _controllerRestoreLocalRenderers.Count; i++) { RestoreRendererState(_controllerRestoreLocalRenderers[i]); } _controllerRestoreLocalRenderers.Clear(); if ((Object)(object)_controllerRestoreLocalVisor != (Object)null) { try { _controllerRestoreLocalVisor.localPosition = _controllerRestoreLocalVisorLocalPosition; _controllerRestoreLocalVisor.localRotation = _controllerRestoreLocalVisorLocalRotation; _controllerRestoreLocalVisor.localScale = _controllerRestoreLocalVisorLocalScale; } catch { } } _controllerRestorePlayer = null; _controllerRestoreLocalVisor = null; _controllerRestoreLocalVisorLocalPosition = Vector3.zero; _controllerRestoreLocalVisorLocalRotation = Quaternion.identity; _controllerRestoreLocalVisorLocalScale = Vector3.one; } private static void ReassertLocalPlayerObstructors() { //IL_0109: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _focusHiddenLocalRenderers.Count; i++) { LocalRendererState localRendererState = _focusHiddenLocalRenderers[i]; if ((Object)(object)localRendererState?.Renderer == (Object)null) { continue; } try { if (localRendererState.Renderer.enabled) { localRendererState.Renderer.enabled = false; } } catch { } } for (int j = 0; j < _focusForcedLocalRenderers.Count; j++) { LocalRendererState localRendererState2 = _focusForcedLocalRenderers[j]; if ((Object)(object)localRendererState2?.Renderer == (Object)null) { continue; } try { if (!localRendererState2.Renderer.enabled) { localRendererState2.Renderer.enabled = true; } } catch { } ApplyFirstPersonArmsOffset(localRendererState2); } for (int k = 0; k < _previewForcedLocalRenderers.Count; k++) { LocalRendererState localRendererState3 = _previewForcedLocalRenderers[k]; if (!((Object)(object)localRendererState3?.Renderer == (Object)null)) { ReassertPreviewRendererState(localRendererState3.Renderer); } } if ((Object)(object)_focusHiddenLocalVisor != (Object)null) { try { _focusHiddenLocalVisor.position = _focusHiddenLocalVisorHiddenWorldPosition; } catch { } } LethalPhonesCompat.ReassertLocalPhoneSuppression(); } private static void RestoreLocalPlayerObstructors(string reason) { //IL_00be: 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_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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_00a9: Unknown result type (might be due to invalid IL or missing references) LogLocalObstructorCallOnce("restore", reason); LethalPhonesCompat.RestoreLocalPhone(reason); FinishFirstPersonArmsOffsetEditing(); RestorePreviewForcedLocalRenderers(); for (int i = 0; i < _focusHiddenLocalRenderers.Count; i++) { RestoreRendererState(_focusHiddenLocalRenderers[i]); } _focusHiddenLocalRenderers.Clear(); for (int j = 0; j < _focusForcedLocalRenderers.Count; j++) { RestoreRendererState(_focusForcedLocalRenderers[j]); } _focusForcedLocalRenderers.Clear(); if ((Object)(object)_focusHiddenLocalVisor != (Object)null) { try { _focusHiddenLocalVisor.localPosition = _focusHiddenLocalVisorLocalPosition; _focusHiddenLocalVisor.localRotation = _focusHiddenLocalVisorLocalRotation; _focusHiddenLocalVisor.localScale = _focusHiddenLocalVisorLocalScale; } catch { } } _focusHiddenLocalVisor = null; _focusHiddenLocalVisorLocalPosition = Vector3.zero; _focusHiddenLocalVisorLocalRotation = Quaternion.identity; _focusHiddenLocalVisorLocalScale = Vector3.one; _focusHiddenLocalVisorHiddenWorldPosition = Vector3.zero; _holdLocalObstructorsForInteractionsApiRestore = false; } internal static void ReleaseLocalPlayerObstructorsAfterInteractionsApiRestore(PlayerControllerB player, string reason) { bool num = _holdLocalObstructorsForInteractionsApiRestore || HasActiveLocalPlayerObstructors(); RestoreLocalPlayerObstructors("interactions-api-restored:" + reason); if (num) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] obstructor suppression released reason=" + reason + ".")); } } } private static void TickPendingLocalObstructorRestore() { if (_holdLocalObstructorsForInteractionsApiRestore) { ReassertLocalPlayerObstructors(); } } private static void CreateOverlayBackground(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Background"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; Image obj2 = val.AddComponent(); ((Graphic)obj2).color = new Color(0.018f, 0.052f, 0.038f, 1f); ((Graphic)obj2).raycastTarget = false; } private static void CreateOverlayWorkstationBackplate(Transform parent) { //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_0023: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0156: 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_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) float num = 984f; float num2 = 744f; GameObject val = new GameObject("WorkstationBackplate"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); obj.anchoredPosition = Vector2.zero; obj.sizeDelta = new Vector2(num, num2); Image obj2 = val.AddComponent(); obj2.sprite = EnsureTerminalBackdropSprite(); ((Graphic)obj2).color = Color.white; ((Graphic)obj2).raycastTarget = false; CreateCrtScanlineOverlay(parent); CreateBackplateRule(parent, "BackplateTopRule", new Vector2(0f, num2 / 2f), new Vector2(num, 3f)); CreateBackplateRule(parent, "BackplateBottomRule", new Vector2(0f, (0f - num2) / 2f), new Vector2(num, 3f)); CreateBackplateRule(parent, "BackplateLeftRule", new Vector2((0f - num) / 2f, 0f), new Vector2(3f, num2)); CreateBackplateRule(parent, "BackplateRightRule", new Vector2(num / 2f, 0f), new Vector2(3f, num2)); float num3 = -120f; CreateBackplateRule(parent, "BackplateSectionDivider", new Vector2(0f, num3), new Vector2(num, 3f)); float num4 = GetBottomLeftDockCenterX() + 260f + 7f; CreateBackplateRule(parent, "BackplateBottomColumnDivider", new Vector2(num4, GetBottomDockCenterY()), new Vector2(3f, 220f)); float num5 = GetBottomSectionBottomY() + 10f + 120f + 4f; CreateBackplateRule(parent, "BackplateRightSectionDivider", new Vector2(GetRightColumnCenterX(), num5), new Vector2(392f, 3f)); CreateBackplateRule(parent, "BackplateControlsDivider", new Vector2(GetRightColumnCenterX(), GetRightTopHalfCenter(isLeftHalf: true).y), new Vector2(3f, 92f)); } private static void CreateCrtScanlineOverlay(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_003e: 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) GameObject val = new GameObject("CRTScanlines"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; Image obj2 = val.AddComponent(); obj2.sprite = EnsureCrtScanlineSprite(); obj2.type = (Type)2; ((Graphic)obj2).color = new Color(0.05f, 0.78f, 0.23f, 0.055f); ((Graphic)obj2).raycastTarget = false; } private static Sprite EnsureTerminalBackdropSprite() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_terminalBackdropSprite != (Object)null) { return _terminalBackdropSprite; } _terminalBackdropTexture = new Texture2D(256, 192, (TextureFormat)4, false) { name = "LethalCCTV_FocusTerminalBackplate", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; Color32[] array = (Color32[])(object)new Color32[49152]; for (int i = 0; i < 192; i++) { for (int j = 0; j < 256; j++) { float num = (float)j / 255f * 2f - 1f; float num2 = (float)i / 191f * 2f - 1f; float num3 = Mathf.Clamp01((Mathf.Sqrt(num * num * 0.78f + num2 * num2 * 1.25f) - 0.34f) / 0.74f); int num4 = ((j * 17 + i * 31 + (j ^ i) * 7) & 7) - 3; int num5 = ((i % 4 == 0) ? 18 : ((i % 4 == 2) ? (-2) : 0)); int num6 = ((j % 64 == 0 || i % 48 == 0) ? 18 : 0); float num7 = 1f - num3 * 0.24f; int value = Mathf.RoundToInt((float)(18 + num4) * num7); int value2 = Mathf.RoundToInt((float)(70 + num5 + num6 + num4) * num7); int value3 = Mathf.RoundToInt((float)(50 + num4) * num7); array[i * 256 + j] = new Color32(ToByte(value), ToByte(value2), ToByte(value3), byte.MaxValue); } } _terminalBackdropTexture.SetPixels32(array); _terminalBackdropTexture.Apply(false, true); _terminalBackdropSprite = Sprite.Create(_terminalBackdropTexture, new Rect(0f, 0f, 256f, 192f), new Vector2(0.5f, 0.5f), 1f); return _terminalBackdropSprite; } private static byte ToByte(int value) { return (byte)Mathf.Clamp(value, 0, 255); } private static Sprite EnsureCrtScanlineSprite() { //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_0027: 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_003a: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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) if ((Object)(object)_crtScanlineSprite != (Object)null) { return _crtScanlineSprite; } _crtScanlineTexture = new Texture2D(1, 8, (TextureFormat)4, false) { name = "LethalCCTV_FocusCrtScanlines", filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)0 }; Color32[] array = (Color32[])(object)new Color32[8] { new Color32((byte)80, byte.MaxValue, (byte)128, (byte)115), default(Color32), default(Color32), default(Color32), default(Color32), default(Color32), default(Color32), default(Color32) }; for (int i = 1; i < array.Length; i++) { array[i] = new Color32((byte)0, (byte)0, (byte)0, (byte)0); } _crtScanlineTexture.SetPixels32(array); _crtScanlineTexture.Apply(false, true); _crtScanlineSprite = Sprite.Create(_crtScanlineTexture, new Rect(0f, 0f, 1f, 8f), new Vector2(0.5f, 0.5f), 1f); return _crtScanlineSprite; } private static void CreateBackplateRule(Transform parent, string name, Vector2 position, Vector2 size) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_007f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); obj.anchoredPosition = position; obj.sizeDelta = size; Image obj2 = val.AddComponent(); ((Graphic)obj2).color = new Color(0.045f, 0.64f, 0.27f, 0.98f); ((Graphic)obj2).raycastTarget = false; } private static Vector2 GetTurretPaneCenter() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) float num = 360f - 480f; float num2 = 360f - 30f - 18f; float num3 = num + 20f; return new Vector2(0f, (num2 + num3) * 0.5f); } private static Vector2 GetTurretPaneSize() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return new Vector2(854f, 438f); } private static Vector2 GetOverlayPaneCenter(int slotIndex) { //IL_006e: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) if (IsTurretPageActive && slotIndex == 0) { return GetTurretPaneCenter(); } float num = -217f; float num2 = 217f; float num3 = 360f - 480f; float num4 = 360f - 30f - 18f; float num5 = num3 + 20f; float num6 = (num4 + num5) * 0.5f; float num7 = 113f; float num8 = num6 + num7; float num9 = num6 - num7; return (Vector2)(slotIndex switch { 0 => new Vector2(num, num8), 1 => new Vector2(num2, num8), 2 => new Vector2(num, num9), _ => new Vector2(num2, num9), }); } private static Vector2 GetOverlayPaneSize(int slotIndex) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (IsTurretPageActive && slotIndex == 0) { return GetTurretPaneSize(); } return new Vector2(420f, 212f); } internal static bool TryGetOverlayPaneGeometry(int slotIndex, out Vector2 center, out Vector2 size) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_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_0074: 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) center = Vector2.zero; size = Vector2.zero; if (_overlayPaneRects == null || slotIndex < 0 || slotIndex >= _overlayPaneRects.Length) { return false; } RectTransform val = _overlayPaneRects[slotIndex]; if ((Object)(object)val == (Object)null) { return false; } center = val.anchoredPosition; size = val.sizeDelta; if (size.x <= 1f || size.y <= 1f) { size = GetOverlayPaneSize(slotIndex); } if (size.x > 1f) { return size.y > 1f; } return false; } private static Image CreateOverlayOutline(Transform parent, int slotIndex) { //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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) Vector2 overlayPaneCenter = GetOverlayPaneCenter(slotIndex); Vector2 overlayPaneSize = GetOverlayPaneSize(slotIndex); GameObject val = new GameObject($"OverlayQuadrantOutline_{slotIndex}"); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent(); val2.anchorMin = new Vector2(0.5f, 0.5f); val2.anchorMax = new Vector2(0.5f, 0.5f); val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = overlayPaneCenter; val2.sizeDelta = overlayPaneSize + new Vector2(6f, 6f); if (_overlayOutlineRects != null && slotIndex >= 0 && slotIndex < _overlayOutlineRects.Length) { _overlayOutlineRects[slotIndex] = val2; } Image obj = val.AddComponent(); ((Graphic)obj).color = Color.clear; ((Graphic)obj).raycastTarget = false; if (_overlayPaneFrames != null && slotIndex >= 0 && slotIndex < _overlayPaneFrames.Length) { _overlayPaneFrames[slotIndex] = CreatePaneFrame(val.transform, slotIndex); ApplyPaneFrameLayout(_overlayPaneFrames[slotIndex], val2.sizeDelta); } return obj; } private static PaneFrame CreatePaneFrame(Transform parent, int slotIndex) { //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_0041: 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_0067: 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_008c: Unknown result type (might be due to invalid IL or missing references) PaneFrame paneFrame = new PaneFrame { Segments = (Image[])(object)new Image[8] }; for (int i = 0; i < paneFrame.Segments.Length; i++) { GameObject val = new GameObject($"OverlayQuadrantFrame_{slotIndex}_{i}"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); Image val2 = val.AddComponent(); ((Graphic)val2).color = Color.clear; ((Graphic)val2).raycastTarget = false; paneFrame.Segments[i] = val2; } return paneFrame; } private static void ApplyPaneFrameLayout(PaneFrame frame, Vector2 outlineSize) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0045: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0126: 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_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) if (frame?.Segments != null && frame.Segments.Length >= 8) { float num = outlineSize.x * 0.5f; float num2 = outlineSize.y * 0.5f; float num3 = 2f; float num4 = Mathf.Min(46f, Mathf.Min(outlineSize.x, outlineSize.y) * 0.27f); SetPaneFrameSegment(frame.Segments[0], new Vector2(0f - num + num4 * 0.5f, num2 - num3 * 0.5f), new Vector2(num4, num3)); SetPaneFrameSegment(frame.Segments[1], new Vector2(0f - num + num3 * 0.5f, num2 - num4 * 0.5f), new Vector2(num3, num4)); SetPaneFrameSegment(frame.Segments[2], new Vector2(num - num4 * 0.5f, num2 - num3 * 0.5f), new Vector2(num4, num3)); SetPaneFrameSegment(frame.Segments[3], new Vector2(num - num3 * 0.5f, num2 - num4 * 0.5f), new Vector2(num3, num4)); SetPaneFrameSegment(frame.Segments[4], new Vector2(0f - num + num4 * 0.5f, 0f - num2 + num3 * 0.5f), new Vector2(num4, num3)); SetPaneFrameSegment(frame.Segments[5], new Vector2(0f - num + num3 * 0.5f, 0f - num2 + num4 * 0.5f), new Vector2(num3, num4)); SetPaneFrameSegment(frame.Segments[6], new Vector2(num - num4 * 0.5f, 0f - num2 + num3 * 0.5f), new Vector2(num4, num3)); SetPaneFrameSegment(frame.Segments[7], new Vector2(num - num3 * 0.5f, 0f - num2 + num4 * 0.5f), new Vector2(num3, num4)); } } private static void SetPaneFrameSegment(Image image, Vector2 position, Vector2 size) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)image == (Object)null)) { RectTransform rectTransform = ((Graphic)image).rectTransform; rectTransform.anchoredPosition = position; rectTransform.sizeDelta = size; } } internal static void SetOverlayFrameTint(int slotIndex, Color color) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (_overlayPaneFrames == null || slotIndex < 0 || slotIndex >= _overlayPaneFrames.Length) { return; } PaneFrame paneFrame = _overlayPaneFrames[slotIndex]; if (paneFrame?.Segments == null) { return; } for (int i = 0; i < paneFrame.Segments.Length; i++) { if ((Object)(object)paneFrame.Segments[i] != (Object)null) { ((Graphic)paneFrame.Segments[i]).color = color; } } } private static RawImage CreateOverlayQuadrant(Transform parent, int slotIndex) { //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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_007e: Unknown result type (might be due to invalid IL or missing references) Vector2 overlayPaneCenter = GetOverlayPaneCenter(slotIndex); Vector2 overlayPaneSize = GetOverlayPaneSize(slotIndex); GameObject val = new GameObject($"OverlayQuadrant_{slotIndex}"); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent(); val2.anchorMin = new Vector2(0.5f, 0.5f); val2.anchorMax = new Vector2(0.5f, 0.5f); val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = overlayPaneCenter; val2.sizeDelta = overlayPaneSize; if (_overlayPaneRects != null && slotIndex >= 0 && slotIndex < _overlayPaneRects.Length) { _overlayPaneRects[slotIndex] = val2; } RawImage obj = val.AddComponent(); obj.texture = QuadMonitor.GetCurrentDisplayTexture(slotIndex); ((Graphic)obj).raycastTarget = false; return obj; } private static Image CreateOverlayCameraLabel(Transform parent, int slotIndex, out TextMeshProUGUI label) { //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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_0129: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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) Vector2 overlayPaneCenter = GetOverlayPaneCenter(slotIndex); Vector2 overlayPaneSize = GetOverlayPaneSize(slotIndex); GameObject val = new GameObject($"OverlayCameraLabelBg_{slotIndex}"); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent(); val2.anchorMin = new Vector2(0.5f, 0.5f); val2.anchorMax = new Vector2(0.5f, 0.5f); val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(overlayPaneCenter.x - overlayPaneSize.x / 2f + 8f, overlayPaneCenter.y + overlayPaneSize.y / 2f - 8f); val2.sizeDelta = new Vector2(92f, 22f); if (_overlayCameraLabelRects != null && slotIndex >= 0 && slotIndex < _overlayCameraLabelRects.Length) { _overlayCameraLabelRects[slotIndex] = val2; } Image obj = val.AddComponent(); ((Graphic)obj).color = new Color(0.002f, 0.022f, 0.014f, 0.78f); ((Graphic)obj).raycastTarget = false; GameObject val3 = new GameObject($"OverlayCameraLabel_{slotIndex}"); val3.transform.SetParent(val.transform, false); RectTransform obj2 = val3.AddComponent(); obj2.anchorMin = Vector2.zero; obj2.anchorMax = Vector2.one; obj2.offsetMin = new Vector2(8f, 0f); obj2.offsetMax = new Vector2(-8f, 0f); label = val3.AddComponent(); ((TMP_Text)label).text = "CAM_--"; ((TMP_Text)label).fontSize = 20f; ((TMP_Text)label).fontStyle = (FontStyles)1; ((TMP_Text)label).alignment = (TextAlignmentOptions)4097; ((Graphic)label).color = Color.white; ((Graphic)label).raycastTarget = false; ApplyOverlayFont(label); ((Behaviour)obj).enabled = false; ((Behaviour)label).enabled = false; return obj; } private static void CreateOverlayChrome(Transform parent) { //IL_0012: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) float num = 341f; Image val = CreateOverlayStatusBar(parent, "OverlayHeader", new Vector2(0f, num), new Vector2(960f, 30f)); _overlayHeaderText = CreateOverlayText(((Component)val).transform, "HeaderText", "LETHALCCTV SECURITY FEED", 14f, OVERLAY_ACTIVE_GREEN, (TextAlignmentOptions)4097); SetRectFill(((TMP_Text)_overlayHeaderText).rectTransform, new Vector2(28f, 0f), new Vector2(-330f, 0f)); _overlayPageText = CreateOverlayText(((Component)val).transform, "PageText", "PAGE 1/1", 12f, Color.white, (TextAlignmentOptions)4100); SetRectFill(((TMP_Text)_overlayPageText).rectTransform, new Vector2(620f, 0f), new Vector2(-28f, 0f)); _overlayClockText = CreateOverlayText(((Component)val).transform, "HeaderClockText", "--:--", 13f, Color.white, (TextAlignmentOptions)514); SetRectFill(((TMP_Text)_overlayClockText).rectTransform, new Vector2(330f, 0f), new Vector2(-330f, 0f)); GameObject val2 = new GameObject("HeaderRecDot"); val2.transform.SetParent(((Component)val).transform, false); RectTransform obj = val2.AddComponent(); obj.anchorMin = new Vector2(0f, 0.5f); obj.anchorMax = new Vector2(0f, 0.5f); obj.pivot = new Vector2(0f, 0.5f); obj.anchoredPosition = new Vector2(640f, 0f); obj.sizeDelta = new Vector2(9f, 9f); _overlayRecDot = val2.AddComponent(); ((Graphic)_overlayRecDot).color = OVERLAY_REC_RED; ((Graphic)_overlayRecDot).raycastTarget = false; _overlayRecText = CreateOverlayText(((Component)val).transform, "HeaderRecText", "REC", 12f, OVERLAY_REC_RED, (TextAlignmentOptions)4097); SetRectFill(((TMP_Text)_overlayRecText).rectTransform, new Vector2(656f, 0f), new Vector2(-230f, 0f)); _overlayRecOn = true; RefreshOverlayHeaderStatus(force: true); } private static void RefreshOverlayHeaderStatus(bool force) { //IL_00e1: 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) if ((Object)(object)_overlayClockText == (Object)null && (Object)(object)_overlayRecText == (Object)null && (Object)(object)_overlayRecDot == (Object)null) { return; } float unscaledTime = Time.unscaledTime; if (!force && unscaledTime < _nextOverlayHeaderRefreshTime) { return; } _nextOverlayHeaderRefreshTime = unscaledTime + 0.25f; if ((Object)(object)_overlayClockText != (Object)null) { string shipTime24h = CctvScreenClock.GetShipTime24h(); if (!string.Equals(((TMP_Text)_overlayClockText).text, shipTime24h, StringComparison.Ordinal)) { ((TMP_Text)_overlayClockText).text = shipTime24h; CctvScreenClock.LogComparisonOnce(shipTime24h); } } bool flag = Mathf.Repeat(unscaledTime, 1f) < 0.55f; if (force || flag != _overlayRecOn) { _overlayRecOn = flag; if ((Object)(object)_overlayRecDot != (Object)null) { ((Graphic)_overlayRecDot).color = new Color(OVERLAY_REC_RED.r, OVERLAY_REC_RED.g, OVERLAY_REC_RED.b, flag ? 1f : 0.14f); } if ((Object)(object)_overlayRecText != (Object)null) { ((Graphic)_overlayRecText).color = new Color(OVERLAY_REC_RED.r, OVERLAY_REC_RED.g, OVERLAY_REC_RED.b, flag ? 1f : 0.25f); } } } private static Image CreateOverlayStatusBar(Transform parent, string name, Vector2 position, Vector2 size) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_007f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); obj.anchoredPosition = position; obj.sizeDelta = size; Image obj2 = val.AddComponent(); ((Graphic)obj2).color = new Color(0.002f, 0.022f, 0.014f, 0.78f); ((Graphic)obj2).raycastTarget = false; return obj2; } private static Vector2 GetBottomLeftDockPosition() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return new Vector2(GetBottomLeftDockCenterX(), GetBottomDockCenterY()); } private static Vector2 GetBottomLeftDockSize() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return new Vector2(520f, 220f); } private static Vector2 GetRightBottomRadarPosition() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) float num = GetBottomSectionBottomY() + 10f + 60f; return new Vector2(GetRightColumnCenterX(), num); } private static Vector2 GetRightBottomRadarSize() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return new Vector2(392f, 120f); } private static void CreateSignalLogPanel(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00cb: 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_0102: 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_016b: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("SignalLogFrame"); val.transform.SetParent(parent, false); _signalLogRect = val.AddComponent(); _signalLogRect.anchorMin = new Vector2(0.5f, 0.5f); _signalLogRect.anchorMax = new Vector2(0.5f, 0.5f); _signalLogRect.pivot = new Vector2(0.5f, 0.5f); _signalLogRect.anchoredPosition = GetRightBottomRadarPosition(); _signalLogRect.sizeDelta = GetRightBottomRadarSize(); Image obj = val.AddComponent(); ((Graphic)obj).color = new Color(0.01f, 0.058f, 0.034f, 0.82f); ((Graphic)obj).raycastTarget = false; _signalLogTitleText = CreateOverlayText(val.transform, "SignalLogTitle", "SIGNAL LOG", 10f, OVERLAY_AMBER, (TextAlignmentOptions)257); SetRectFill(((TMP_Text)_signalLogTitleText).rectTransform, new Vector2(14f, 0f), new Vector2(-14f, -6f)); _signalLogText = CreateOverlayText(val.transform, "SignalLogText", "", 8.8f, new Color(0.54f, 0.76f, 0.6f, 1f), (TextAlignmentOptions)4097); ((TMP_Text)_signalLogText).lineSpacing = -7f; SetRectFill(((TMP_Text)_signalLogText).rectTransform, new Vector2(14f, 8f), new Vector2(-14f, -24f)); RefreshSignalLogPanel(force: true); } private static Vector2 GetRightTopHalfSize() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return new Vector2(192f, 92f); } private static Vector2 GetRightTopHalfCenter(bool isLeftHalf) { //IL_0000: 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) float num = GetRightTopHalfSize().x * 0.5f + 4f; float num2 = GetRightColumnCenterX() + (isLeftHalf ? (0f - num) : num); float num3 = GetBottomSectionTopY() - 10f - 46f; return new Vector2(num2, num3); } private static float GetBottomLeftDockCenterX() { return -203f; } private static float GetRightColumnCenterX() { return 267f; } private static float GetBottomSectionTopY() { return -120f; } private static float GetBottomSectionBottomY() { return -360f; } private static float GetBottomDockCenterY() { return GetBottomSectionBottomY() + 10f + 110f; } private static void RefreshFocusDockLayout() { bool flag = IsHackingOverlayOpen || IsMainframeOverlayOpen; bool isTurretPageActive = IsTurretPageActive; if (_focusDockLayoutInitialized && _lastHackDockState == flag && _lastDockTurretState == isTurretPageActive) { return; } if (_lastHackDockState != flag) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Focus dock layout mode=" + (flag ? "terminal-dock" : "normal") + ".")); } } ApplyRadarDockLayout(flag); if (flag) { PrepareInteractiveOverlayDock(); } _lastHackDockState = flag; _lastDockTurretState = isTurretPageActive; _focusDockLayoutInitialized = true; } private static void ApplyRadarDockLayout(bool hackingOpen) { //IL_00ce: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_011c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_radarInsetRect == (Object)null) { return; } if (IsTurretPageActive) { if (((Component)_radarInsetRect).gameObject.activeSelf) { ((Component)_radarInsetRect).gameObject.SetActive(false); } if ((Object)(object)_signalLogRect != (Object)null && ((Component)_signalLogRect).gameObject.activeSelf) { ((Component)_signalLogRect).gameObject.SetActive(false); } return; } if (!((Component)_radarInsetRect).gameObject.activeSelf) { ((Component)_radarInsetRect).gameObject.SetActive(true); } if ((Object)(object)_signalLogRect != (Object)null) { ((Component)_signalLogRect).gameObject.SetActive(!hackingOpen); } if (hackingOpen) { _radarInsetRect.anchoredPosition = GetRightBottomRadarPosition(); _radarInsetRect.sizeDelta = GetRightBottomRadarSize(); } else { _radarInsetRect.anchoredPosition = GetBottomLeftDockPosition(); _radarInsetRect.sizeDelta = GetBottomLeftDockSize(); } if ((Object)(object)_radarImageRect != (Object)null) { _radarImageRect.offsetMin = new Vector2(2f, 2f); _radarImageRect.offsetMax = new Vector2(-2f, -18f); } } private static void CreateRadarInset(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0032: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: 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) GameObject val = new GameObject("RadarInsetFrame"); val.transform.SetParent(parent, false); _radarInsetRect = val.AddComponent(); _radarInsetRect.anchorMin = new Vector2(0.5f, 0.5f); _radarInsetRect.anchorMax = new Vector2(0.5f, 0.5f); _radarInsetRect.pivot = new Vector2(0.5f, 0.5f); Image obj = val.AddComponent(); ((Graphic)obj).color = new Color(0.01f, 0.062f, 0.036f, 0.82f); ((Graphic)obj).raycastTarget = false; GameObject val2 = new GameObject("RadarInsetImage"); val2.transform.SetParent(val.transform, false); _radarImageRect = val2.AddComponent(); _radarImageRect.anchorMin = Vector2.zero; _radarImageRect.anchorMax = Vector2.one; _radarImageRect.offsetMin = new Vector2(2f, 2f); _radarImageRect.offsetMax = new Vector2(-2f, -18f); _radarInsetImage = val2.AddComponent(); ((Graphic)_radarInsetImage).color = Color.white; ((Graphic)_radarInsetImage).raycastTarget = false; _radarInsetStatus = CreateOverlayText(val.transform, "RadarInsetStatus", "RADAR MAP", 11f, OVERLAY_AMBER, (TextAlignmentOptions)4097); RectTransform rectTransform = ((TMP_Text)_radarInsetStatus).rectTransform; rectTransform.anchorMin = new Vector2(0f, 1f); rectTransform.anchorMax = new Vector2(1f, 1f); rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(0f, -2f); rectTransform.sizeDelta = new Vector2(-14f, 20f); ApplyRadarDockLayout(hackingOpen: false); RefreshRadarInsetTexture(); } private static void CreateOperatorStatsPanel(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("OperatorStatsFrame"); val.transform.SetParent(parent, false); _operatorStatsRect = val.AddComponent(); _operatorStatsRect.anchorMin = new Vector2(0.5f, 0.5f); _operatorStatsRect.anchorMax = new Vector2(0.5f, 0.5f); _operatorStatsRect.pivot = new Vector2(0.5f, 0.5f); _operatorStatsRect.anchoredPosition = GetRightTopHalfCenter(isLeftHalf: true); _operatorStatsRect.sizeDelta = GetRightTopHalfSize(); Image obj = val.AddComponent(); ((Graphic)obj).color = new Color(0.01f, 0.055f, 0.032f, 0.82f); ((Graphic)obj).raycastTarget = false; _operatorStatsText = CreateOverlayText(val.transform, "OperatorStatsText", "MAINFRAME // READY", 10.4f, Color.white, (TextAlignmentOptions)4097); ((TMP_Text)_operatorStatsText).lineSpacing = -8f; SetRectFill(((TMP_Text)_operatorStatsText).rectTransform, new Vector2(16f, 6f), new Vector2(-14f, -6f)); RefreshOperatorStats(force: true); } private static void CreateCameraScanOverlay(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0066: 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_00b8: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("CameraScanStatus"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); obj.sizeDelta = new Vector2(220f, 28f); _scanStatusText = val.AddComponent(); ((TMP_Text)_scanStatusText).text = ""; ((TMP_Text)_scanStatusText).fontSize = 18f; ((TMP_Text)_scanStatusText).fontStyle = (FontStyles)1; ((TMP_Text)_scanStatusText).alignment = (TextAlignmentOptions)514; ((Graphic)_scanStatusText).color = OVERLAY_SCAN_BLUE; ((Graphic)_scanStatusText).raycastTarget = false; ApplyOverlayFont(_scanStatusText); val.SetActive(false); _scanLabels = new ScanLabel[6]; for (int i = 0; i < _scanLabels.Length; i++) { _scanLabels[i] = CreateCameraScanLabel(parent, i, "CameraScan"); _scanLabels[i].Tracer = CreateScanTracer(parent, i, "CameraScan"); } } private static void CreateCameraReviewMenu(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0088: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) _reviewMenuRoot = new GameObject("CameraReviewMenu"); _reviewMenuRoot.transform.SetParent(parent, false); RectTransform obj = _reviewMenuRoot.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); obj.anchoredPosition = new Vector2(0f, 40f); obj.sizeDelta = new Vector2(520f, 360f); Image obj2 = _reviewMenuRoot.AddComponent(); ((Graphic)obj2).color = new Color(0f, 0f, 0f, 0.88f); ((Graphic)obj2).raycastTarget = false; _reviewMenuText = CreateOverlayText(_reviewMenuRoot.transform, "CameraReviewMenuText", string.Empty, 16f, Color.white, (TextAlignmentOptions)257); ((TMP_Text)_reviewMenuText).enableWordWrapping = false; ((TMP_Text)_reviewMenuText).richText = true; ((TMP_Text)_reviewMenuText).lineSpacing = -6f; SetRectFill(((TMP_Text)_reviewMenuText).rectTransform, new Vector2(22f, 18f), new Vector2(-22f, -18f)); _reviewMenuRoot.SetActive(false); } private static void CreatePlacementEditorMenu(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0088: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) _placementEditorRoot = new GameObject("PlacementEditorMenu"); _placementEditorRoot.transform.SetParent(parent, false); RectTransform obj = _placementEditorRoot.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); obj.anchoredPosition = new Vector2(0f, -18f); obj.sizeDelta = new Vector2(610f, 260f); Image obj2 = _placementEditorRoot.AddComponent(); ((Graphic)obj2).color = new Color(0f, 0f, 0f, 0.88f); ((Graphic)obj2).raycastTarget = false; _placementEditorText = CreateOverlayText(_placementEditorRoot.transform, "PlacementEditorMenuText", string.Empty, 16f, Color.white, (TextAlignmentOptions)257); ((TMP_Text)_placementEditorText).enableWordWrapping = false; ((TMP_Text)_placementEditorText).richText = true; ((TMP_Text)_placementEditorText).lineSpacing = -4f; SetRectFill(((TMP_Text)_placementEditorText).rectTransform, new Vector2(22f, 18f), new Vector2(-22f, -18f)); _placementEditorRoot.SetActive(false); } private static ScanLabel CreateCameraScanLabel(Transform parent, int index, string prefix) { //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_0023: 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_004a: 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_0074: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"{prefix}Label_{index}"); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent(); val2.anchorMin = new Vector2(0.5f, 0.5f); val2.anchorMax = new Vector2(0.5f, 0.5f); val2.pivot = new Vector2(0.5f, 0.5f); val2.sizeDelta = new Vector2(58f, 58f); Image val3 = val.AddComponent(); ((Graphic)val3).color = new Color(0f, 0f, 0f, 0f); ((Graphic)val3).raycastTarget = false; Image top = CreateScanMarkerLine(val.transform, "Top"); Image bottom = CreateScanMarkerLine(val.transform, "Bottom"); Image left = CreateScanMarkerLine(val.transform, "Left"); Image right = CreateScanMarkerLine(val.transform, "Right"); Image center = CreateScanMarkerLine(val.transform, "Center"); TextMeshProUGUI val4 = CreateOverlayText(val.transform, "Header", "", 11f, OVERLAY_SCAN_BLUE, (TextAlignmentOptions)514); RectTransform rectTransform = ((TMP_Text)val4).rectTransform; rectTransform.anchorMin = new Vector2(0.5f, 0f); rectTransform.anchorMax = new Vector2(0.5f, 0f); rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(0f, -5f); rectTransform.sizeDelta = new Vector2(150f, 20f); TextMeshProUGUI val5 = CreateOverlayText(val.transform, "SubText", "", 10f, Color.white, (TextAlignmentOptions)514); ((Component)val5).gameObject.SetActive(false); val.SetActive(false); return new ScanLabel { Rect = val2, Background = val3, Top = top, Bottom = bottom, Left = left, Right = right, Center = center, Header = val4, SubText = val5 }; } private static Image CreateScanTracer(Transform parent, int index, string prefix) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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) GameObject val = new GameObject($"{prefix}Tracer_{index}"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); Image obj2 = val.AddComponent(); ((Graphic)obj2).color = new Color(OVERLAY_SCAN_BLUE.r, OVERLAY_SCAN_BLUE.g, OVERLAY_SCAN_BLUE.b, 0.68f); ((Graphic)obj2).raycastTarget = false; val.SetActive(false); return obj2; } private static Image CreateScanMarkerLine(Transform parent, string name) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_004d: 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) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); Image obj2 = val.AddComponent(); ((Graphic)obj2).color = OVERLAY_SCAN_BLUE; ((Graphic)obj2).raycastTarget = false; return obj2; } private static void CreateActivePaneReticle(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0066: 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_0094: 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) //IL_00cd: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("CameraCenterReticle"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); obj.sizeDelta = new Vector2(46f, 46f); _centerReticle = val.AddComponent(); ((Graphic)_centerReticle).color = new Color(0f, 0f, 0f, 0f); ((Graphic)_centerReticle).raycastTarget = false; CreateReticleSegment(val.transform, "Top", new Vector2(0f, 15f), new Vector2(2f, 12f)); CreateReticleSegment(val.transform, "Bottom", new Vector2(0f, -15f), new Vector2(2f, 12f)); CreateReticleSegment(val.transform, "Left", new Vector2(-15f, 0f), new Vector2(12f, 2f)); CreateReticleSegment(val.transform, "Right", new Vector2(15f, 0f), new Vector2(12f, 2f)); CreateReticleSegment(val.transform, "CenterH", Vector2.zero, new Vector2(8f, 1.5f), 0.48f); CreateReticleSegment(val.transform, "CenterV", Vector2.zero, new Vector2(1.5f, 8f), 0.48f); val.SetActive(false); } private static Image CreateReticleSegment(Transform parent, string name, Vector2 position, Vector2 size, float alpha = 0.72f) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_007c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); obj.anchoredPosition = position; obj.sizeDelta = size; Image obj2 = val.AddComponent(); ((Graphic)obj2).color = new Color(0.1f, 1f, 0.35f, alpha); ((Graphic)obj2).raycastTarget = false; return obj2; } private static TextMeshProUGUI CreateOverlayText(Transform parent, string name, string text, float fontSize, Color color, TextAlignmentOptions alignment) { //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_0013: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_005f: 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) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; TextMeshProUGUI obj2 = val.AddComponent(); ((TMP_Text)obj2).text = text; ((TMP_Text)obj2).fontSize = fontSize; ((TMP_Text)obj2).fontStyle = (FontStyles)1; ((TMP_Text)obj2).alignment = alignment; ((Graphic)obj2).color = color; ((TMP_Text)obj2).enableWordWrapping = false; ((TMP_Text)obj2).overflowMode = (TextOverflowModes)0; ((Graphic)obj2).raycastTarget = false; ApplyOverlayFont(obj2); return obj2; } private static void SetRectFill(RectTransform rect, Vector2 offsetMin, Vector2 offsetMax) { //IL_000b: 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_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) if (!((Object)(object)rect == (Object)null)) { rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.offsetMin = offsetMin; rect.offsetMax = offsetMax; } } private static void ApplyActivePaneLayout() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //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_002f: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) if (_overlayPaneRects == null) { return; } for (int i = 0; i < 4; i++) { Vector2 overlayPaneCenter = GetOverlayPaneCenter(i); Vector2 overlayPaneSize = GetOverlayPaneSize(i); RectTransform val = _overlayPaneRects[i]; if ((Object)(object)val != (Object)null) { val.anchoredPosition = overlayPaneCenter; val.sizeDelta = overlayPaneSize; } RectTransform val2 = ((_overlayOutlineRects != null && i < _overlayOutlineRects.Length) ? _overlayOutlineRects[i] : null); if ((Object)(object)val2 != (Object)null) { val2.anchoredPosition = overlayPaneCenter; val2.sizeDelta = new Vector2(overlayPaneSize.x + 6f, overlayPaneSize.y + 6f); if (_overlayPaneFrames != null && i < _overlayPaneFrames.Length) { ApplyPaneFrameLayout(_overlayPaneFrames[i], val2.sizeDelta); } } RectTransform val3 = ((_overlayCameraLabelRects != null && i < _overlayCameraLabelRects.Length) ? _overlayCameraLabelRects[i] : null); if ((Object)(object)val3 != (Object)null) { val3.anchoredPosition = new Vector2(overlayPaneCenter.x - overlayPaneSize.x * 0.5f + 8f, overlayPaneCenter.y + overlayPaneSize.y * 0.5f - 8f); } } } private static void ApplyOverlayFont(TextMeshProUGUI tmp) { if (!((Object)(object)tmp == (Object)null)) { TMP_FontAsset val = ResolveOverlayFontAsset(); if ((Object)(object)val != (Object)null) { ((TMP_Text)tmp).font = val; } } } private static void RefreshOverlayFonts() { ApplyOverlayFont(_overlayHeaderText); ApplyOverlayFont(_overlayPageText); ApplyOverlayFont(_overlayClockText); ApplyOverlayFont(_overlayRecText); ApplyOverlayFont(_overlayActiveText); ApplyOverlayFont(_radarInsetStatus); ApplyOverlayFont(_operatorStatsText); ApplyOverlayFont(_signalLogTitleText); ApplyOverlayFont(_signalLogText); ApplyOverlayFont(_scanStatusText); if (_overlayCameraLabels != null) { for (int i = 0; i < _overlayCameraLabels.Length; i++) { ApplyOverlayFont(_overlayCameraLabels[i]); } } if (_scanLabels != null) { for (int j = 0; j < _scanLabels.Length; j++) { ApplyOverlayFont(_scanLabels[j]?.Header); ApplyOverlayFont(_scanLabels[j]?.SubText); } } } private static TMP_FontAsset ResolveOverlayFontAsset() { try { Terminal target = Object.FindObjectOfType(); TMP_Text val = ReadTerminalTmp(target, "topRightText") ?? ReadTerminalTmp(target, "inputFieldText") ?? ReadTerminalTmp(target, "screenText"); if ((Object)(object)val != (Object)null && (Object)(object)val.font != (Object)null) { return val.font; } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] terminal font read failed: " + ex.Message)); } } try { HUDManager instance = HUDManager.Instance; if ((Object)(object)instance != (Object)null && instance.controlTipLines != null && instance.controlTipLines.Length != 0) { TextMeshProUGUI val2 = instance.controlTipLines[0]; if ((Object)(object)val2 != (Object)null && (Object)(object)((TMP_Text)val2).font != (Object)null) { return ((TMP_Text)val2).font; } } } catch (Exception ex2) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogDebug((object)("[LethalCCTV] HUD control-tip font read failed: " + ex2.Message)); } } try { if ((Object)(object)TMP_Settings.defaultFontAsset != (Object)null) { return TMP_Settings.defaultFontAsset; } } catch (Exception ex3) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogDebug((object)("[LethalCCTV] TMP default font read failed: " + ex3.Message)); } } return null; } private static TMP_Text ReadTerminalTmp(object target, string memberName) { if (target == null || string.IsNullOrEmpty(memberName)) { return null; } Type type = target.GetType(); object obj = null; FieldInfo field = type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { try { obj = field.GetValue(target); } catch { obj = null; } } if (obj == null) { PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { try { obj = property.GetValue(target); } catch { obj = null; } } } TMP_Text val = (TMP_Text)((obj is TMP_Text) ? obj : null); if (val != null) { return val; } TMP_InputField val2 = (TMP_InputField)((obj is TMP_InputField) ? obj : null); if (val2 != null) { return val2.textComponent; } return null; } private static void RefreshRadarInsetTexture() { if ((Object)(object)_radarInsetImage == (Object)null || Time.unscaledTime < _nextRadarInsetRefreshTime) { return; } _nextRadarInsetRefreshTime = Time.unscaledTime + 0.2f; Texture val = RadarOverlay.ResolveMapTexture(); if ((Object)(object)_radarInsetImage.texture != (Object)(object)val) { _radarInsetImage.texture = val; } if ((Object)(object)_radarInsetStatus != (Object)null) { string text = (((Object)(object)val != (Object)null) ? RadarOverlay.GetActiveInteriorFloorLabel() : "RADAR WAITING"); if (((TMP_Text)_radarInsetStatus).text != text) { ((TMP_Text)_radarInsetStatus).text = text; } } } private static void RefreshSignalLogPanel(bool force) { if (!((Object)(object)_signalLogText == (Object)null) && (force || !(Time.unscaledTime < _nextSignalLogRefreshTime))) { _nextSignalLogRefreshTime = Time.unscaledTime + 0.85f; CCTVCamera activeCamera = GetActiveCamera(); string text = (((Object)(object)activeCamera != (Object)null) ? activeCamera.ResolvedLabel : "NO CAMERA"); string text2 = (((Object)(object)_cameraAudioProxyListener != (Object)null && ((Behaviour)_cameraAudioProxyListener).enabled && (Object)(object)activeCamera != (Object)null) ? activeCamera.ResolvedLabel : "LOCAL"); string text3 = ((QuadCameraAssignment.TotalPages > 0) ? (QuadCameraAssignment.CurrentPage + 1 + "/" + QuadCameraAssignment.TotalPages) : "0/0"); ((TMP_Text)_signalLogText).text = "LINK " + text + "\nPAGE " + text3 + "\nRADAR MAP READY\nAUDIO " + text2 + "\nCMD PORT DIRECT\nHACK BUS IDLE"; } } private static void RefreshOperatorStats(bool force) { if (!((Object)(object)_operatorStatsText == (Object)null) && (force || !(Time.unscaledTime < _nextStatsRefreshTime))) { _nextStatsRefreshTime = Time.unscaledTime + 0.5f; RadarOverlay.StatsSnapshot statsSnapshot = RadarOverlay.CollectStats(); CCTVCamera activeCamera = GetActiveCamera(); string text = (((Object)(object)_cameraAudioProxyListener != (Object)null && ((Behaviour)_cameraAudioProxyListener).enabled && (Object)(object)activeCamera != (Object)null) ? activeCamera.ResolvedLabel : "LOCAL"); string text2 = (CCTVWalkieTalkieBridge.IsTransmitting ? "TX" : (CCTVWalkieTalkieBridge.IsListening ? "READY" : "OFF")); if (IsTurretPageActive) { ((TMP_Text)_operatorStatsText).text = ShipTurretController.BuildStatsBlock(text2); return; } string text3 = (((Object)(object)activeCamera != (Object)null) ? FormatZoom(activeCamera) : "1.0X"); ((TMP_Text)_operatorStatsText).text = "INTERIOR\nSCRAP $" + statsSnapshot.FacilityScrapValue + "\nPLAYERS " + statsSnapshot.LiveInteriorPlayers + "\nHOSTILES " + statsSnapshot.LiveInteriorEnemies + "\nAUDIO " + text + "\nZOOM " + text3 + "\nWALKIE " + text2; } } private static void LogFocusRenderDiagnostics() { try { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] --- focus render diagnostics ---"); } Camera[] allCameras = Camera.allCameras; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)$"[LethalCCTV] enabled cameras: {allCameras.Length}"); } for (int i = 0; i < allCameras.Length; i++) { Camera val = allCameras[i]; if (!((Object)(object)val == (Object)null)) { string arg = (((Object)(object)val.targetTexture != (Object)null) ? $"{((Object)val.targetTexture).name} {((Texture)val.targetTexture).width}x{((Texture)val.targetTexture).height}" : ""); ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)($"[LethalCCTV] cam[{i}] '{GetTransformPath(((Component)val).transform)}' target={arg} " + $"cullingMask=0x{val.cullingMask:X8} fov={val.fieldOfView:F0} ortho={val.orthographic}")); } } } for (int j = 0; j < 4; j++) { CCTVCamera boundCamera = QuadCameraAssignment.GetBoundCamera(j); if (!((Object)(object)boundCamera == (Object)null) && !((Object)(object)boundCamera.Cam == (Object)null)) { RenderTexture targetTexture = boundCamera.Cam.targetTexture; string text = (((Object)(object)targetTexture != (Object)null) ? $"{((Object)targetTexture).name} {((Texture)targetTexture).width}x{((Texture)targetTexture).height}" : ""); ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogInfo((object)$"[LethalCCTV] cctv slot[{j}] '{boundCamera.ResolvedLabel}' camEnabled={((Behaviour)boundCamera.Cam).enabled} target={text}"); } } } float num = ((SurveillanceBootstrap.Config?.RenderHzPerMonitor != null) ? ((float)SurveillanceBootstrap.Config.RenderHzPerMonitor.Value) : (-1f)); float num2 = ((SurveillanceBootstrap.Config?.InactivePaneRenderHz != null) ? ((float)SurveillanceBootstrap.Config.InactivePaneRenderHz.Value) : (-1f)); bool flag = SurveillanceBootstrap.Config?.DynamicActiveRendererEnabled != null && SurveillanceBootstrap.Config.DynamicActiveRendererEnabled.Value; int num3 = ((SurveillanceBootstrap.Config?.RenderRTWidth != null) ? SurveillanceBootstrap.Config.RenderRTWidth.Value : (-1)); float num4 = ((num > 0f) ? Mathf.Min(num, 24f) : (-1f)); float num5 = ((num4 > 0f) ? Mathf.Min(24f, Mathf.Max(num4, num4 * 1.8f)) : (-1f)); ManualLogSource log5 = SurveillanceBootstrap.Log; if (log5 != null) { log5.LogInfo((object)($"[LethalCCTV] cctv throttle: stationBase={num4:F1}fps stationBurst={num5:F1}fps stationInactiveSlots=disabled " + $"renderHzPerMonitor={num:F1} inactivePaneHz={num2:F1} dynamicActive={flag} quadRtWidth={num3}")); } ManualLogSource log6 = SurveillanceBootstrap.Log; if (log6 != null) { log6.LogInfo((object)("[LethalCCTV] " + CCTVVanillaMonitorDisplay.GetRenderDiagnostics())); } ManualLogSource log7 = SurveillanceBootstrap.Log; if (log7 != null) { log7.LogInfo((object)("[LethalCCTV] " + VanillaRadarFeed.GetRenderDiagnostics())); } ManualLogSource log8 = SurveillanceBootstrap.Log; if (log8 != null) { log8.LogInfo((object)($"[LethalCCTV] focusUiCamEnabled={(Object)(object)_physicalFocusUiCamera != (Object)null && ((Behaviour)_physicalFocusUiCamera).enabled} " + $"legacyOverlayActive={(Object)(object)_overlayRoot != (Object)null && _overlayRoot.activeSelf} " + $"focusRT={1920}x{1440} (legacy path only)")); } ManualLogSource log9 = SurveillanceBootstrap.Log; if (log9 != null) { log9.LogInfo((object)"[LethalCCTV] --- end focus render diagnostics ---"); } } catch (Exception ex) { ManualLogSource log10 = SurveillanceBootstrap.Log; if (log10 != null) { log10.LogDebug((object)("[LethalCCTV] Focus render diagnostics failed: " + ex.Message)); } } } private static void UpdateCameraScanOverlay() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) if (_scanLabels == null) { return; } bool flag = _contextTarget != null && Time.unscaledTime <= _contextTarget.ExpiresAt; if (!IsFocused || (Time.unscaledTime > _scanVisibleUntil && !flag)) { HideCameraScanOverlay(); return; } CCTVCamera activeCamera = GetActiveCamera(); Camera val = (((Object)(object)activeCamera != (Object)null) ? activeCamera.Cam : null); if ((Object)(object)val == (Object)null) { HideScanLabels(); return; } Vector2 overlayPaneCenter = GetOverlayPaneCenter(ActiveSlot); Vector2 overlayPaneSize = GetOverlayPaneSize(ActiveSlot); if ((Object)(object)_scanStatusText != (Object)null) { ((TMP_Text)_scanStatusText).rectTransform.anchoredPosition = new Vector2(overlayPaneCenter.x, overlayPaneCenter.y - overlayPaneSize.y * 0.5f + 24f); } int num = 0; if (flag && num < _scanLabels.Length) { UpdateContextLabel(_scanLabels[num], _contextTarget, val, overlayPaneCenter); num++; } for (int i = num; i < _scanLabels.Length; i++) { SetScanLabelActive(_scanLabels[i], active: false); } } private static void UpdateContextLabel(ScanLabel label, ContextTarget target, Camera cam, Vector2 paneCenter) { //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_001c: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0050: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00c9: 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_00df: 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_0112: 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_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: 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_01ef: Unknown result type (might be due to invalid IL or missing references) if (label != null && target != null && !((Object)(object)cam == (Object)null)) { Vector3 val = cam.WorldToViewportPoint(target.Position); if (val.z <= 0f) { SetScanLabelActive(label, active: false); return; } Vector2 overlayPaneSize = GetOverlayPaneSize(ActiveSlot); float num = paneCenter.x - overlayPaneSize.x * 0.5f + val.x * overlayPaneSize.x; float num2 = paneCenter.y - overlayPaneSize.y * 0.5f + val.y * overlayPaneSize.y; float num3 = 95f; float num4 = 24f; num = Mathf.Clamp(num, paneCenter.x - overlayPaneSize.x * 0.5f + num3, paneCenter.x + overlayPaneSize.x * 0.5f - num3); num2 = Mathf.Clamp(num2, paneCenter.y - overlayPaneSize.y * 0.5f + num4, paneCenter.y + overlayPaneSize.y * 0.5f - num4); label.Rect.anchoredPosition = new Vector2(num, num2); float num5 = Mathf.Max(1f, Vector3.Distance(((Component)cam).transform.position, target.Position)); float num6 = Mathf.Clamp(target.Radius / num5 * GetOverlayPaneSize(ActiveSlot).x * 1.9f, 34f, 96f); label.Rect.sizeDelta = new Vector2(num6, num6); ((TMP_Text)label.Header).text = target.DisplayName; ((Graphic)label.Header).color = target.Color; ((Graphic)label.Background).color = new Color(target.Color.r, target.Color.g, target.Color.b, target.Commandable ? 0.12f : 0.08f); ApplyScanMarkerShape(label, target.Color, num6); UpdateScanTracer(label.Tracer, paneCenter, label.Rect.anchoredPosition); SetScanLabelActive(label, active: true); } } private static void UpdateScanTracer(Image tracer, Vector2 paneCenter, Vector2 markerPosition) { //IL_000a: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) //IL_0036: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)tracer == (Object)null)) { Vector2 val = markerPosition - paneCenter; float magnitude = ((Vector2)(ref val)).magnitude; if (magnitude < 18f) { ((Component)tracer).gameObject.SetActive(false); return; } Vector2 val2 = val / magnitude; float num = Mathf.Clamp(magnitude * 0.22f, 18f, 76f); RectTransform rectTransform = ((Graphic)tracer).rectTransform; rectTransform.anchoredPosition = markerPosition - val2 * (num * 0.5f + 12f); rectTransform.sizeDelta = new Vector2(num, 3f); ((Transform)rectTransform).localEulerAngles = new Vector3(0f, 0f, Mathf.Atan2(val.y, val.x) * 57.29578f); ((Graphic)tracer).color = new Color(OVERLAY_SCAN_BLUE.r, OVERLAY_SCAN_BLUE.g, OVERLAY_SCAN_BLUE.b, 0.26f); ((Component)tracer).gameObject.SetActive(true); } } private static void ApplyScanMarkerShape(ScanLabel label, Color color, float size) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) if (label != null) { float num = size * 0.5f; float num2 = 4f; float num3 = Mathf.Clamp(size * 0.34f, 12f, 30f); SetScanMarkerLine(label.Top, new Vector2(0f - num + num3 * 0.5f, num), new Vector2(num3, num2), color); SetScanMarkerLine(label.Left, new Vector2(0f - num, num - num3 * 0.5f), new Vector2(num2, num3), color); SetScanMarkerLine(label.Bottom, new Vector2(num - num3 * 0.5f, 0f - num), new Vector2(num3, num2), color); SetScanMarkerLine(label.Right, new Vector2(num, 0f - num + num3 * 0.5f), new Vector2(num2, num3), color); SetScanMarkerLine(label.Center, Vector2.zero, new Vector2(4f, 4f), new Color(color.r, color.g, color.b, 0.7f)); if ((Object)(object)label.Header != (Object)null) { ((TMP_Text)label.Header).rectTransform.anchoredPosition = new Vector2(0f, 0f - num - 5f); } } } private static void SetScanMarkerLine(Image image, Vector2 position, Vector2 size, Color color) { //IL_0011: 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_001e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)image == (Object)null)) { RectTransform rectTransform = ((Graphic)image).rectTransform; rectTransform.anchoredPosition = position; rectTransform.sizeDelta = size; ((Graphic)image).color = color; } } private static Color ColorForScanNode(ScanNodeProperties node) { //IL_0009: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)node == (Object)null) { return OVERLAY_SCAN_BLUE; } if (node.nodeType == 2) { return OVERLAY_AMBER; } if (node.creatureScanID >= 0) { return OVERLAY_SCAN_RED; } return OVERLAY_SCAN_BLUE; } private static void ShowScanStatus(string text, Color color) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_scanStatusText == (Object)null)) { ((TMP_Text)_scanStatusText).text = text; ((Graphic)_scanStatusText).color = color; ((Component)_scanStatusText).gameObject.SetActive(true); } } private static void ShowTimedScanStatus(string text, Color color, float seconds) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) _scanVisibleUntil = Time.unscaledTime + Mathf.Max(0.1f, seconds); ShowScanStatus(text, color); UpdateCameraScanOverlay(); } private static bool FocusCamera(CCTVCamera camera, string reason) { if ((Object)(object)camera == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] FocusCamera failed reason=" + reason + " camera=null.")); } return false; } if (!QuadCameraAssignment.TrySelectCamera(camera, out var slot)) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)$"[LethalCCTV] FocusCamera failed reason={reason} camera='{DescribeCameraForLog(camera)}' activeSlot={ActiveSlot} active='{DescribeCameraForLog(GetActiveCamera())}'."); } return false; } SetActiveSlot(slot); BoostStationCameraRenderCadence(0.25f); RefreshOperatorStats(force: true); ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)$"[LethalCCTV] FocusCamera reason={reason} camera='{DescribeCameraForLog(camera)}' page={QuadCameraAssignment.CurrentPage + 1}/{QuadCameraAssignment.TotalPages} slot={slot} active='{DescribeCameraForLog(GetActiveCamera())}'."); } return GetActiveCamera() == camera; } private static string DescribeCameraForLog(CCTVCamera camera) { //IL_002a: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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) if ((Object)(object)camera == (Object)null) { return ""; } Vector3 val = (((Object)(object)((Component)camera).transform != (Object)null) ? ((Component)camera).transform.position : Vector3.zero); return $"{camera.ResolvedLabel}#{camera.CameraIndex}@{val.x:F1},{val.y:F1},{val.z:F1}"; } private static void HideCameraScanOverlay() { _scanVisibleUntil = 0f; _contextTarget = null; HideScanLabels(); if ((Object)(object)_scanStatusText != (Object)null) { ((Component)_scanStatusText).gameObject.SetActive(false); } } private static void HideScanLabels() { if (_scanLabels != null) { for (int i = 0; i < _scanLabels.Length; i++) { SetScanLabelActive(_scanLabels[i], active: false); } } } private static void SetScanLabelActive(ScanLabel label, bool active) { if (!((Object)(object)label?.Rect == (Object)null)) { ((Component)label.Rect).gameObject.SetActive(active); if ((Object)(object)label.Tracer != (Object)null) { ((Component)label.Tracer).gameObject.SetActive(active); } } } private static void UpdateActivePaneReticle() { //IL_003a: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_centerReticle == (Object)null)) { ((Component)_centerReticle).gameObject.SetActive(IsFocused); if (IsFocused) { RectTransform rectTransform = ((Graphic)_centerReticle).rectTransform; rectTransform.anchoredPosition = GetOverlayPaneCenter(ActiveSlot); bool flag = IsTurretPageActive && Time.unscaledTime <= _turretHitmarkerUntil; rectTransform.sizeDelta = (flag ? new Vector2(62f, 62f) : new Vector2(46f, 46f)); SetReticleColor((!flag) ? OVERLAY_ACTIVE_GREEN : (_turretHitmarkerEnemy ? OVERLAY_SCAN_RED : OVERLAY_AMBER), flag ? 0.95f : 0.72f); } } } internal static void ShowTurretHitmarker(bool enemyHit) { _turretHitmarkerEnemy = enemyHit; _turretHitmarkerUntil = Time.unscaledTime + 0.22f; UpdateActivePaneReticle(); } private static void SetReticleColor(Color color, float alpha) { //IL_0056: 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_0062: 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)_centerReticle == (Object)null) { return; } Image[] componentsInChildren = ((Component)_centerReticle).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (!((Object)(object)componentsInChildren[i] == (Object)null) && componentsInChildren[i] != _centerReticle) { float num = (((Object)componentsInChildren[i]).name.StartsWith("Center", StringComparison.OrdinalIgnoreCase) ? (alpha * 0.66f) : alpha); ((Graphic)componentsInChildren[i]).color = new Color(color.r, color.g, color.b, num); } } } internal static bool TryGetApiOperatorFloorRootDelta(out float worldDeltaY) { worldDeltaY = _stationPlayerPoseFloorDeltaWorldY; if (_stationPlayerPoseLockActive) { return _stationPlayerPoseUsesApiFloorRoot; } return false; } private static void BoostStationCameraRenderCadence(float seconds = 0.2f) { if (IsFocused) { float num = Time.unscaledTime + Mathf.Max(0f, seconds); if (num > _stationCameraRenderBoostUntil) { _stationCameraRenderBoostUntil = num; } } } private static void BeginStationPlayerPoseTracking(PlayerControllerB player) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: 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_0117: 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_012e: 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_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) if (_stationPlayerPoseLockActive) { RestoreStationPlayerPoseTracking("station-reentry"); } if ((Object)(object)player == (Object)null) { return; } Transform operatorPoseAnchor = CCTVOperatorStation.OperatorPoseAnchor; if ((Object)(object)operatorPoseAnchor == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Station player pose lock skipped: CCTVStationOperatorPoseAnchor is missing."); } return; } try { bool flag = _stationPoseSettleTransferToFocus && _stationPoseSettleSnapshot.Valid && _stationPoseSettleSnapshot.Player == player; StationPlayerPoseSnapshot stationPlayerPoseSnapshot = (flag ? _stationPoseSettleSnapshot : CaptureStationPlayerPoseSnapshot(player)); if (!stationPlayerPoseSnapshot.Valid) { throw new InvalidOperationException("station pose snapshot unavailable"); } bool useInteractionsApiOperatorSession = Y4NGZPlayerAnimationBridge.UseInteractionsApiOperatorSession; bool num = useInteractionsApiOperatorSession && Y4NGZPlayerAnimationBridge.UseApiOperatorRootAtFloorLevel; Transform playerRootAnchor = CCTVOperatorStation.PlayerRootAnchor; bool flag2 = num && (Object)(object)playerRootAnchor != (Object)null && playerRootAnchor != operatorPoseAnchor; if (num && !flag2) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)"[LethalCCTV][ApiPose] floor root requested but a distinct CCTVStationPlayerRootAnchor is unavailable; using OperatorPoseAnchor."); } } float num2 = (flag ? _stationPoseSettleTargetPosition.y : stationPlayerPoseSnapshot.Position.y); ? stationPlayerPoseTargetPosition = (flag2 ? new Vector3(playerRootAnchor.position.x, num2, playerRootAnchor.position.z) : operatorPoseAnchor.position); Quaternion stationPlayerPoseTargetRotation = (flag2 ? Quaternion.Euler(0f, operatorPoseAnchor.eulerAngles.y, 0f) : operatorPoseAnchor.rotation); Vector3 position = ((Component)player).transform.position; _stationPlayerPosePlayer = player; _stationPlayerPoseTargetPosition = (Vector3)stationPlayerPoseTargetPosition; _stationPlayerPoseTargetRotation = stationPlayerPoseTargetRotation; _stationPlayerPoseTargetAnchorKind = (flag2 ? "player-root-grounded-y+operator-pose-yaw" : "operator-pose"); _stationPlayerPoseApiModeConfigured = useInteractionsApiOperatorSession; _stationPlayerPoseUsesApiFloorRoot = flag2; _stationPlayerPoseFloorDeltaWorldY = 0f; _stationPlayerPoseNextRootTelemetryAt = float.PositiveInfinity; _stationPlayerPoseSavedPosition = stationPlayerPoseSnapshot.Position; _stationPlayerPoseSavedRotation = stationPlayerPoseSnapshot.Rotation; _stationPlayerPoseHandbackRotation = (flag ? FlattenToYaw(_stationPoseSettleTargetRotation) : FlattenToYaw(((Component)player).transform.rotation)); _stationPlayerPoseHandbackCameraPitch = 0f; _stationPlayerPoseSavedServerPosition = stationPlayerPoseSnapshot.ServerPosition; _stationPlayerPoseSavedSnapToServerPosition = stationPlayerPoseSnapshot.SnapToServerPosition; _stationPlayerPoseSavedDisableSyncInAnimation = stationPlayerPoseSnapshot.DisableSyncInAnimation; _stationPlayerPoseSavedFreeRotationInInteractAnimation = stationPlayerPoseSnapshot.FreeRotationInInteractAnimation; _stationPlayerPoseSavedInSpecialInteractAnimation = stationPlayerPoseSnapshot.InSpecialInteractAnimation; _stationPlayerPoseSavedEnteringSpecialAnimation = stationPlayerPoseSnapshot.EnteringSpecialAnimation; _stationPlayerPoseHadController = stationPlayerPoseSnapshot.HadController; _stationPlayerPoseSavedControllerDetectCollisions = stationPlayerPoseSnapshot.ControllerDetectCollisions; _stationPlayerPoseSavedControllerEnabled = stationPlayerPoseSnapshot.ControllerEnabled; _stationPlayerPoseSavedWasCrouching = stationPlayerPoseSnapshot.WasCrouching; _stationPlayerCameraBaselineCaptured = stationPlayerPoseSnapshot.CameraBaselineCaptured; _stationPlayerCameraPlayerLocalPosition = stationPlayerPoseSnapshot.CameraPlayerLocalPosition; ArmStationPlayerCameraStabilizer(player); _stationPlayerPoseLockActive = true; ApplyStationPlayerPoseLock(); if (_stationPlayerPoseLockActive && UseExitToStationPose) { _stationPlayerPoseSavedPosition = ((Component)player).transform.position; _stationPlayerPoseSavedRotation = ((Component)player).transform.rotation; _stationPlayerPoseSavedServerPosition = ((Component)player).transform.localPosition; } if (_stationPlayerPoseLockActive && useInteractionsApiOperatorSession) { Vector3 position2 = ((Component)player).transform.position; _stationPlayerPoseFloorDeltaWorldY = (flag2 ? (operatorPoseAnchor.position.y - position2.y) : 0f); ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)("[LethalCCTV][ApiPose] root-snap anchor=" + _stationPlayerPoseTargetAnchorKind + " preRootWorld=" + FormatDebugVector(position) + " postRootWorld=" + FormatDebugVector(position2) + " delta=" + FormatDebugVector(position2 - position) + " " + $"poseAnchorWorldY={operatorPoseAnchor.position.y:F3} " + $"floorDeltaWorldY={_stationPlayerPoseFloorDeltaWorldY:F3} " + $"targetYaw={((Quaternion)(ref stationPlayerPoseTargetRotation)).eulerAngles.y:F1}.")); } _stationPlayerPoseNextRootTelemetryAt = Time.unscaledTime + 1f; } if (!_stationPoseTrackingLogged) { _stationPoseTrackingLogged = true; ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogInfo((object)("[LethalCCTV] Station player pose lock active: targetAnchor=" + _stationPlayerPoseTargetAnchorKind + ", targetWorld=" + FormatDebugVector(_stationPlayerPoseTargetPosition) + ", operatorPose=" + FormatDebugVector(operatorPoseAnchor.position) + ", savedWorld=" + FormatDebugVector(_stationPlayerPoseSavedPosition) + ", cameraPlayerLocal=" + (_stationPlayerCameraBaselineCaptured ? FormatDebugVector(_stationPlayerCameraPlayerLocalPosition) : "") + ".")); } } } catch (Exception ex) { ManualLogSource log5 = SurveillanceBootstrap.Log; if (log5 != null) { log5.LogWarning((object)("[LethalCCTV] Station player pose lock failed to start: " + ex.Message)); } RestoreStationPlayerPoseTracking("begin-failed"); } } private static void EndStationPlayerPoseTracking() { RestoreStationPlayerPoseTracking("end"); } private static void ArmStationPlayerCameraStabilizer(PlayerControllerB player) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) _stationPlayerCameraPositionStabilizer = null; if (!_stationPlayerCameraBaselineCaptured || (Object)(object)player == (Object)null || (Object)(object)player.gameplayCamera == (Object)null) { return; } try { GameObject gameObject = ((Component)player.gameplayCamera).gameObject; _stationPlayerCameraPositionStabilizer = gameObject.GetComponent(); if ((Object)(object)_stationPlayerCameraPositionStabilizer == (Object)null) { _stationPlayerCameraPositionStabilizer = gameObject.AddComponent(); } _stationPlayerCameraPositionStabilizer.Initialize(player, ((Component)player).transform, ((Component)player.gameplayCamera).transform, _stationPlayerCameraPlayerLocalPosition); } catch (Exception ex) { _stationPlayerCameraPositionStabilizer = null; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Station camera baseline guard failed to arm: " + ex.Message)); } } } private static void ApplyStationPlayerPoseLock() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) if (!_stationPlayerPoseLockActive) { return; } PlayerControllerB stationPlayerPosePlayer = _stationPlayerPosePlayer; if ((Object)(object)stationPlayerPosePlayer == (Object)null) { return; } try { ((Component)stationPlayerPosePlayer).transform.SetPositionAndRotation(_stationPlayerPoseTargetPosition, _stationPlayerPoseTargetRotation); stationPlayerPosePlayer.serverPlayerPosition = ((Component)stationPlayerPosePlayer).transform.localPosition; stationPlayerPosePlayer.snapToServerPosition = false; stationPlayerPosePlayer.disableSyncInAnimation = true; stationPlayerPosePlayer.freeRotationInInteractAnimation = true; stationPlayerPosePlayer.inSpecialInteractAnimation = true; stationPlayerPosePlayer.enteringSpecialAnimation = false; if (stationPlayerPosePlayer.isCrouching) { stationPlayerPosePlayer.Crouch(false); } stationPlayerPosePlayer.ResetFallGravity(); if (_stationPlayerPoseApiModeConfigured && Time.unscaledTime >= _stationPlayerPoseNextRootTelemetryAt) { _stationPlayerPoseNextRootTelemetryAt = Time.unscaledTime + 1f; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ApiPose] root-world anchor=" + _stationPlayerPoseTargetAnchorKind + " world=" + FormatDebugVector(((Component)stationPlayerPosePlayer).transform.position) + " target=" + FormatDebugVector(_stationPlayerPoseTargetPosition) + " " + $"residual={Vector3.Distance(((Component)stationPlayerPosePlayer).transform.position, _stationPlayerPoseTargetPosition):F4}m.")); } } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Station player pose lock failed while focused: " + ex.Message)); } RestoreStationPlayerPoseTracking("lock-failed"); } } private static void RestoreStationPlayerPoseTracking(string reason) { //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022a: 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_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: 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_005c: 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_006c: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB stationPlayerPosePlayer = _stationPlayerPosePlayer; if (_stationPlayerPoseLockActive && (Object)(object)stationPlayerPosePlayer != (Object)null) { try { if (_stationPlayerPoseHadController && (Object)(object)stationPlayerPosePlayer.thisController != (Object)null) { stationPlayerPosePlayer.thisController.detectCollisions = _stationPlayerPoseSavedControllerDetectCollisions; ((Collider)stationPlayerPosePlayer.thisController).enabled = _stationPlayerPoseSavedControllerEnabled; } ((Component)stationPlayerPosePlayer).transform.SetPositionAndRotation(_stationPlayerPoseSavedPosition, _stationPlayerPoseHandbackRotation); stationPlayerPosePlayer.serverPlayerPosition = _stationPlayerPoseSavedServerPosition; stationPlayerPosePlayer.snapToServerPosition = _stationPlayerPoseSavedSnapToServerPosition; stationPlayerPosePlayer.disableSyncInAnimation = _stationPlayerPoseSavedDisableSyncInAnimation; stationPlayerPosePlayer.freeRotationInInteractAnimation = _stationPlayerPoseSavedFreeRotationInInteractAnimation; stationPlayerPosePlayer.inSpecialInteractAnimation = _stationPlayerPoseSavedInSpecialInteractAnimation; stationPlayerPosePlayer.enteringSpecialAnimation = _stationPlayerPoseSavedEnteringSpecialAnimation; if (stationPlayerPosePlayer.isCrouching != _stationPlayerPoseSavedWasCrouching) { stationPlayerPosePlayer.Crouch(_stationPlayerPoseSavedWasCrouching); } if (!_stationPlayerPoseSavedInSpecialInteractAnimation) { stationPlayerPosePlayer.UpdateSpecialAnimationValue(false, (short)0, 0f, false); } stationPlayerPosePlayer.ResetFallGravity(); if (_stationPlayerCameraBaselineCaptured && (Object)(object)stationPlayerPosePlayer.gameplayCamera != (Object)null) { ((Component)stationPlayerPosePlayer.gameplayCamera).transform.position = ((Component)stationPlayerPosePlayer).transform.TransformPoint(_stationPlayerCameraPlayerLocalPosition); } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Station player pose restored (" + reason + ") world=" + FormatDebugVector(((Component)stationPlayerPosePlayer).transform.position) + " " + $"bodyYaw={((Component)stationPlayerPosePlayer).transform.eulerAngles.y:F1}.")); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Station player pose restore failed (" + reason + "): " + ex.Message)); } } } CCTVLocalCameraPositionStabilizer stationPlayerCameraPositionStabilizer = _stationPlayerCameraPositionStabilizer; _stationPlayerCameraPositionStabilizer = null; if ((Object)(object)stationPlayerCameraPositionStabilizer != (Object)null) { try { stationPlayerCameraPositionStabilizer.ApplyNow(); stationPlayerCameraPositionStabilizer.ReleaseAfterLateUpdates(2); ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)"[LethalCCTV] Station camera baseline guard activated after pose restore; it will hold through controller restore, then release across 2 final LateUpdates before the deferred vanilla rig rebuild."); } } catch (Exception ex2) { ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogWarning((object)("[LethalCCTV] Station camera baseline guard release failed (" + reason + "): " + ex2.Message)); } } } _stationViewpointChannelOverrideActive = false; _stationPlayerPoseLockActive = false; _stationPlayerPosePlayer = null; _stationPlayerPoseTargetPosition = Vector3.zero; _stationPlayerPoseTargetRotation = Quaternion.identity; _stationPlayerPoseTargetAnchorKind = null; _stationPlayerPoseApiModeConfigured = false; _stationPlayerPoseUsesApiFloorRoot = false; _stationPlayerPoseFloorDeltaWorldY = 0f; _stationPlayerPoseNextRootTelemetryAt = 0f; _stationPlayerPoseSavedPosition = Vector3.zero; _stationPlayerPoseSavedRotation = Quaternion.identity; _stationPlayerPoseHandbackRotation = Quaternion.identity; _stationPlayerPoseHandbackCameraPitch = 0f; _stationPlayerPoseSavedServerPosition = Vector3.zero; _stationPlayerPoseSavedSnapToServerPosition = false; _stationPlayerPoseSavedDisableSyncInAnimation = false; _stationPlayerPoseSavedFreeRotationInInteractAnimation = false; _stationPlayerPoseSavedInSpecialInteractAnimation = false; _stationPlayerPoseSavedEnteringSpecialAnimation = false; _stationPlayerPoseHadController = false; _stationPlayerPoseSavedControllerDetectCollisions = false; _stationPlayerPoseSavedControllerEnabled = false; _stationPlayerPoseSavedWasCrouching = false; _stationPlayerCameraBaselineCaptured = false; _stationPlayerCameraPlayerLocalPosition = Vector3.zero; _stationPlayerCameraPositionStabilizer = null; _stationPoseTrackingLogged = false; } private static void BeginPhysicalFocusView(PlayerControllerB player) { //IL_0062: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_0087: 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_0092: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: 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_0170: 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_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player.gameplayCamera == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Physical focus view: gameplay camera unavailable; staying in normal player camera pose."); } return; } Camera val = (_physicalFocusCamera = player.gameplayCamera); _physicalFocusCameraTransform = ((Component)val).transform; bool num = _stationPoseSettleTransferToFocus && _stationPoseSettleEntryCameraPoseCaptured && _stationPoseSettlePlayer == player; Vector3 position = _physicalFocusCameraTransform.position; Vector3 startPosition = (num ? _stationPoseSettleEntryCameraWorldPosition : position); Quaternion val2 = (num ? _stationPoseSettleEntryCameraWorldRotation : _physicalFocusCameraTransform.rotation); _priorFocusCameraLocalPosition = _physicalFocusCameraTransform.localPosition; _priorFocusCameraLocalRotation = _physicalFocusCameraTransform.localRotation; _priorFocusCameraWorldPosition = position; _priorFocusCameraWorldRotation = val2; _priorFocusCameraFov = val.fieldOfView; _physicalFocusViewActive = true; _exitCameraInvariantPlayer = null; _exitCameraInvariantScheduledFrame = -1; CaptureFirstPersonArmsCameraPose(player); EntryPerfMark("BPFV.capture-arms-pose"); if (!HasActiveLocalPlayerObstructors()) { _localObstructorCallLogs.Clear(); _visorSnapProbeLogsRemaining = 3; } SuppressLocalPlayerObstructors(player, "focus-view-begin"); EntryPerfMark("BPFV.suppress-obstructors"); ArmLocalFirstPersonArmsPresentation(player); EntryPerfMark("BPFV.arm-first-person-arms"); Transform focusViewAnchor = CCTVOperatorStation.FocusViewAnchor; if ((Object)(object)focusViewAnchor != (Object)null) { ResolveStationFocusCameraPose(focusViewAnchor, out var position2, out var rotation); EntryPerfMark("BPFV.resolve-station-pose"); StartFocusViewAnimation(startPosition, val2, val.fieldOfView, position2, rotation, GetPreservedFocusFov(), 1.1f, exiting: false); EntryPerfMark("BPFV.start-focus-view-animation"); BuildStationEnterCameraPath(player, startPosition, val2, position2, rotation); EntryPerfMark("BPFV.build-enter-camera-path"); _introCameraRenderedFramesLogged = 0; _introCameraLastRenderedFrame = -1; LogIntroCameraPose("enter-start-knot", _focusViewAnimationStartPosition, _focusViewAnimationStartRotation); ApplyPhysicalFocusView(); EntryPerfMark("BPFV.apply-physical-focus-view"); } else { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)"[LethalCCTV] Physical focus view: CCTVFocusViewAnchor missing from terminal prefab; falling back to FOV-only focus."); } ApplyPhysicalFocusView(); } } private static void BuildStationEnterCameraPath(PlayerControllerB player, Vector3 startPosition, Quaternion startRotation, Vector3 focusPosition, Quaternion focusRotation) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0058: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: 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_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: 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_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0190: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_024e: 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_0256: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) _focusViewEnterPath = null; ResetStationIntroHandFollow(); Transform val = (((Object)(object)CCTVOperatorStation.RightHandTarget != (Object)null) ? CCTVOperatorStation.RightHandTarget : CCTVOperatorStation.JoystickTiltPivot); Vector3? val2 = Y4NGZPlayerAnimationBridge.ResolveAccessButtonPressPoint(); if (!val2.HasValue || (Object)(object)val == (Object)null) { if ((Object)(object)val != (Object)null) { Vector3 val3 = Vector3.Lerp(startPosition, focusPosition, 0.5f); Vector3 val4 = val.position - val3; if (((Vector3)(ref val4)).sqrMagnitude > 0.01f) { _focusViewWaypointPosition = val3; _focusViewWaypointRotation = Quaternion.LookRotation(((Vector3)(ref val4)).normalized, Vector3.up); _focusViewAnimationHasWaypoint = true; } } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Enter camera path fallback (button=" + (val2.HasValue ? "ok" : "missing") + ", lever=" + (((Object)(object)val != (Object)null) ? "ok" : "missing") + "); using single-waypoint sweep.")); } return; } string text = "live-start"; Vector3 val5 = startPosition; if (TryResolveCanonicalStationStandEye(player, out var standEye)) { val5 = standEye; text = "canonical-stand"; } Vector3 val6 = Vector3.Lerp(val5, focusPosition, 0.4f); float anchorDistance; Vector3 val7 = ResolveEnterLeanEye(val6, val2.Value, 0.6f, out anchorDistance); Vector3 val8 = val2.Value - val7; Vector3 lookDirection = val.position - focusPosition; if (((Vector3)(ref val8)).sqrMagnitude < 0.0025f || ((Vector3)(ref lookDirection)).sqrMagnitude < 0.0025f) { return; } float num = Vector3.Distance(ComputeApiAnchorWorldForEye(focusPosition, lookDirection), val.position); float num2 = Vector3.Distance(ComputeApiAnchorWorldForEye(focusPosition, focusRotation * Vector3.forward), val.position); if (Mathf.Max(num, num2) > 0.75f) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] Enter camera path exceeds unassisted lever reach " + $"(anchor->lever leverLook={num:0.000}m settleLook={num2:0.000}m " + $"bound={0.75f:0.00}m); " + "the first-person shoulder assist will compensate.")); } } Quaternion rotation = Quaternion.LookRotation(((Vector3)(ref val8)).normalized, Vector3.up); Quaternion rotation2 = Quaternion.LookRotation(((Vector3)(ref lookDirection)).normalized, Vector3.up); _focusViewEnterPath = new FocusPathKnot[5] { new FocusPathKnot { T = 0f, Position = startPosition, Rotation = startRotation }, new FocusPathKnot { T = 0.218f, Position = val7, Rotation = rotation }, new FocusPathKnot { T = 0.455f, Position = val7, Rotation = rotation }, new FocusPathKnot { T = 0.818f, Position = focusPosition, Rotation = rotation2 }, new FocusPathKnot { T = 1f, Position = focusPosition, Rotation = focusRotation } }; ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)("[LethalCCTV] Enter camera path built (camera-lean): button=" + FormatDebugVector(val2.Value) + " lever=" + FormatDebugVector(val.position) + " buttonEye=" + FormatDebugVector(val7) + " buttonEyeBasis=" + text + " baselineOrigin=" + FormatDebugVector(val5) + " " + $"lean={Vector3.Distance(val6, val7):0.000}m " + $"anchorToButton={anchorDistance:0.000}m " + $"anchorToLever={num:0.000}m " + $"buttonPitch={GetSignedCameraPitchDegrees(rotation):0.0} " + $"leverPitch={GetSignedCameraPitchDegrees(rotation2):0.0} " + $"total={1.1f:0.00}s.")); } } private static bool TryResolveCanonicalStationStandEye(PlayerControllerB player, out Vector3 standEye) { //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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_0123: 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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_013f: Unknown result type (might be due to invalid IL or missing references) standEye = Vector3.zero; Transform operatorPoseAnchor = CCTVOperatorStation.OperatorPoseAnchor; if ((Object)(object)player == (Object)null || (Object)(object)operatorPoseAnchor == (Object)null) { return false; } bool num = Y4NGZPlayerAnimationBridge.UseInteractionsApiOperatorSession && Y4NGZPlayerAnimationBridge.UseApiOperatorRootAtFloorLevel; Transform playerRootAnchor = CCTVOperatorStation.PlayerRootAnchor; bool num2 = num && (Object)(object)playerRootAnchor != (Object)null && playerRootAnchor != operatorPoseAnchor; bool flag = _stationPoseSettleTransferToFocus && _stationPoseSettleSnapshot.Valid && _stationPoseSettleSnapshot.Player == player; float num3 = (flag ? _stationPoseSettleTargetPosition.y : ((Component)player).transform.position.y); Vector3 val = (Vector3)(num2 ? new Vector3(playerRootAnchor.position.x, num3, playerRootAnchor.position.z) : operatorPoseAnchor.position); Quaternion val2 = (num2 ? Quaternion.Euler(0f, operatorPoseAnchor.eulerAngles.y, 0f) : operatorPoseAnchor.rotation); Vector3 val3; if (flag && _stationPoseSettleSnapshot.CameraBaselineCaptured) { val3 = _stationPoseSettleSnapshot.CameraPlayerLocalPosition; } else { if (!((Object)(object)player.gameplayCamera != (Object)null)) { return false; } val3 = ((Component)player).transform.InverseTransformPoint(((Component)player.gameplayCamera).transform.position); } standEye = val + val2 * val3; return true; } private static Vector3 ComputeApiAnchorWorldForEye(Vector3 eyePosition, Vector3 lookDirection) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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_000b: 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_0027: 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) //IL_0031: 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_0033: 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_003e: 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_001f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.ProjectOnPlane(lookDirection, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.forward; } Quaternion val2 = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); return eyePosition + val2 * Y4NGZPlayerAnimationBridge.ApiCameraAnchorOffset; } private static Vector3 ResolveEnterLeanEye(Vector3 baselineEye, Vector3 contactPoint, float reachBound, out float anchorDistance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_002c: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_0047: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_0060: 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_008f: 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_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_00cd: 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_00d2: 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_00d5: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) Vector3 val = baselineEye - contactPoint; float magnitude = ((Vector3)(ref val)).magnitude; anchorDistance = Vector3.Distance(ComputeApiAnchorWorldForEye(baselineEye, -val), contactPoint); if (magnitude < 0.35f) { return baselineEye; } if (anchorDistance <= reachBound) { return baselineEye; } Vector3 val2 = ComputeApiAnchorWorldForEye(baselineEye, -val) - baselineEye; float num = Vector3.Dot(val, val); float num2 = 2f * Vector3.Dot(val, val2); float num3 = Vector3.Dot(val2, val2) - reachBound * reachBound; float num4 = num2 * num2 - 4f * num * num3; if (num4 < 0f || num < 0.0001f) { return baselineEye; } float num5 = (0f - num2 + Mathf.Sqrt(num4)) / (2f * num); float num6 = 0.35f / magnitude; num5 = Mathf.Clamp(num5, num6, 1f); Vector3 val3 = contactPoint + val * num5; anchorDistance = Vector3.Distance(ComputeApiAnchorWorldForEye(val3, contactPoint - val3), contactPoint); return val3; } private static void EvaluateStationEnterCameraPath(float rawT, out Vector3 position, out Quaternion rotation) { //IL_0079: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_00d7: 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_00dc: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_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) //IL_0123: 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) FocusPathKnot[] focusViewEnterPath = _focusViewEnterPath; rawT = Mathf.Clamp01(rawT); int num = focusViewEnterPath.Length - 1; int i; for (i = 0; i < num - 1 && rawT > focusViewEnterPath[i + 1].T; i++) { } FocusPathKnot focusPathKnot = focusViewEnterPath[i]; FocusPathKnot focusPathKnot2 = focusViewEnterPath[i + 1]; float num2 = Mathf.Max(0.0001f, focusPathKnot2.T - focusPathKnot.T); float num3 = SmoothFocusTransition(Mathf.Clamp01((rawT - focusPathKnot.T) / num2)); position = Vector3.Lerp(focusPathKnot.Position, focusPathKnot2.Position, num3); rotation = Quaternion.Slerp(focusPathKnot.Rotation, focusPathKnot2.Rotation, num3); if (rawT <= 0.455f) { Vector3? val = Y4NGZPlayerAnimationBridge.ResolveAccessButtonPressPoint(); Vector3 val2 = (val.HasValue ? (val.Value - position) : Vector3.zero); if (((Vector3)(ref val2)).sqrMagnitude >= 0.0025f) { Quaternion val3 = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up); float num4 = SmoothFocusTransition(Mathf.Clamp01(rawT / 0.12f)); rotation = Quaternion.Slerp(focusViewEnterPath[0].Rotation, val3, num4); } } } private static float EvaluateStationEnterFovWidening(float rawT) { rawT = Mathf.Clamp01(rawT); if (rawT <= 0.218f) { float value = rawT / Mathf.Max(0.0001f, 0.218f); return Mathf.Lerp(0f, 6f, SmoothFocusTransition(value)); } if (rawT <= 0.455f) { return 6f; } if (rawT <= 0.818f) { float value2 = (rawT - 0.455f) / Mathf.Max(0.0001f, 0.363f); return Mathf.Lerp(6f, 4f, SmoothFocusTransition(value2)); } float value3 = (rawT - 0.818f) / Mathf.Max(0.0001f, 0.18199998f); return Mathf.Lerp(4f, 0f, SmoothFocusTransition(value3)); } private static void ResetStationIntroHandFollow() { //IL_0006: 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) _stationIntroHandFollowTarget = null; _stationIntroHandFollowSmoothedRotation = Quaternion.identity; _stationIntroHandFollowRotationInitialized = false; _stationIntroHandFollowResolutionAttempted = false; _stationIntroHandFollowTargetWasResolved = false; _stationIntroHandFollowActivated = false; _stationIntroHandFollowActiveLogged = false; _stationIntroHandFollowFallbackLogged = false; _stationIntroHandFollowSettleLogged = false; } private static bool IsStationIntroHandFollowEnabled() { return false; } private static Vector3 GetStationIntroHandFollowLookBias() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) return new Vector3(0f, 0f, -0.25f); } private static Quaternion ResolveStationIntroHandFollowRotation(float rawT, Vector3 eyePosition, Quaternion knotRotation) { //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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0047: 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_0089: 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_008f: 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) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00bd: 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) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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_0133: 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_015b: Unknown result type (might be due to invalid IL or missing references) //IL_015e: 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) Quaternion rotation = _focusViewEnterPath[^1].Rotation; if (_stationIntroHandFollowActivated && rawT >= 1f) { return rotation; } if (!IsStationIntroHandFollowEnabled() || !Y4NGZPlayerAnimationBridge.IsLocalInteractionsApiSessionActive) { return knotRotation; } if (rawT >= 1f) { return rotation; } if (!TryResolveStationIntroHandFollowTarget()) { return knotRotation; } Vector3 val = _stationIntroHandFollowTarget.position; Transform operatorPoseAnchor = CCTVOperatorStation.OperatorPoseAnchor; Transform val2 = (((Object)(object)operatorPoseAnchor != (Object)null) ? operatorPoseAnchor.parent : null); if ((Object)(object)val2 != (Object)null) { val += val2.TransformVector(GetStationIntroHandFollowLookBias()); } Vector3 val3 = val - eyePosition; Quaternion val4; if (((Vector3)(ref val3)).sqrMagnitude < 0.0025f) { if (!_stationIntroHandFollowRotationInitialized) { return knotRotation; } val4 = _stationIntroHandFollowSmoothedRotation; } else { val4 = Quaternion.LookRotation(((Vector3)(ref val3)).normalized, Vector3.up); } if (!_stationIntroHandFollowRotationInitialized) { _stationIntroHandFollowSmoothedRotation = _focusViewAnimationStartRotation; _stationIntroHandFollowRotationInitialized = true; } float num = 1f - Mathf.Exp(-14f * Mathf.Max(0f, Time.unscaledDeltaTime)); _stationIntroHandFollowSmoothedRotation = Quaternion.Slerp(_stationIntroHandFollowSmoothedRotation, val4, num); float num2 = SmoothFocusTransition(Mathf.Clamp01(Mathf.Clamp01(rawT) * 1.1f / 0.15f)); Quaternion val5 = Quaternion.Slerp(_focusViewAnimationStartRotation, _stationIntroHandFollowSmoothedRotation, num2); float num3 = SmoothFocusTransition(Mathf.InverseLerp(0.73f, 1f, Mathf.Clamp01(rawT))); return Quaternion.Slerp(val5, rotation, num3); } private static bool TryResolveStationIntroHandFollowTarget() { if ((Object)(object)_stationIntroHandFollowTarget != (Object)null) { return true; } string text; if (!_stationIntroHandFollowResolutionAttempted) { _stationIntroHandFollowResolutionAttempted = true; text = "enter_start"; } else { if (!_stationIntroHandFollowTargetWasResolved) { return false; } text = "cached_target_destroyed"; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null) { LogStationIntroHandFollowFallback(text + ":local_player_missing"); _stationIntroHandFollowTargetWasResolved = false; return false; } Transform val2 = val.localArmsTransform; if ((Object)(object)val2 == (Object)null && (Object)(object)val.gameplayCamera != (Object)null) { val2 = ((Component)val.gameplayCamera).transform.root; } if ((Object)(object)val2 == (Object)null) { LogStationIntroHandFollowFallback(text + ":local_arms_root_missing"); _stationIntroHandFollowTargetWasResolved = false; return false; } Transform[] componentsInChildren = ((Component)val2).GetComponentsInChildren(true); foreach (Transform val3 in componentsInChildren) { if (!((Object)(object)val3 != (Object)null) || !string.Equals(((Object)val3).name, "ArmsLeftArm_target", StringComparison.Ordinal)) { continue; } _stationIntroHandFollowTarget = val3; _stationIntroHandFollowTargetWasResolved = true; _stationIntroHandFollowActivated = true; if (!_stationIntroHandFollowActiveLogged) { _stationIntroHandFollowActiveLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][IntroFollow] active target=" + GetTransformPath(val3) + " " + $"smoothing={14f:0.0}/s " + $"blendIn={0.15f:0.00}s " + $"blendOut={0.73f:0.00}->1.00.")); } } return true; } LogStationIntroHandFollowFallback(text + ":target_missing path=ScavengerModelArmsOnly/metarig/spine.003/RigArms/LeftArm/ArmsLeftArm_target"); _stationIntroHandFollowTargetWasResolved = false; return false; } private static void LogStationIntroHandFollowFallback(string reason) { if (!_stationIntroHandFollowFallbackLogged) { _stationIntroHandFollowFallbackLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][IntroFollow] fallback_knots reason=" + reason + ".")); } } } private static void LogStationIntroHandFollowSettle(Quaternion appliedRotation) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) if (_stationIntroHandFollowActivated && !_stationIntroHandFollowSettleLogged && _focusViewEnterPath != null && _focusViewEnterPath.Length >= 1) { _stationIntroHandFollowSettleLogged = true; Quaternion rotation = _focusViewEnterPath[_focusViewEnterPath.Length - 1].Rotation; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV][IntroFollow] settle finalRotationDelta={Quaternion.Angle(appliedRotation, rotation):F3}deg."); } } } private static float GetPreservedFocusFov() { if (_priorFocusCameraFov > 1f) { return _priorFocusCameraFov; } if (!((Object)(object)_physicalFocusCamera != (Object)null)) { return 60f; } return Mathf.Clamp(_physicalFocusCamera.fieldOfView, 30f, 90f); } private static void ApplyStationFocusRenderBudget(Camera camera) { if (!((Object)(object)camera == (Object)null) && !_focusRenderBudgetActive) { _focusRenderBudgetCamera = camera; _focusRenderBudgetSavedFarClip = camera.farClipPlane; camera.farClipPlane = Mathf.Min(camera.farClipPlane, 55f); _focusRenderBudgetActive = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] Station focus render budget applied: farClip {_focusRenderBudgetSavedFarClip:F1}m -> {camera.farClipPlane:F1}m, scalarOnly=True."); } } } private static void RestoreStationFocusRenderBudget() { if (_focusRenderBudgetActive) { if ((Object)(object)_focusRenderBudgetCamera != (Object)null) { _focusRenderBudgetCamera.farClipPlane = _focusRenderBudgetSavedFarClip; } _focusRenderBudgetActive = false; _focusRenderBudgetCamera = null; _focusRenderBudgetSavedFarClip = 0f; } } private static void LogRadarEditCameraDiagnostic() { //IL_0044: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0232: 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_0266: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime < _radarEditDiagNextLogAt) { return; } _radarEditDiagNextLogAt = Time.unscaledTime + 0.5f; Transform radarViewAnchor = CCTVOperatorStation.RadarViewAnchor; bool flag = (Object)(object)_physicalFocusCameraTransform != (Object)null; string text = ((_radarEditDiagWrotePreviousFrame && flag) ? $"{Quaternion.Angle(_radarEditDiagLastWrittenRotation, _physicalFocusCameraTransform.rotation):0.00}deg" : "n/a"); float num = (((Object)(object)radarViewAnchor != (Object)null) ? GetPlanarYaw(radarViewAnchor.forward) : 0f); float num2 = (flag ? GetPlanarYaw(_physicalFocusCameraTransform.forward) : 0f); string text2 = ((_radarEditDiagHavePreviousSample && (Object)(object)radarViewAnchor != (Object)null) ? $"{Mathf.DeltaAngle(_radarEditDiagPreviousAnchorYaw, num):0.00}deg" : "n/a"); string text3 = ((_radarEditDiagHavePreviousSample && flag) ? $"{Mathf.DeltaAngle(_radarEditDiagPreviousCamYaw, num2):0.00}deg" : "n/a"); _radarEditDiagHavePreviousSample = true; _radarEditDiagPreviousAnchorYaw = num; _radarEditDiagPreviousCamYaw = num2; PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { string[] obj = new string[23] { "[LethalCCTV][RadarEditDiag] branchLastFrame=", _radarEditDiagBranch, " ", $"viewActive={_physicalFocusViewActive} haveCam={flag} ", $"animating={_focusViewAnimating} ", $"tpPreview={_stationThirdPersonPreviewActive} ", string.Format("editRadar={0} ", CCTVOperatorStation.IsEditingDebugPlacement("radar")), "anchorEuler=", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null }; object obj2; Quaternion rotation; if (!((Object)(object)radarViewAnchor != (Object)null)) { obj2 = ""; } else { rotation = radarViewAnchor.rotation; obj2 = FormatDebugVector(((Quaternion)(ref rotation)).eulerAngles); } obj[8] = (string)obj2; obj[9] = " camEuler="; object obj3; if (!flag) { obj3 = ""; } else { rotation = _physicalFocusCameraTransform.rotation; obj3 = FormatDebugVector(((Quaternion)(ref rotation)).eulerAngles); } obj[10] = (string)obj3; obj[11] = " camLocalEuler="; obj[12] = (flag ? FormatDebugVector(_physicalFocusCameraTransform.localEulerAngles) : ""); obj[13] = " bodyYaw="; obj[14] = (((Object)(object)val != (Object)null) ? ((Component)val).transform.eulerAngles.y.ToString("0.00") : ""); obj[15] = " anchorYawStep="; obj[16] = text2; obj[17] = " camYawStep="; obj[18] = text3; obj[19] = " camPos="; obj[20] = (flag ? FormatDebugVector(_physicalFocusCameraTransform.position) : ""); obj[21] = " driftSinceOurWrite="; obj[22] = text; log.LogMessage((object)string.Concat(obj)); } } private static void ApplyPhysicalFocusView() { if (CCTVOperatorStation.IsEditingDebugPlacement("radar")) { LogRadarEditCameraDiagnostic(); } else { _radarEditDiagHavePreviousSample = false; } ApplyPhysicalFocusViewCore(); SnapLocalVisorToCameraTarget("focus-view"); } private static void ApplyPhysicalFocusViewCore() { //IL_006c: 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_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: 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_0165: 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_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: 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_01a6: 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_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: 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_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_0257: 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_0266: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) _radarEditDiagBranch = "entered"; _radarEditDiagWrotePreviousFrame = false; if (!_physicalFocusViewActive) { _radarEditDiagBranch = "bail:viewInactive"; } else if ((Object)(object)_physicalFocusCamera == (Object)null || (Object)(object)_physicalFocusCameraTransform == (Object)null) { _radarEditDiagBranch = "bail:noCamera"; } else if (_focusViewAnimating) { _radarEditDiagBranch = "animating"; if (Time.unscaledTime < _focusViewAnimationDelayUntil) { _physicalFocusCameraTransform.SetPositionAndRotation(_focusViewAnimationStartPosition, _focusViewAnimationStartRotation); _physicalFocusCamera.fieldOfView = _focusViewAnimationStartFov; LogIntroCameraRenderedFrame(0f, "delay"); return; } float num = Mathf.Max(0.0001f, _focusViewAnimationDuration); if (Time.frameCount != _focusViewAnimationLastAdvanceFrame) { _focusViewAnimationLastAdvanceFrame = Time.frameCount; _focusViewAnimationElapsedSeconds += Mathf.Min(Mathf.Max(0f, Time.unscaledDeltaTime), 0.05f); } float num2 = Mathf.Clamp01(_focusViewAnimationElapsedSeconds / num); float num3 = SmoothFocusTransition(num2); float num4 = 0f; if (_focusViewEnterPath != null && _focusViewEnterPath.Length >= 2) { EvaluateStationEnterCameraPath(num2, out var position, out var rotation); num4 = EvaluateStationEnterFovWidening(num2); Quaternion val = ResolveStationIntroHandFollowRotation(num2, position, rotation); _physicalFocusCameraTransform.SetPositionAndRotation(position, val); if (num2 >= 1f) { LogStationIntroHandFollowSettle(_physicalFocusCameraTransform.rotation); } } else if (_focusViewAnimationHasWaypoint) { Vector3 val2 = Vector3.Lerp(_focusViewAnimationStartPosition, _focusViewWaypointPosition, num3); Vector3 val3 = Vector3.Lerp(_focusViewWaypointPosition, _focusViewAnimationTargetPosition, num3); Quaternion val4 = Quaternion.Slerp(_focusViewAnimationStartRotation, _focusViewWaypointRotation, num3); Quaternion val5 = Quaternion.Slerp(_focusViewWaypointRotation, _focusViewAnimationTargetRotation, num3); _physicalFocusCameraTransform.SetPositionAndRotation(Vector3.Lerp(val2, val3, num3), Quaternion.Slerp(val4, val5, num3)); } else { Quaternion val6 = Quaternion.Slerp(_focusViewAnimationStartRotation, _focusViewAnimationTargetRotation, num3); _physicalFocusCameraTransform.SetPositionAndRotation(Vector3.Lerp(_focusViewAnimationStartPosition, _focusViewAnimationTargetPosition, num3), val6); } _physicalFocusCamera.fieldOfView = Mathf.Clamp(Mathf.Lerp(_focusViewAnimationStartFov, _focusViewAnimationTargetFov, num3) + num4, 1f, 179f); LogIntroCameraRenderedFrame(num2, "path"); if (!(num2 >= 1f)) { return; } _focusViewAnimating = false; if (_focusViewExitPending) { _exitHandbackAnimationCompletePoseCaptured = true; _exitHandbackAnimationCompletePosition = _physicalFocusCameraTransform.position; _exitHandbackAnimationCompleteRotation = _physicalFocusCameraTransform.rotation; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ExitSeam] exit anim complete: cam=" + FormatDebugVector(_physicalFocusCameraTransform.position) + " " + $"yaw={GetPlanarYaw(_physicalFocusCameraTransform.forward):F1} " + $"pitch={GetSignedCameraPitchDegrees(_physicalFocusCameraTransform.rotation):F1} " + $"rotationDelta={Quaternion.Angle(_exitSeamReferenceRotation, _physicalFocusCameraTransform.rotation):F3}deg; " + "running cleanup.")); } CompleteExitFocusCleanup(); } else { _arrivalViewFramingLogPending = true; } } else { ApplyStationPhysicalFocusView(); } } private static void ApplyStationPhysicalFocusView() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) CCTVOperatorStation.EnsureFocusAnchorAimed(); Transform val = (((Object)(object)CCTVOperatorStation.FocusViewAnchor != (Object)null) ? CCTVOperatorStation.FocusViewAnchor : QuadMonitor.FocusViewAnchor); if ((Object)(object)val == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Station focus view: CCTVFocusViewAnchor missing from operator station."); } return; } if (_stationThirdPersonPreviewActive) { _radarEditDiagBranch = "thirdPersonPreview"; ApplyStationThirdPersonPreviewView(val); return; } ResolveStationFocusCameraPose(val, out var position, out var rotation); float num = Mathf.Max(Time.unscaledDeltaTime, 0.004166667f); CCTVOperatorStation.EnsureRadarAnchorAimed(); Transform radarViewAnchor = CCTVOperatorStation.RadarViewAnchor; if (CCTVOperatorStation.IsEditingDebugPlacement("focus")) { _physicalFocusCameraTransform.SetPositionAndRotation(position, rotation); _physicalFocusCamera.fieldOfView = GetPreservedFocusFov(); _radarEditDiagBranch = "focusWysiwyg"; _radarEditDiagWrotePreviousFrame = true; _radarEditDiagLastWrittenRotation = rotation; return; } Vector3 position2; if (CCTVOperatorStation.IsEditingDebugPlacement("radar") && (Object)(object)radarViewAnchor != (Object)null) { ResolveStationFocusCameraPose(radarViewAnchor, out position2, out var rotation2); _physicalFocusCameraTransform.SetPositionAndRotation(position, rotation2); _physicalFocusCamera.fieldOfView = GetPreservedFocusFov(); ApplyStationViewpointThroughVanillaChannels(rotation2); _radarEditDiagBranch = "radarWysiwyg"; _radarEditDiagWrotePreviousFrame = true; _radarEditDiagLastWrittenRotation = rotation2; return; } bool num2 = Time.unscaledTime < _stationFocusAnchorForcedUntil; bool flag = !num2 && Time.unscaledTime >= _stationRadarLookSuppressedUntil; bool flag2 = !num2 && IsStationRadarLookHeld(); bool flag3 = flag && flag2 && !_stationEditMenuOpen && !Y4NGZPlayerAnimationBridge.IsFirstPersonHandEditModeActive && !CCTVOperatorStation.IsDebugPlacementActive; if (_radarLookEventState != flag3) { _radarLookEventState = flag3; CCTVStationEvents.RaiseRadarViewChanged(flag3); } _stationRadarLookBlend = Mathf.MoveTowards(_stationRadarLookBlend, flag3 ? 1f : 0f, num / 0.46f); float num3 = SmoothFocusTransition(_stationRadarLookBlend); Quaternion rotation3 = rotation * Quaternion.Euler(-1.5f, 28f, -3.5f); if ((Object)(object)radarViewAnchor != (Object)null) { ResolveStationFocusCameraPose(radarViewAnchor, out position2, out rotation3); } else { rotation3 = ClampPresentationCameraPitch(rotation3); } PlayerControllerB stationPlayerPosePlayer = _stationPlayerPosePlayer; if (!_stationViewpointChannelOverrideActive && (Object)(object)stationPlayerPosePlayer != (Object)null) { _stationGlanceRestYawDeg = GetPlanarYaw(_stationPlayerPoseTargetRotation * Vector3.forward); _stationGlanceRestPitchDeg = stationPlayerPosePlayer.cameraUp; } float planarYaw = GetPlanarYaw(rotation3 * Vector3.forward); float signedCameraPitchDegrees = GetSignedCameraPitchDegrees(rotation3); float num4 = _stationGlanceRestYawDeg + Mathf.DeltaAngle(_stationGlanceRestYawDeg, planarYaw) * num3; Quaternion val2 = Quaternion.Euler(Mathf.Lerp(_stationGlanceRestPitchDeg, signedCameraPitchDegrees, num3), num4, 0f); _physicalFocusCameraTransform.SetPositionAndRotation(position, val2); _physicalFocusCamera.fieldOfView = GetPreservedFocusFov(); if (_stationRadarLookBlend > 0.0001f) { ApplyStationViewpointThroughVanillaChannels(val2); } else { ReleaseStationViewpointChannelOverride(); } _radarEditDiagBranch = $"steadyGlance(blend={_stationRadarLookBlend:0.00})"; _radarEditDiagWrotePreviousFrame = true; _radarEditDiagLastWrittenRotation = val2; } private static void ApplyStationViewpointThroughVanillaChannels(Quaternion worldRotation) { //IL_004f: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB stationPlayerPosePlayer = _stationPlayerPosePlayer; if (_stationPlayerPoseLockActive && !((Object)(object)stationPlayerPosePlayer == (Object)null)) { if (!_stationViewpointChannelOverrideActive) { _stationViewpointChannelOverrideActive = true; _stationViewpointSavedPoseRotation = _stationPlayerPoseTargetRotation; _stationViewpointSavedCameraUp = stationPlayerPosePlayer.cameraUp; _stationViewpointSavedMinVerticalClamp = stationPlayerPosePlayer.minVerticalClamp; _stationViewpointSavedMaxVerticalClamp = stationPlayerPosePlayer.maxVerticalClamp; } float planarYaw = GetPlanarYaw(worldRotation * Vector3.forward); float signedCameraPitchDegrees = GetSignedCameraPitchDegrees(worldRotation); _stationPlayerPoseTargetRotation = Quaternion.Euler(0f, planarYaw, 0f); ((Component)stationPlayerPosePlayer).transform.rotation = _stationPlayerPoseTargetRotation; stationPlayerPosePlayer.minVerticalClamp = signedCameraPitchDegrees; stationPlayerPosePlayer.maxVerticalClamp = signedCameraPitchDegrees; stationPlayerPosePlayer.cameraUp = signedCameraPitchDegrees; } } private static void ReleaseStationViewpointChannelOverride() { //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) if (_stationViewpointChannelOverrideActive) { _stationViewpointChannelOverrideActive = false; _stationPlayerPoseTargetRotation = _stationViewpointSavedPoseRotation; PlayerControllerB stationPlayerPosePlayer = _stationPlayerPosePlayer; if (!((Object)(object)stationPlayerPosePlayer == (Object)null)) { stationPlayerPosePlayer.cameraUp = _stationViewpointSavedCameraUp; stationPlayerPosePlayer.minVerticalClamp = _stationViewpointSavedMinVerticalClamp; stationPlayerPosePlayer.maxVerticalClamp = _stationViewpointSavedMaxVerticalClamp; } } } private static void ResolveStationFocusCameraPose(Transform anchor, out Vector3 position, out Quaternion rotation) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_00b4: 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_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_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) position = (((Object)(object)anchor != (Object)null) ? anchor.position : Vector3.zero); rotation = (((Object)(object)anchor != (Object)null) ? anchor.rotation : Quaternion.identity); if (!((Object)(object)anchor != (Object)null) || !CCTVOperatorStation.ShouldUseExactStationFocusPose(anchor)) { rotation = ClampPresentationCameraPitch(rotation); } if ((Object)(object)anchor != (Object)null && (Object)(object)anchor == (Object)(object)CCTVOperatorStation.FocusViewAnchor) { rotation *= Quaternion.Euler(-3.5f, 0f, 0f); position += rotation * Vector3.back * 0.22f + Vector3.up * 0.12f; } } internal static bool TryGetStationFocusPresentationEye(out Vector3 position, out Quaternion rotation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; rotation = Quaternion.identity; Transform focusViewAnchor = CCTVOperatorStation.FocusViewAnchor; if ((Object)(object)focusViewAnchor == (Object)null) { return false; } ResolveStationFocusCameraPose(focusViewAnchor, out position, out rotation); return true; } private static void ApplyStationThirdPersonPreviewView(Transform fallbackAnchor) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0184: 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_018d: 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_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: 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_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: 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_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0215: 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) Transform operatorPoseAnchor = CCTVOperatorStation.OperatorPoseAnchor; Transform val = (((Object)(object)operatorPoseAnchor != (Object)null) ? operatorPoseAnchor : fallbackAnchor); if (!((Object)(object)val == (Object)null) && !((Object)(object)_physicalFocusCameraTransform == (Object)null) && !((Object)(object)_physicalFocusCamera == (Object)null)) { Renderer renderer = ForceLocalPlayerThirdPersonPreviewRenderers(_focusedPlayer); Bounds bounds; bool flag = TryGetPreviewRendererBounds(renderer, out bounds); Vector3 val2 = (flag ? ((Bounds)(ref bounds)).center : (val.position + Vector3.up * 0.42f)); float num = (flag ? Mathf.Max(((Bounds)(ref bounds)).size.x, Mathf.Max(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z)) : 0.9f); float num2 = (flag ? Mathf.Clamp(num * 1.45f + 0.55f, 1.05f, 2.45f) : 1.45f); float num3 = (flag ? Mathf.Clamp(num * 0.48f, 0.45f, 0.95f) : 0.82f); float num4 = (flag ? Mathf.Clamp(((Bounds)(ref bounds)).size.y * 0.18f + 0.16f, 0.24f, 0.62f) : 0.42f); Vector3 val3 = val.forward; Vector3 val4; if (!(((Vector3)(ref val3)).sqrMagnitude > 0.0001f)) { val4 = Vector3.forward; } else { val3 = val.forward; val4 = ((Vector3)(ref val3)).normalized; } val3 = val.right; Vector3 val5; if (!(((Vector3)(ref val3)).sqrMagnitude > 0.0001f)) { val5 = Vector3.right; } else { val3 = val.right; val5 = ((Vector3)(ref val3)).normalized; } Vector3 val6 = val5; Vector3 baseOffset = -val4 * num2 + val6 * num3 + Vector3.up * num4; Vector3 val7 = val2 + ApplyStationThirdPersonOrbit(baseOffset); val3 = val2 - val7; Quaternion val8 = Quaternion.LookRotation(((Vector3)(ref val3)).normalized, Vector3.up); _physicalFocusCameraTransform.SetPositionAndRotation(val7, val8); _physicalFocusCamera.fieldOfView = Mathf.Clamp(GetPreservedFocusFov() + 8f, 40f, 78f); LogStationThirdPersonPreviewFraming(renderer, flag, bounds, val2, val7); } } internal static void ApplyStationThirdPersonOrbitDelta(Vector2 lookDeltaDeg) { //IL_0005: 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) _stationThirdPersonOrbitYawDeg = Mathf.Clamp(_stationThirdPersonOrbitYawDeg + lookDeltaDeg.x, -160f, 160f); _stationThirdPersonOrbitPitchDeg = Mathf.Clamp(_stationThirdPersonOrbitPitchDeg - lookDeltaDeg.y, -48f, 58f); _previewCameraFramingLogged = false; } private static Vector3 ApplyStationThirdPersonOrbit(Vector3 baseOffset) { //IL_001a: 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) //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_002a: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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) if (((Vector3)(ref baseOffset)).sqrMagnitude < 0.0001f) { baseOffset = Vector3.back; } Vector3 val = Quaternion.AngleAxis(_stationThirdPersonOrbitYawDeg, Vector3.up) * baseOffset; Vector3 val2 = Vector3.Cross(Vector3.up, -((Vector3)(ref val)).normalized); if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.right; } return Quaternion.AngleAxis(_stationThirdPersonOrbitPitchDeg, ((Vector3)(ref val2)).normalized) * val; } private static void ResetStationThirdPersonOrbit() { _stationThirdPersonOrbitYawDeg = 0f; _stationThirdPersonOrbitPitchDeg = 0f; _previewCameraFramingLogged = false; _stationGlobalThirdPersonFramingLogged = false; } private static void StartFocusViewAnimation(Vector3 startPosition, Quaternion startRotation, float startFov, Vector3 targetPosition, Quaternion targetRotation, float targetFov, float duration, bool exiting, float delaySeconds = 0f) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_0018: 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) _focusViewAnimationStartPosition = startPosition; _focusViewAnimationStartRotation = startRotation; _focusViewAnimationStartFov = startFov; _focusViewAnimationTargetPosition = targetPosition; _focusViewAnimationTargetRotation = targetRotation; _focusViewAnimationTargetFov = targetFov; _focusViewAnimationStartedAt = Time.unscaledTime; _focusViewAnimationDelayUntil = ((delaySeconds > 0f) ? (_focusViewAnimationStartedAt + delaySeconds) : 0f); _focusViewAnimationDuration = Mathf.Max(0.0001f, duration); _focusViewAnimationElapsedSeconds = 0f; _focusViewAnimationLastAdvanceFrame = Time.frameCount; _focusViewAnimationHasWaypoint = false; _focusViewEnterPath = null; _focusViewAnimating = true; _focusViewExitPending = exiting; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Focus view animation started: phase=" + (exiting ? "exit" : "enter") + ", " + $"delay={Mathf.Max(0f, delaySeconds):0.00}s, duration={_focusViewAnimationDuration:0.00}s.")); } } private static float SmoothFocusTransition(float value) { value = Mathf.Clamp01(value); return value * value * value * (value * (value * 6f - 15f) + 10f); } private static bool BeginPhysicalFocusExitAnimation() { //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_0035: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0099: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_00f8: 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_0102: 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_0108: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) if (!_physicalFocusViewActive) { return false; } if ((Object)(object)_physicalFocusCamera == (Object)null || (Object)(object)_physicalFocusCameraTransform == (Object)null) { return false; } Vector3 position = _physicalFocusCameraTransform.position; Quaternion rotation = _physicalFocusCameraTransform.rotation; Quaternion val = _priorFocusCameraWorldRotation; if (UseExitToStationPose && _stationPlayerPoseLockActive) { val = (_priorFocusCameraWorldRotation = Quaternion.Euler(0f, ((Quaternion)(ref _stationPlayerPoseSavedRotation)).eulerAngles.y, 0f)); } else if (!_stationPlayerPoseLockActive) { val = (_priorFocusCameraWorldRotation = Quaternion.Euler(0f, ((Quaternion)(ref rotation)).eulerAngles.y, 0f)); } Quaternion val2 = (_stationPlayerPoseHandbackRotation = FlattenToYaw(val)); _stationPlayerPoseHandbackCameraPitch = GetSignedCameraPitchDegrees(val); Vector3 val3 = _stationPlayerPoseSavedPosition + val2 * _stationPlayerCameraPlayerLocalPosition; if (!_stationPlayerPoseLockActive) { val3 = position; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV][ExitSeam] exit anim begin after pose lock restore; holding camera position for the glide instead of the cleared saved pose."); } } _exitHandbackAnimationCompletePoseCaptured = false; _exitHandbackAnimationCompletePosition = Vector3.zero; _exitHandbackAnimationCompleteRotation = Quaternion.identity; _exitSeamReferenceRotation = rotation; _exitSeamStartedAt = Time.unscaledTime; _exitSeamLogUntil = Time.unscaledTime + 0.15f + 0.6f + 1.6f; _exitSeamNextLogAt = 0f; StartFocusViewAnimation(position, rotation, _physicalFocusCamera.fieldOfView, val3, val, _priorFocusCameraFov, 0.6f, exiting: true, 0.15f); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV][ExitSeam] exit anim begin: start=" + FormatDebugVector(position) + " rotStart=" + FormatDebugVector(((Quaternion)(ref rotation)).eulerAngles) + " rotTarget=" + FormatDebugVector(((Quaternion)(ref val)).eulerAngles) + " -> handbackTarget=" + FormatDebugVector(val3) + " " + $"rotationDelta={Quaternion.Angle(rotation, val):F3}deg " + "(savedWorld=" + FormatDebugVector(_stationPlayerPoseSavedPosition) + ", " + $"savedBodyYaw={((Quaternion)(ref _stationPlayerPoseSavedRotation)).eulerAngles.y:F1}, " + $"handbackBodyYaw={((Quaternion)(ref val2)).eulerAngles.y:F1}, " + $"cameraUp={_stationPlayerPoseHandbackCameraPitch:F1}, " + "cameraPlayerLocal=" + FormatDebugVector(_stationPlayerCameraPlayerLocalPosition) + ").")); } return true; } private static void EndPhysicalFocusView() { //IL_0027: 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) //IL_0057: 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_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0284: 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_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_00be: 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_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) if (!_physicalFocusViewActive) { EndStationPlayerPoseTracking(); ResetFirstPersonArmsCameraPose(); return; } PlayerControllerB val = _stationPlayerPosePlayer ?? _focusedPlayer; float stationPlayerPoseHandbackCameraPitch = _stationPlayerPoseHandbackCameraPitch; Quaternion priorFocusCameraWorldRotation = _priorFocusCameraWorldRotation; EndStationPlayerPoseTracking(); if ((Object)(object)_physicalFocusCamera != (Object)null && (Object)(object)_physicalFocusCameraTransform != (Object)null) { _physicalFocusCameraTransform.SetPositionAndRotation(_focusViewAnimationTargetPosition, priorFocusCameraWorldRotation); if ((Object)(object)val != (Object)null) { val.cameraUp = stationPlayerPoseHandbackCameraPitch; } EnforceExitCameraLocalYawInvariant(val, "focus-view-restored"); _physicalFocusCamera.fieldOfView = _priorFocusCameraFov; string text = ""; string text2 = ""; string text3 = ""; if (_exitHandbackAnimationCompletePoseCaptured) { float num = Vector3.Distance(_exitHandbackAnimationCompletePosition, _physicalFocusCameraTransform.position); float num2 = Quaternion.Angle(_exitHandbackAnimationCompleteRotation, _physicalFocusCameraTransform.rotation); text = $"{num:F4}m/{num2:F3}deg"; text2 = $"{num:F4}m"; text3 = $"{num2:F3}deg"; } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ExitSeam] post-restore: cam=" + FormatDebugVector(_physicalFocusCameraTransform.position) + " " + $"yaw={GetPlanarYaw(_physicalFocusCameraTransform.forward):F1} " + $"pitch={GetSignedCameraPitchDegrees(_physicalFocusCameraTransform.rotation):F1} " + $"localRoll={_physicalFocusCameraTransform.localEulerAngles.z:F2} " + "positionDelta=" + text2 + " rotationDelta=" + text3 + " handbackDelta=" + text + " (handback pose restored under restored root).")); } if (_exitSeamStartedAt <= 0f) { _exitSeamStartedAt = Time.unscaledTime; } _exitSeamLogUntil = Mathf.Max(_exitSeamLogUntil, Time.unscaledTime + 1.6f); _exitSeamNextLogAt = 0f; } RestoreStationFocusRenderBudget(); if (Y4NGZPlayerAnimationBridge.IsLocalInteractionsApiSessionActive) { _holdLocalObstructorsForInteractionsApiRestore = true; ReassertLocalPlayerObstructors(); LogLocalObstructorCallOnce("hold", "interactions-api-restore"); } else { RestoreLocalPlayerObstructors("focus-view-end"); } ResetFirstPersonArmsCameraPose(); _physicalFocusCamera = null; _physicalFocusCameraTransform = null; _priorFocusCameraLocalPosition = Vector3.zero; _priorFocusCameraLocalRotation = Quaternion.identity; _priorFocusCameraWorldPosition = Vector3.zero; _priorFocusCameraWorldRotation = Quaternion.identity; _priorFocusCameraFov = 0f; _focusViewAnimating = false; _focusViewExitPending = false; _focusViewAnimationDelayUntil = 0f; _physicalFocusViewActive = false; _exitHandbackAnimationCompletePoseCaptured = false; _exitHandbackAnimationCompletePosition = Vector3.zero; _exitHandbackAnimationCompleteRotation = Quaternion.identity; } private static void LogIntroCameraPose(string point, Vector3 worldPosition, Quaternion worldRotation) { //IL_0026: 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) ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][IntroCam] point=" + point + " cameraWorldPos=" + FormatDebugVector(worldPosition) + " cameraWorldEuler=" + FormatDebugVector(((Quaternion)(ref worldRotation)).eulerAngles) + ".")); } } private static void LogIntroCameraRenderedFrame(float rawT, string phase) { //IL_0082: 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) if (!_focusViewExitPending && _introCameraRenderedFramesLogged < 16 && Time.frameCount != _introCameraLastRenderedFrame) { _introCameraLastRenderedFrame = Time.frameCount; _introCameraRenderedFramesLogged++; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][IntroCam] point=focus-render " + $"frame={_introCameraRenderedFramesLogged}/{16} unityFrame={Time.frameCount} " + "cameraWorldPos=" + FormatDebugVector(_physicalFocusCameraTransform.position) + " cameraWorldEuler=" + FormatDebugVector(_physicalFocusCameraTransform.eulerAngles) + " " + $"rawT={rawT:F4} phase={phase}.")); } } } private static void TickOperatorDebugToolsGate(bool enabled) { if (enabled == _operatorDebugToolsEnabledLastFrame) { return; } _operatorDebugToolsEnabledLastFrame = enabled; if (!enabled) { CloseStationEditMenu("operator-debug-tools-disabled"); if (_placementEditorOpen) { CancelPlacementEditor(restore: true); } CloseCameraReviewMenu(); _cameraPlacementEditModeOpen = false; SetStationThirdPersonDebugPersistent(active: false); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Operator debug tools disabled by config; edit modes closed and their hotkeys are now inert."); } } } internal static void ToggleStationThirdPersonDebug() { SetStationThirdPersonDebugPersistent(!_stationThirdPersonDebugPersistent); } internal static void SetStationThirdPersonDebugPersistent(bool active) { if (_stationThirdPersonDebugPersistent == active) { return; } _stationThirdPersonDebugPersistent = active; _stationGlobalThirdPersonFramingLogged = false; if (active) { ResetStationThirdPersonOrbit(); Y4NGZPlayerAnimationBridge.SetLocalThirdPersonPreviewEnabled(enabled: true); if (IsFocused) { SetStationThirdPersonPreview(active: true); } else { TickStationGlobalThirdPersonDebugView(); } } else if (IsFocused) { SetStationThirdPersonPreview(active: false); } else { RestoreStationGlobalThirdPersonDebugView(); RestorePreviewForcedLocalRenderers(); Y4NGZPlayerAnimationBridge.SetLocalThirdPersonPreviewEnabled(_stationThirdPersonPreviewActive); } if (IsFocused) { RefreshLocalOperatorFirstPersonVisibility(); } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Persistent station third-person debug " + (active ? "enabled" : "disabled") + ".")); } } private static void TickStationThirdPersonDebugHotkey() { if (Y4NGZPlayerAnimationBridge.IsFirstPersonHandEditModeActive || IsFocused) { return; } Keyboard current = Keyboard.current; if (current != null && ((ButtonControl)current.f4Key).wasPressedThisFrame) { PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if (!((Object)(object)val != (Object)null) || (!val.inTerminalMenu && (!((Object)(object)val.quickMenuManager != (Object)null) || !val.quickMenuManager.isMenuOpen) && !val.isTypingChat)) { ToggleStationThirdPersonDebug(); } } } private static void TickLocalFirstPersonOperatorAnimationHotkey() { if (Y4NGZPlayerAnimationBridge.IsFirstPersonHandEditModeActive) { return; } Keyboard current = Keyboard.current; if (current == null || !((ButtonControl)current.f8Key).wasPressedThisFrame) { return; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if (!((Object)(object)val != (Object)null) || (!val.inTerminalMenu && (!((Object)(object)val.quickMenuManager != (Object)null) || !val.quickMenuManager.isMenuOpen) && !val.isTypingChat)) { bool flag = SurveillanceBootstrap.Config?.LocalAuthoredOperatorAnimationsEnabled == null || !SurveillanceBootstrap.Config.LocalAuthoredOperatorAnimationsEnabled.Value; if (SurveillanceBootstrap.Config?.LocalAuthoredOperatorAnimationsEnabled != null) { SurveillanceBootstrap.Config.LocalAuthoredOperatorAnimationsEnabled.Value = flag; } Y4NGZPlayerAnimationBridge.RefreshLocalAuthoredOperatorAnimationSetting(flag ? "first-person-operator-hotkey-enabled" : "first-person-operator-hotkey-disabled"); RefreshLocalOperatorFirstPersonVisibility(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] First-person/local authored operator animations " + (flag ? "enabled" : "disabled") + " from F8.")); } } } private static void TickStationGlobalThirdPersonDebugView() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_0123: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_018c: 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_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: 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_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: 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_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: 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_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: 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_0247: 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) if (!_stationThirdPersonDebugPersistent || IsFocused) { if (!_stationThirdPersonDebugPersistent && _stationGlobalThirdPersonCameraActive) { RestoreStationGlobalThirdPersonDebugView(); } return; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null || (Object)(object)val.gameplayCamera == (Object)null) { return; } Camera gameplayCamera = val.gameplayCamera; Transform transform = ((Component)gameplayCamera).transform; if (!_stationGlobalThirdPersonCameraActive || (Object)(object)_stationGlobalThirdPersonCamera != (Object)(object)gameplayCamera) { RestoreStationGlobalThirdPersonDebugView(); _stationGlobalThirdPersonCamera = gameplayCamera; _stationGlobalThirdPersonCameraTransform = transform; _stationGlobalThirdPersonSavedLocalPosition = transform.localPosition; _stationGlobalThirdPersonSavedLocalRotation = transform.localRotation; _stationGlobalThirdPersonSavedFov = gameplayCamera.fieldOfView; _stationGlobalThirdPersonSaved = true; _stationGlobalThirdPersonCameraActive = true; } Transform operatorPoseAnchor = CCTVOperatorStation.OperatorPoseAnchor; if ((Object)(object)operatorPoseAnchor == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Persistent station third-person debug view dropped: operator pose anchor unavailable."); } SetStationThirdPersonDebugPersistent(active: false); RestoreStationGlobalThirdPersonDebugView(); return; } Renderer val2 = ForceLocalPlayerThirdPersonPreviewRenderers(val); Bounds bounds; bool num = TryGetPreviewRendererBounds(val2, out bounds); Transform val3 = operatorPoseAnchor; Vector3 val4 = (num ? ((Bounds)(ref bounds)).center : (((Component)val).transform.position + Vector3.up * 1.05f)); Vector3 val5; Vector3 val6; if ((Object)(object)val3 != (Object)null) { val5 = val3.forward; if (((Vector3)(ref val5)).sqrMagnitude > 0.0001f) { val5 = val3.forward; val6 = ((Vector3)(ref val5)).normalized; goto IL_0163; } } val6 = ((Component)val).transform.forward; goto IL_0163; IL_01a3: Vector3 val8; Vector3 val7 = (Vector3)val8; Vector3 val10; Vector3 val9 = val4 - val10 * 2.1f + val7 * 0.92f + Vector3.up * 0.34f; Vector3 val11 = val4 - val9; if (((Vector3)(ref val11)).sqrMagnitude < 0.0001f) { val11 = val10; } transform.SetPositionAndRotation(val9, Quaternion.LookRotation(((Vector3)(ref val11)).normalized, Vector3.up)); gameplayCamera.fieldOfView = 68f; if (!_stationGlobalThirdPersonFramingLogged) { _stationGlobalThirdPersonFramingLogged = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] Persistent station third-person debug camera active: target=" + FormatDebugVector(val4) + ", camera=" + FormatDebugVector(val9) + ", renderer=" + (((Object)(object)val2 != (Object)null) ? ((Object)val2).name : "") + ".")); } } return; IL_0163: val10 = val6; if ((Object)(object)val3 != (Object)null) { val5 = val3.right; if (((Vector3)(ref val5)).sqrMagnitude > 0.0001f) { val5 = val3.right; val8 = ((Vector3)(ref val5)).normalized; goto IL_01a3; } } val8 = ((Component)val).transform.right; goto IL_01a3; } private static void RestoreStationGlobalThirdPersonDebugView() { //IL_006c: 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) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (_stationGlobalThirdPersonSaved && (Object)(object)_stationGlobalThirdPersonCamera != (Object)null && (Object)(object)_stationGlobalThirdPersonCameraTransform != (Object)null && !_physicalFocusViewActive) { try { _stationGlobalThirdPersonCameraTransform.localPosition = _stationGlobalThirdPersonSavedLocalPosition; _stationGlobalThirdPersonCameraTransform.localRotation = _stationGlobalThirdPersonSavedLocalRotation; _stationGlobalThirdPersonCamera.fieldOfView = _stationGlobalThirdPersonSavedFov; } catch { } } _stationGlobalThirdPersonCameraActive = false; _stationGlobalThirdPersonCamera = null; _stationGlobalThirdPersonCameraTransform = null; _stationGlobalThirdPersonSavedLocalPosition = Vector3.zero; _stationGlobalThirdPersonSavedLocalRotation = Quaternion.identity; _stationGlobalThirdPersonSavedFov = 0f; _stationGlobalThirdPersonSaved = false; _stationGlobalThirdPersonFramingLogged = false; } private static void TickStationFocusAnchorHotkeys() { if (_focusViewExitPending) { return; } Keyboard current = Keyboard.current; if (current == null) { return; } if (((ButtonControl)current.f1Key).wasPressedThisFrame) { if (_stationEditMenuOpen) { CloseStationEditMenu("f1"); } else { OpenStationEditMenu(); } } else if (_stationEditMenuOpen) { if (((ButtonControl)current.digit1Key).wasPressedThisFrame || ((ButtonControl)current.numpad1Key).wasPressedThisFrame) { SelectStationEditMenuTarget(StationEditMenuTarget.BothHands); } else if (((ButtonControl)current.digit2Key).wasPressedThisFrame || ((ButtonControl)current.numpad2Key).wasPressedThisFrame) { SelectStationEditMenuTarget(StationEditMenuTarget.LeftHand); } else if (((ButtonControl)current.digit3Key).wasPressedThisFrame || ((ButtonControl)current.numpad3Key).wasPressedThisFrame) { SelectStationEditMenuTarget(StationEditMenuTarget.RightHandCamera); } else if (((ButtonControl)current.digit4Key).wasPressedThisFrame || ((ButtonControl)current.numpad4Key).wasPressedThisFrame) { SelectStationEditMenuTarget(StationEditMenuTarget.RightHandAction); } else if (((ButtonControl)current.digit5Key).wasPressedThisFrame || ((ButtonControl)current.numpad5Key).wasPressedThisFrame) { SelectStationEditMenuTarget(StationEditMenuTarget.FocusView); } else if (((ButtonControl)current.digit6Key).wasPressedThisFrame || ((ButtonControl)current.numpad6Key).wasPressedThisFrame) { SelectStationEditMenuTarget(StationEditMenuTarget.RadarView); } else if (((ButtonControl)current.digit7Key).wasPressedThisFrame || ((ButtonControl)current.numpad7Key).wasPressedThisFrame) { SelectStationEditMenuTarget(StationEditMenuTarget.ThirdPersonDebug); } else if (((ButtonControl)current.digit8Key).wasPressedThisFrame || ((ButtonControl)current.numpad8Key).wasPressedThisFrame) { SelectStationEditMenuTarget(StationEditMenuTarget.ThirdPersonPlayer); } else if (((ButtonControl)current.f6Key).wasPressedThisFrame) { CCTVOperatorStation.DumpControlGeometry("station-edit-menu"); } if (_stationEditMenuTarget == StationEditMenuTarget.BothHands) { TickStationBothHandsEditInput(current); } } } private static bool IsStationEditInputActive() { if (!_stationEditMenuOpen && !Y4NGZPlayerAnimationBridge.IsFirstPersonHandEditModeActive) { return CCTVOperatorStation.IsDebugPlacementActive; } return true; } private static void OpenStationEditMenu() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (!_stationEditMenuOpen) { if (_placementEditorOpen) { CancelPlacementEditor(restore: true); } CloseCameraReviewMenu(); _cameraPlacementEditModeOpen = false; _stationEditMenuOpen = true; _stationEditMenuTarget = StationEditMenuTarget.None; _stationRadarLookBlend = 0f; _stationRadarLookSuppressedUntil = Time.unscaledTime + 0.35f; _stationFocusAnchorForcedUntil = Time.unscaledTime + 0.35f; ShowTimedScanStatus("CCTV EDIT MENU", OVERLAY_ACTIVE_GREEN, 1f); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Station edit menu opened."); } } } internal static void CloseStationEditMenu(string reason) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) bool num = _stationEditMenuOpen || _stationEditMenuTarget != StationEditMenuTarget.None || Y4NGZPlayerAnimationBridge.IsFirstPersonHandEditModeActive || CCTVOperatorStation.IsDebugPlacementActive || _stationThirdPersonPreviewActive; _stationEditMenuOpen = false; _stationEditMenuTarget = StationEditMenuTarget.None; Y4NGZPlayerAnimationBridge.ExitFirstPersonHandEditModes(reason); CCTVOperatorStation.CancelDebugPlacement(); SetStationThirdPersonPreview(active: false, keepPersistentDebug: true); FinishFirstPersonArmsOffsetEditing(); _stationRadarLookBlend = 0f; _stationRadarLookSuppressedUntil = Time.unscaledTime + 0.35f; _stationFocusAnchorForcedUntil = Time.unscaledTime + 0.35f; if (num) { ShowTimedScanStatus("CCTV EDIT CLOSED", OVERLAY_ACTIVE_GREEN, 0.8f); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Station edit menu closed: reason=" + reason + ".")); } } } private static void SelectStationEditMenuTarget(StationEditMenuTarget target) { //IL_010d: Unknown result type (might be due to invalid IL or missing references) if (_stationEditMenuOpen && target != StationEditMenuTarget.None && _stationEditMenuTarget != target) { FinishFirstPersonArmsOffsetEditing(); Y4NGZPlayerAnimationBridge.ExitFirstPersonHandEditModes("station-edit-target-changed"); CCTVOperatorStation.CancelDebugPlacement(); SetStationThirdPersonPreview(active: false, keepPersistentDebug: true); _stationEditMenuTarget = target; _stationRadarLookBlend = 0f; _stationRadarLookSuppressedUntil = Time.unscaledTime + 0.35f; _stationFocusAnchorForcedUntil = Time.unscaledTime + 0.35f; switch (target) { case StationEditMenuTarget.BothHands: EnsureFirstPersonArmsEnabledForEdit(); EnsureFirstPersonArmsOffsetLoaded(); _firstPersonArmsOffsetEditingLastFrame = true; ApplyFirstPersonArmsOffsetToForcedRenderers(); ShowFirstPersonArmsOffsetStatus(force: true); break; case StationEditMenuTarget.LeftHand: Y4NGZPlayerAnimationBridge.StartFirstPersonLeftHandEditMode("station-edit-menu"); break; case StationEditMenuTarget.RightHandCamera: Y4NGZPlayerAnimationBridge.StartFirstPersonRightHandBlueEditMode("station-edit-menu"); break; case StationEditMenuTarget.RightHandAction: Y4NGZPlayerAnimationBridge.StartFirstPersonRightHandGreenEditMode("station-edit-menu"); break; case StationEditMenuTarget.FocusView: CCTVOperatorStation.StartDebugPlacement("focus"); break; case StationEditMenuTarget.RadarView: CCTVOperatorStation.StartDebugPlacement("radar"); break; case StationEditMenuTarget.ThirdPersonDebug: SetStationThirdPersonPreview(active: true); break; case StationEditMenuTarget.ThirdPersonPlayer: SetStationThirdPersonPreview(active: true); CCTVOperatorStation.StartDebugPlacement("player"); break; } ShowTimedScanStatus("EDIT " + GetStationEditMenuTargetLabel(target), OVERLAY_ACTIVE_GREEN, 0.8f); } } private static void EnsureFirstPersonArmsEnabledForEdit() { if (!Y4NGZPlayerAnimationBridge.UseLocalAuthoredOperatorAnimations && SurveillanceBootstrap.Config?.LocalAuthoredOperatorAnimationsEnabled != null) { SurveillanceBootstrap.Config.LocalAuthoredOperatorAnimationsEnabled.Value = true; Y4NGZPlayerAnimationBridge.RefreshLocalAuthoredOperatorAnimationSetting("station-edit-menu-enabled-first-person-arms"); RefreshLocalOperatorFirstPersonVisibility(); } } private static void TickStationBothHandsEditInput(Keyboard keyboard) { //IL_0031: 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_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_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0176: 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_0181: 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_018b: Unknown result type (might be due to invalid IL or missing references) if (keyboard == null || !CanEditFirstPersonArmsOffset()) { return; } EnsureFirstPersonArmsOffsetLoaded(); _firstPersonArmsOffsetEditingLastFrame = true; if (((ButtonControl)keyboard.digit0Key).wasPressedThisFrame || ((ButtonControl)keyboard.numpad0Key).wasPressedThisFrame) { _firstPersonArmsOffset = Vector3.zero; _firstPersonArmsOffsetDirty = true; ApplyFirstPersonArmsOffsetToForcedRenderers(); FlushFirstPersonArmsOffsetConfig(); ShowFirstPersonArmsOffsetStatus(force: true); return; } Vector3 zero = Vector3.zero; if (((ButtonControl)keyboard.aKey).isPressed) { zero.x -= 1f; } if (((ButtonControl)keyboard.dKey).isPressed) { zero.x += 1f; } if (((ButtonControl)keyboard.fKey).isPressed || ((ButtonControl)keyboard.pageDownKey).isPressed) { zero.y -= 1f; } if (((ButtonControl)keyboard.rKey).isPressed || ((ButtonControl)keyboard.pageUpKey).isPressed) { zero.y += 1f; } if (((ButtonControl)keyboard.sKey).isPressed) { zero.z -= 1f; } if (((ButtonControl)keyboard.wKey).isPressed) { zero.z += 1f; } if (!(((Vector3)(ref zero)).sqrMagnitude <= 0.0001f)) { float num = ((((ButtonControl)keyboard.leftShiftKey).isPressed || ((ButtonControl)keyboard.rightShiftKey).isPressed) ? 1.2f : 0.22f); float num2 = Mathf.Max(Time.unscaledDeltaTime, 0.001f); _firstPersonArmsOffset = ClampFirstPersonArmsOffset(_firstPersonArmsOffset + ((Vector3)(ref zero)).normalized * num * num2); _firstPersonArmsOffsetDirty = true; ApplyFirstPersonArmsOffsetToForcedRenderers(); ShowFirstPersonArmsOffsetStatus(force: false); } } internal static string GetStationEditMenuOverlayText() { if (!_stationEditMenuOpen) { return null; } string text = ((_stationEditMenuTarget == StationEditMenuTarget.None) ? "SELECT TARGET" : GetStationEditMenuTargetLabel(_stationEditMenuTarget)); string stationEditMenuTargetDetails = GetStationEditMenuTargetDetails(_stationEditMenuTarget); return "CCTV EDIT MENU\n1 BOTH HANDS\n2 LEFT HAND LEVER\n3 RH CAMERA BUTTON\n4 RH ACTION BUTTON\n5 NORMAL VIEWPOINT\n6 RADAR VIEWPOINT\n7 THIRD PERSON DEBUG\n8 3P PLAYER MODEL\nF6 DUMP CONTROLS\nTARGET " + text + "\n" + stationEditMenuTargetDetails + "F1/ESC EXIT EDIT"; } internal static string GetCameraPlacementEditOverlayText() { if (!IsFocused) { return null; } if (_placementEditorOpen) { return BuildPlacementEditorOverlayText(); } if (_reviewMenuOpen) { return BuildCameraReviewMenuOverlayText(); } if (!_cameraPlacementEditModeOpen) { return null; } return BuildCameraPlacementEditModeOverlayText(); } private static string BuildCameraPlacementEditModeOverlayText() { CCTVCamera activeCamera = GetActiveCamera(); string text = (((Object)(object)activeCamera != (Object)null) ? activeCamera.ResolvedLabel : "NO CAMERA"); int num = Mathf.Max(1, QuadCameraAssignment.CurrentPage + 1); int num2 = Mathf.Max(1, QuadCameraAssignment.TotalPages); return "CAMERA EDIT\nACTIVE " + text + "\nPAGE " + num + "/" + num2 + "\n\nMOUSE AIM CAMERA\nARROWS CAMERA LIST\nF5/1 ADJUST CAMERA\nF6/2 ADD CAMERA\nF4 RATE CAMERA\nDEL DELETE CAMERA\nF2 EXIT CAMERA EDIT\nE/ESC EXIT CCTV"; } private static string GetStationEditMenuTargetDetails(StationEditMenuTarget target) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_00aa: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0147: 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_019f: Unknown result type (might be due to invalid IL or missing references) switch (target) { case StationEditMenuTarget.BothHands: EnsureFirstPersonArmsOffsetLoaded(); return "POS " + FormatStationEditVector(_firstPersonArmsOffset) + "\nWASD X/Z R/F UP/DOWN\nSHIFT FAST 0 RESET\n"; case StationEditMenuTarget.LeftHand: { Y4NGZPlayerAnimationBridge.FirstPersonRightHandPoseTuning firstPersonLeftHandPoseTuning = Y4NGZPlayerAnimationBridge.GetFirstPersonLeftHandPoseTuning(); return "POS " + FormatStationEditVector(firstPersonLeftHandPoseTuning.Offset) + "\nROT " + FormatStationEditVector(firstPersonLeftHandPoseTuning.Euler) + "\nWASD X/Z R/F UP/DOWN\nCTRL ROTATE SHIFT FAST 0 RESET\n"; } case StationEditMenuTarget.RightHandCamera: { Y4NGZPlayerAnimationBridge.FirstPersonRightHandPoseTuning firstPersonRightHandPoseTuning = Y4NGZPlayerAnimationBridge.GetFirstPersonRightHandPoseTuning(1); return "POS " + FormatStationEditVector(firstPersonRightHandPoseTuning.Offset) + "\nROT " + FormatStationEditVector(firstPersonRightHandPoseTuning.Euler) + "\nWASD X/Z R/F UP/DOWN\nCTRL ROTATE SHIFT FAST 0 RESET\n"; } case StationEditMenuTarget.RightHandAction: { Y4NGZPlayerAnimationBridge.FirstPersonRightHandPoseTuning firstPersonRightHandPoseTuning2 = Y4NGZPlayerAnimationBridge.GetFirstPersonRightHandPoseTuning(0); return "POS " + FormatStationEditVector(firstPersonRightHandPoseTuning2.Offset) + "\nROT " + FormatStationEditVector(firstPersonRightHandPoseTuning2.Euler) + "\nWASD X/Z R/F UP/DOWN\nCTRL ROTATE SHIFT FAST 0 RESET\n"; } case StationEditMenuTarget.FocusView: { Transform focusViewAnchor = CCTVOperatorStation.FocusViewAnchor; return (((Object)(object)focusViewAnchor != (Object)null) ? ("POS " + FormatStationEditVector(focusViewAnchor.localPosition) + "\nROT " + FormatStationEditVector(focusViewAnchor.localEulerAngles) + "\n") : string.Empty) + "WASD/ARROWS MOVE X/Z\nQ/E UP/DOWN\nF/G PITCH R/T YAW\nZ/X ROLL ENTER SAVE\n"; } case StationEditMenuTarget.RadarView: { Transform radarViewAnchor = CCTVOperatorStation.RadarViewAnchor; return (((Object)(object)radarViewAnchor != (Object)null) ? ("ROT " + FormatStationEditVector(radarViewAnchor.localEulerAngles) + "\n") : string.Empty) + "ROTATION ONLY - POSITION LOCKED\nA/D OR ARROWS PIVOT\nF/G PITCH R/T YAW\nZ/X ROLL ENTER SAVE\n"; } case StationEditMenuTarget.ThirdPersonDebug: return "MOUSE ORBIT CAMERA\nCAMERA CONTROL DISABLED\n"; case StationEditMenuTarget.ThirdPersonPlayer: return "WASD/ARROWS MOVE X/Z\nQ/E UP/DOWN\nF/G PITCH R/T YAW\nZ/X ROLL ENTER SAVE\n"; default: return "PRESS 1-8 TO EDIT\n"; } } private static string GetStationEditMenuTargetLabel(StationEditMenuTarget target) { return target switch { StationEditMenuTarget.BothHands => "BOTH HANDS", StationEditMenuTarget.LeftHand => "LEFT HAND LEVER", StationEditMenuTarget.RightHandCamera => "RH CAMERA BUTTON", StationEditMenuTarget.RightHandAction => "RH ACTION BUTTON", StationEditMenuTarget.FocusView => "NORMAL VIEWPOINT", StationEditMenuTarget.RadarView => "RADAR VIEWPOINT", StationEditMenuTarget.ThirdPersonDebug => "THIRD PERSON DEBUG", StationEditMenuTarget.ThirdPersonPlayer => "3P PLAYER MODEL", _ => "NONE", }; } private static string FormatStationEditVector(Vector3 value) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"{value.x:+0.00;-0.00;0.00},{value.y:+0.00;-0.00;0.00},{value.z:+0.00;-0.00;0.00}"; } private static bool IsStationRadarLookHeld() { Keyboard current = Keyboard.current; if (current != null && ((ButtonControl)current.spaceKey).isPressed) { return true; } return false; } private static void ResetStationRadarLookView() { HoldStationFocusAnchorForAction(0.45f); } private static void HoldStationFocusAnchorForAction(float seconds) { float num = Mathf.Max(0.05f, seconds); _stationRadarLookBlend = 0f; _stationRadarLookSuppressedUntil = Time.unscaledTime + Mathf.Max(0.35f, num); _stationFocusAnchorForcedUntil = Time.unscaledTime + num; if (_radarLookEventState) { _radarLookEventState = false; CCTVStationEvents.RaiseRadarViewChanged(lookingAtRadar: false); } } private static void ScheduleStationCameraControlActivation() { _stationCameraControlActive = false; _stationCameraControlEnablePending = true; _stationCameraControlEnableAt = Time.unscaledTime + 1.35f; } private static void DisableStationCameraControl() { _stationCameraControlEnablePending = false; _stationCameraControlEnableAt = 0f; if (_stationCameraControlActive) { _stationCameraControlActive = false; CCTVStationEvents.RaiseCameraControlChanged(controllingCamera: false); } } private static void TickStationCameraControlActivation() { if (!_stationCameraControlEnablePending) { return; } if (!IsFocused || _focusViewExitPending) { _stationCameraControlEnablePending = false; } else if (!(Time.unscaledTime < _stationCameraControlEnableAt)) { _stationCameraControlEnablePending = false; if (!_stationCameraControlActive) { _stationCameraControlActive = true; CCTVStationEvents.RaiseCameraControlChanged(controllingCamera: true); } } } internal static void TickFrame() { bool flag = BeginEntryPerfFrame(); try { TickFrameCore(); } finally { if (flag) { EndEntryPerfFrame(); } } } private static void TickFrameCore() { TickEntryPoseSettle(); EntryPerfMark("TickEntryPoseSettle.rest"); if (_enterPerfLogPending && Time.frameCount > _enterPerfFrame) { _enterPerfLogPending = false; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV][EnterPerf] engine frame time spanning enter: {Time.unscaledDeltaTime * 1000f:F0}ms"); } } TickExitSeamSampling(); TickExitCameraLocalYawInvariantReassert(); TickExitPostureDiagnostic(); EntryPerfMark("exit-diagnostics"); TickPendingStationFeedFlip(); EntryPerfMark("TickPendingStationFeedFlip"); TickPendingLocalObstructorRestore(); EntryPerfMark("TickPendingLocalObstructorRestore"); bool isOperatorDebugToolsEnabled = IsOperatorDebugToolsEnabled; TickOperatorDebugToolsGate(isOperatorDebugToolsEnabled); if (isOperatorDebugToolsEnabled) { TickStationThirdPersonDebugHotkey(); TickLocalFirstPersonOperatorAnimationHotkey(); } if (!IsFocused) { TickStationGlobalThirdPersonDebugView(); TickFocusHudScanRearm(); } EntryPerfMark("debug-hotkeys"); if (WasActiveThisFrame && Time.frameCount > _wasActiveSetFrame) { WasActiveThisFrame = false; } if (IsFocused) { EnforceFocusInputLock(); EntryPerfMark("EnforceFocusInputLock"); RunFocusPerfStep("ApplyStationPlayerPoseLock", ApplyStationPlayerPoseLock); if (isOperatorDebugToolsEnabled && !_stationEditMenuOpen) { TickFirstPersonArmsOffsetHotkeys(); } EntryPerfMark("TickFirstPersonArmsOffsetHotkeys"); RunFocusPerfStep("ReassertLocalPlayerObstructors", ReassertLocalPlayerObstructors); RunFocusPerfStep("ApplyPhysicalFocusView", ApplyPhysicalFocusView); RunFocusPerfStep("ApplyFirstPersonArmsCameraFollow", ApplyFirstPersonArmsOffsetToForcedRenderers); if (!IsFocused) { return; } TickStationCameraControlActivation(); EntryPerfMark("TickStationCameraControlActivation"); if (_focusViewExitPending) { EntryPerfMark("exit-pending-render"); return; } bool isHackingOverlayOpen = IsHackingOverlayOpen; bool isMainframeOverlayOpen = IsMainframeOverlayOpen; if (isOperatorDebugToolsEnabled) { TickStationFocusAnchorHotkeys(); } EntryPerfMark("TickStationFocusAnchorHotkeys"); if (isOperatorDebugToolsEnabled && !isHackingOverlayOpen && !isMainframeOverlayOpen) { TickPlacementEditorInput(); } EntryPerfMark("TickPlacementEditorInput"); if (isOperatorDebugToolsEnabled && !isHackingOverlayOpen && !isMainframeOverlayOpen && !_placementEditorOpen) { TickCameraReviewInput(); } EntryPerfMark("TickCameraReviewInput"); if (IsStationEditInputActive()) { TickStationFocusMaintenance(); EntryPerfMark("TickStationFocusMaintenance.rest"); return; } if (_placementEditorOpen || _reviewMenuOpen) { TickStationFocusMaintenance(); EntryPerfMark("TickStationFocusMaintenance.rest"); return; } if (isHackingOverlayOpen || isMainframeOverlayOpen) { TickInteractiveOverlays(); EntryPerfMark("TickInteractiveOverlays"); } else { TickStationRadarZoomInput(); EntryPerfMark("TickStationRadarZoomInput"); } TickStationFocusMaintenance(); EntryPerfMark("TickStationFocusMaintenance.rest"); } else { RestoreFocusHudDimming(); CctvOutlineManager.Tick(null, isActive: false); CctvScreenOutlineOverlay.Tick(focused: false); if ((Object)(object)_cameraAudioProxyListener != (Object)null && ((Behaviour)_cameraAudioProxyListener).enabled) { RestoreAudioListenerToPlayer(); } } } private static void TickExitSeamSampling() { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_0105: 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_0157: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime >= _exitSeamLogUntil || Time.unscaledTime < _exitSeamNextLogAt) { return; } _exitSeamNextLogAt = Time.unscaledTime + 0.15f; PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val.gameplayCamera == (Object)null)) { string arg = (((Object)(object)val.playerBodyAnimator != (Object)null && (Object)(object)val.playerBodyAnimator.runtimeAnimatorController != (Object)null) ? ((Object)val.playerBodyAnimator.runtimeAnimatorController).name : ""); Transform transform = ((Component)val.gameplayCamera).transform; float num = Quaternion.Angle(_exitSeamReferenceRotation, transform.rotation); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][ExitSeam] t+{Time.unscaledTime - _exitSeamStartedAt:F2}s " + "camPos=" + FormatDebugVector(transform.position) + " " + $"camYaw={GetPlanarYaw(transform.forward):F1} " + $"camPitch={GetSignedCameraPitchDegrees(transform.rotation):F1} " + $"rotationDelta={num:F3}deg " + $"bodyYaw={((Component)val).transform.eulerAngles.y:F1} controller='{arg}'.")); } } } private static void ScheduleExitPostureDiagnostic(PlayerControllerB player) { if (!((Object)(object)player == (Object)null)) { _exitPosturePlayer = player; _exitPostureRestoredAt = Time.unscaledTime; _exitPostureSampleIndex = 0; _exitPostureLogAt = _exitPostureRestoredAt + 0.25f; _exitPostureLogPending = true; } } private static void TickExitPostureDiagnostic() { //IL_0081: 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) //IL_00bb: 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 (!_exitPostureLogPending || Time.unscaledTime < _exitPostureLogAt) { return; } PlayerControllerB exitPosturePlayer = _exitPosturePlayer; if ((Object)(object)exitPosturePlayer == (Object)null) { _exitPostureLogPending = false; _exitPosturePlayer = null; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV][ExitPosture] player unavailable for the scheduled sample."); } return; } try { Transform val = (((Object)(object)exitPosturePlayer.gameplayCamera != (Object)null) ? ((Component)exitPosturePlayer.gameplayCamera).transform : null); Transform cameraContainerTransform = exitPosturePlayer.cameraContainerTransform; Transform playerModelArmsMetarig = exitPosturePlayer.playerModelArmsMetarig; string text = (((Object)(object)val != (Object)null) ? FormatDebugVector(val.localEulerAngles) : ""); string text2 = (((Object)(object)cameraContainerTransform != (Object)null) ? FormatDebugVector(cameraContainerTransform.localPosition) : ""); string text3 = (((Object)(object)cameraContainerTransform != (Object)null) ? FormatDebugVector(cameraContainerTransform.localEulerAngles) : ""); string text4 = (((Object)(object)playerModelArmsMetarig != (Object)null) ? FormatDebugVector(playerModelArmsMetarig.localEulerAngles) : ""); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)($"[LethalCCTV][ExitPosture] t+{Time.unscaledTime - _exitPostureRestoredAt:F2}s " + "gameplayCamera.localEulerAngles=" + text + " cameraContainer.localPosition=" + text2 + " cameraContainer.localEulerAngles=" + text3 + " playerModelArmsMetarig.localEulerAngles=" + text4 + " " + $"inSpecialInteractAnimation={exitPosturePlayer.inSpecialInteractAnimation} " + $"enteringSpecialAnimation={exitPosturePlayer.enteringSpecialAnimation}.")); } } catch (Exception ex) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV][ExitPosture] sample failed: " + ex.Message)); } } if (_exitPostureSampleIndex == 0) { _exitPostureSampleIndex = 1; _exitPostureLogAt = _exitPostureRestoredAt + 1f; } else { _exitPostureLogPending = false; _exitPosturePlayer = null; } } internal static void EnforceExitCameraLocalYawInvariant(PlayerControllerB player, string reason, bool reassertNextFrame = false) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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_0185: 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_01b7: Unknown result type (might be due to invalid IL or missing references) if (reassertNextFrame) { _exitCameraInvariantPlayer = player; _exitCameraInvariantScheduledFrame = Time.frameCount; } if ((Object)(object)player == (Object)null || (Object)(object)player.gameplayCamera == (Object)null) { return; } try { Transform transform = ((Component)player).transform; Transform transform2 = ((Component)player.gameplayCamera).transform; Vector3 localEulerAngles = transform2.localEulerAngles; float num = Mathf.DeltaAngle(0f, localEulerAngles.y); float y = transform.eulerAngles.y; float planarYaw = GetPlanarYaw(transform2.forward); if (Mathf.Abs(num) > 0.0001f) { transform.rotation = Quaternion.AngleAxis(num, Vector3.up) * transform.rotation; } transform2.localEulerAngles = new Vector3(localEulerAngles.x, 0f, 0f); float num2 = Mathf.DeltaAngle(GetPlanarYaw(transform2.forward), planarYaw); if (Mathf.Abs(num2) > 0.0001f) { transform.rotation = Quaternion.AngleAxis(num2, Vector3.up) * transform.rotation; transform2.localEulerAngles = new Vector3(localEulerAngles.x, 0f, 0f); } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogMessage((object)("[LethalCCTV][ExitCameraInvariant] reason=" + reason + " " + $"residualLocalYaw={num:F2} viewYawCorrection={num2:F3} " + $"bodyYaw={y:F1}->{transform.eulerAngles.y:F1} " + $"viewYaw={planarYaw:F1}->{GetPlanarYaw(transform2.forward):F1} " + "cameraLocal=" + FormatDebugVector(localEulerAngles) + "->" + FormatDebugVector(transform2.localEulerAngles) + " " + $"reassertNextFrame={reassertNextFrame}.")); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][ExitCameraInvariant] enforcement failed (" + reason + "): " + ex.Message)); } } } private static void TickExitCameraLocalYawInvariantReassert() { if (_exitCameraInvariantScheduledFrame >= 0 && Time.frameCount > _exitCameraInvariantScheduledFrame) { PlayerControllerB exitCameraInvariantPlayer = _exitCameraInvariantPlayer; _exitCameraInvariantPlayer = null; _exitCameraInvariantScheduledFrame = -1; EnforceExitCameraLocalYawInvariant(exitCameraInvariantPlayer, "frame-after-deferred-rig-rebuild"); } } private static float GetPlanarYaw(Vector3 direction) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) direction.y = 0f; if (!(((Vector3)(ref direction)).sqrMagnitude > 1E-06f)) { return 0f; } return Mathf.Atan2(direction.x, direction.z) * 57.29578f; } private static float GetSignedCameraPitchDegrees(Quaternion rotation) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_0026: Unknown result type (might be due to invalid IL or missing references) Vector3 val = rotation * Vector3.forward; Vector2 val2 = new Vector2(val.x, val.z); float magnitude = ((Vector2)(ref val2)).magnitude; return Mathf.Atan2(0f - val.y, magnitude) * 57.29578f; } private static float GetMaxPresentationCameraPitchDegrees() { return 16f; } private static float ClampPresentationCameraPitchDegrees(float pitchDegrees) { return Mathf.Min(pitchDegrees, GetMaxPresentationCameraPitchDegrees()); } private static Quaternion ClampPresentationCameraPitch(Quaternion rotation) { //IL_0000: 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) //IL_0020: 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_0037: 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) float signedCameraPitchDegrees = GetSignedCameraPitchDegrees(rotation); float num = ClampPresentationCameraPitchDegrees(signedCameraPitchDegrees); if (Mathf.Abs(num - signedCameraPitchDegrees) <= 0.0001f) { return rotation; } float planarYaw = GetPlanarYaw(rotation * Vector3.forward); return Quaternion.Euler(num, planarYaw, 0f); } internal static void LogPendingViewFraming(Camera camera, Transform leftShoulder, Transform rightShoulder) { Vector3? buttonPoint; bool monitorResolved; Vector3 monitorCenter; if ((_settleViewFramingLogPending || _arrivalViewFramingLogPending) && !((Object)(object)camera == (Object)null)) { buttonPoint = Y4NGZPlayerAnimationBridge.ResolveAccessButtonPressPoint(); monitorResolved = CCTVOperatorStation.TryResolveMainMonitorScreenFrame(out monitorCenter, out var _, out var _, out var _, out var _, out var _); if (_settleViewFramingLogPending) { _settleViewFramingLogPending = false; LogPhase("settle-complete"); } if (_arrivalViewFramingLogPending) { _arrivalViewFramingLogPending = false; LogPhase("arrival"); } } void LogPhase(string phase) { //IL_0020: 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_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_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) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) string text = (buttonPoint.HasValue ? FormatDebugVector(camera.WorldToViewportPoint(buttonPoint.Value)) : ""); string text2 = (monitorResolved ? FormatDebugVector(camera.WorldToViewportPoint(monitorCenter)) : ""); string text3 = (((Object)(object)leftShoulder != (Object)null) ? FormatDebugVector(camera.WorldToViewportPoint(leftShoulder.position)) : ""); string text4 = (((Object)(object)rightShoulder != (Object)null) ? FormatDebugVector(camera.WorldToViewportPoint(rightShoulder.position)) : ""); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][ViewFraming] phase={phase} frame={Time.frameCount} " + $"cameraPitch={GetSignedCameraPitchDegrees(((Component)camera).transform.rotation):F2} " + $"maxPitch={GetMaxPresentationCameraPitchDegrees():F2} " + "button.viewport=" + text + " monitor-screen-center.viewport=" + text2 + " shoulder.L.viewport=" + text3 + " shoulder.R.viewport=" + text4 + ".")); } } } private static void TickStationFocusMaintenance(bool force = false) { float unscaledTime = Time.unscaledTime; RunFocusPerfStep("ApplyFocusHudDimming", delegate { ApplyFocusHudDimming(force); }); RunFocusPerfStep("SyncCameraAudioProxy", SyncCameraAudioProxy); if (force || unscaledTime >= _nextStationFocusOverlayRefreshAt) { _nextStationFocusOverlayRefreshAt = unscaledTime + 0.2f; RunFocusPerfStep("RefreshBodycamFocusSlot", RefreshBodycamFocusSlot); RunFocusPerfStep("RefreshTurretFocusPage", RefreshTurretFocusPage); } } private static void RunFocusPerfStep(string stepName, Action action) { if (action == null) { return; } if (!IsFocused) { action(); EntryPerfMark(stepName); return; } long timestamp = Stopwatch.GetTimestamp(); try { action(); } finally { FocusPerfProbe.RecordStep("MonitorFocus." + stepName, Stopwatch.GetTimestamp() - timestamp); EntryPerfMark(stepName); } } } internal static class NightVisionBaker { private sealed class AgcState { public float Gain = 1f; public float NextSampleAt; public bool RequestPending; } private const float AgcSampleIntervalSeconds = 0.5f; private const float AgcTargetLinearLuma = 0.18f; private const float AgcMinGain = 0.35f; private const float AgcSmoothing = 0.35f; private const int AgcProbeSize = 8; private static bool _subscribed; private static Material _bakeMat; private static readonly Dictionary _camToSlot = new Dictionary(4); private static readonly Dictionary _agcBySlot = new Dictionary(4); private static RenderTexture _agcProbeRT; private static CCTVCamera _activeFillLightHolder; internal static bool IsActive => (Object)(object)_bakeMat != (Object)null; internal static Material BakeMaterial => _bakeMat; internal static bool TryStart() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown if (_subscribed) { return (Object)(object)_bakeMat != (Object)null; } Shader val = NightVisionShader.TryLoad(); if ((Object)(object)val == (Object)null) { return false; } _bakeMat = new Material(val) { name = "LethalCCTV_NightVisionBakeMat", hideFlags = (HideFlags)61 }; RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering; RenderPipelineManager.endCameraRendering += OnEndCameraRendering; _subscribed = true; SurveillanceBootstrap.Log.LogInfo((object)"[LethalCCTV][NightVisionBaker] Subscribed to RenderPipelineManager begin/end camera rendering; bake material allocated."); return true; } internal static void Shutdown() { DisableActiveFillLight(); RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering; RenderPipelineManager.endCameraRendering -= OnEndCameraRendering; _subscribed = false; _camToSlot.Clear(); _agcBySlot.Clear(); if ((Object)(object)_agcProbeRT != (Object)null) { _agcProbeRT.Release(); Object.Destroy((Object)(object)_agcProbeRT); _agcProbeRT = null; } if ((Object)(object)_bakeMat != (Object)null) { Object.Destroy((Object)(object)_bakeMat); _bakeMat = null; } } private static void OnBeginCameraRendering(ScriptableRenderContext _, Camera cam) { DisableActiveFillLight(); if (!((Object)(object)cam == (Object)null) && _camToSlot.ContainsKey(cam)) { CCTVCamera component = ((Component)cam).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.SetNightVisionFillLightActive(active: true); _activeFillLightHolder = component; } } } internal static void Register(Camera cam, int slot) { if (IsActive && !((Object)(object)cam == (Object)null)) { _camToSlot[cam] = slot; } } internal static void Unregister(Camera cam) { if (!((Object)(object)cam == (Object)null)) { _camToSlot.Remove(cam); } } internal static void ClearRegistrations() { _camToSlot.Clear(); _agcBySlot.Clear(); } private static void OnEndCameraRendering(ScriptableRenderContext _, Camera cam) { try { if ((Object)(object)cam == (Object)null || !_camToSlot.TryGetValue(cam, out var value) || (Object)(object)_bakeMat == (Object)null) { return; } RenderTexture[] rawRTs = QuadMonitor.RawRTs; RenderTexture[] quadRTs = QuadMonitor.QuadRTs; if (rawRTs == null || quadRTs == null || value < 0 || value >= rawRTs.Length || value >= quadRTs.Length) { return; } RenderTexture val = rawRTs[value]; RenderTexture val2 = quadRTs[value]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null)) { float num = ResolveGain(value, val); if (_bakeMat.HasProperty(NightVisionShader.VhsPhasePropertyId)) { _bakeMat.SetFloat(NightVisionShader.VhsPhasePropertyId, Time.unscaledTime); } if (_bakeMat.HasProperty(NightVisionShader.GainPropertyId)) { _bakeMat.SetFloat(NightVisionShader.GainPropertyId, num); } Graphics.Blit((Texture)(object)val, val2, _bakeMat, 0); } } finally { DisableActiveFillLight(); } } private static void DisableActiveFillLight() { if ((Object)(object)_activeFillLightHolder != (Object)null) { _activeFillLightHolder.SetNightVisionFillLightActive(active: false); _activeFillLightHolder = null; } } private static float ResolveGain(int slot, RenderTexture src) { LethalCCTVConfig config = SurveillanceBootstrap.Config; float num = config?.NightVisionGain.Value ?? 2f; if ((config != null && !config.NightVisionAutoGain.Value) || !SystemInfo.supportsAsyncGPUReadback) { return num; } if (!_agcBySlot.TryGetValue(slot, out var value)) { value = new AgcState { Gain = Mathf.Min(num, 1f) }; _agcBySlot[slot] = value; } if (!value.RequestPending && Time.unscaledTime >= value.NextSampleAt) { value.RequestPending = true; value.NextSampleAt = Time.unscaledTime + 0.5f; SampleAverageLuma(src, value, num); } return Mathf.Clamp(value.Gain, 0.35f, num); } private static void SampleAverageLuma(RenderTexture src, AgcState state, float configGain) { //IL_006b: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown try { if ((Object)(object)_agcProbeRT == (Object)null) { _agcProbeRT = new RenderTexture(8, 8, 0, (RenderTextureFormat)0) { name = "LethalCCTV_NightVisionAgcProbe", hideFlags = (HideFlags)61 }; _agcProbeRT.Create(); } Graphics.Blit((Texture)(object)src, _agcProbeRT); AsyncGPUReadback.Request((Texture)(object)_agcProbeRT, 0, (TextureFormat)4, (Action)delegate(AsyncGPUReadbackRequest request) { //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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) //IL_0052: 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) state.RequestPending = false; if (!((AsyncGPUReadbackRequest)(ref request)).hasError) { NativeArray data = ((AsyncGPUReadbackRequest)(ref request)).GetData(0); if (data.Length != 0) { float num = 0f; for (int i = 0; i < data.Length; i++) { Color32 val = data[i]; float num2 = (0.299f * (float)(int)val.r + 0.587f * (float)(int)val.g + 0.114f * (float)(int)val.b) / 255f; num += Mathf.Pow(num2, 2.2f); } float num3 = num / (float)data.Length; float num4 = Mathf.Clamp(0.18f / Mathf.Max(num3, 0.001f), 0.35f, configGain); state.Gain = Mathf.Lerp(state.Gain, num4, 0.35f); } } }); } catch { state.RequestPending = false; } } } internal static class NightVisionShader { private const string BUNDLE_FILE_NAME = "lethalcctv-nightvision.shaderbundle"; private const string SHADER_NAME = "LethalCCTV/NightVision"; internal static readonly int GainPropertyId = Shader.PropertyToID("_Gain"); internal static readonly int GrayscaleEnabledPropertyId = Shader.PropertyToID("_GrayscaleEnabled"); internal static readonly int FlipYPropertyId = Shader.PropertyToID("_FlipY"); internal static readonly int TintPropertyId = Shader.PropertyToID("_Tint"); internal static readonly int VhsPhasePropertyId = Shader.PropertyToID("_VhsPhase"); internal static readonly int ColorRetentionPropertyId = Shader.PropertyToID("_ColorRetention"); internal static readonly int ScanlineStrengthPropertyId = Shader.PropertyToID("_ScanlineStrength"); internal static readonly int NoiseStrengthPropertyId = Shader.PropertyToID("_NoiseStrength"); internal static readonly int VignetteStrengthPropertyId = Shader.PropertyToID("_VignetteStrength"); internal static readonly int ChromaAberrationPropertyId = Shader.PropertyToID("_ChromaAberration"); internal static readonly int RollBarStrengthPropertyId = Shader.PropertyToID("_RollBarStrength"); internal static readonly int RollBarSpeedPropertyId = Shader.PropertyToID("_RollBarSpeed"); internal static readonly int CurvatureStrengthPropertyId = Shader.PropertyToID("_CurvatureStrength"); internal static readonly int InterlaceStrengthPropertyId = Shader.PropertyToID("_InterlaceStrength"); internal static readonly int DropoutStrengthPropertyId = Shader.PropertyToID("_DropoutStrength"); private static bool _loadAttempted; private static Shader _shader; private static AssetBundle _bundle; internal static bool IsAvailable => (Object)(object)_shader != (Object)null; internal static Shader TryLoad() { if (_loadAttempted) { return _shader; } _loadAttempted = true; try { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (string.IsNullOrEmpty(directoryName)) { SurveillanceBootstrap.Log.LogWarning((object)"[LethalCCTV][NightVision] Cannot resolve plugin directory — skipping shader load. Night-vision will be unavailable; quads keep vanilla HDRP/Unlit."); return null; } string text = Path.Combine(directoryName, "lethalcctv-nightvision.shaderbundle"); if (!File.Exists(text)) { SurveillanceBootstrap.Log.LogWarning((object)("[LethalCCTV][NightVision] Shader bundle not found at '" + text + "'. Night-vision treatment will be unavailable; quads keep vanilla HDRP/Unlit. To enable: compile Shaders/NightVision.shader into 'lethalcctv-nightvision.shaderbundle' via a Unity Editor with HDRP installed and drop it next to the active plugin DLL.")); return null; } _bundle = AssetBundle.LoadFromFile(text); if ((Object)(object)_bundle == (Object)null) { SurveillanceBootstrap.Log.LogError((object)("[LethalCCTV][NightVision] AssetBundle.LoadFromFile returned null for '" + text + "'. Bundle may be corrupt or built against an incompatible Unity version. Night-vision treatment will be unavailable.")); return null; } Shader val = null; Object[] array = _bundle.LoadAllAssets(typeof(Shader)); if (array != null) { foreach (Object obj in array) { Shader val2 = (Shader)(object)((obj is Shader) ? obj : null); if ((Object)(object)val2 != (Object)null && ((Object)val2).name == "LethalCCTV/NightVision") { val = val2; break; } } if ((Object)(object)val == (Object)null && array.Length != 0) { Object obj2 = array[0]; Shader val3 = (Shader)(object)((obj2 is Shader) ? obj2 : null); if ((Object)(object)val3 != (Object)null && array.Length == 1) { SurveillanceBootstrap.Log.LogWarning((object)("[LethalCCTV][NightVision] Bundle contains exactly one Shader but its name '" + ((Object)val3).name + "' != expected 'LethalCCTV/NightVision'. Accepting it anyway — verify Shaders/NightVision.shader's top-line declaration.")); val = val3; } } } if ((Object)(object)val == (Object)null) { SurveillanceBootstrap.Log.LogError((object)("[LethalCCTV][NightVision] Bundle loaded but no Shader matching name 'LethalCCTV/NightVision' found inside. Bundle assets: [" + string.Join(", ", _bundle.GetAllAssetNames()) + "]. Night-vision treatment will be unavailable.")); return null; } _shader = val; SurveillanceBootstrap.Log.LogInfo((object)("[LethalCCTV][NightVision] Shader 'LethalCCTV/NightVision' loaded from '" + text + "'.")); return _shader; } catch (Exception ex) { SurveillanceBootstrap.Log.LogError((object)("[LethalCCTV][NightVision] Load threw: " + ex.GetType().Name + " — " + ex.Message + ". Night-vision unavailable.")); return null; } } } internal sealed class OperatorAnimSession { private sealed class InteractionBeginPresentationState { internal PlayerControllerB Player; internal Transform RightShoulder; internal Vector3 RightShoulderScale = Vector3.one; internal bool RightShoulderCaptured; internal bool RightShoulderHidden; internal Transform HeadBone; internal Vector3 HeadScale = Vector3.one; internal bool HeadCaptured; internal bool HeadHidden; } private sealed class ApiPoseTransformSnapshot { internal string Label; internal Transform Transform; internal Vector3 LocalPosition; internal Quaternion LocalRotation = Quaternion.identity; } private sealed class ExitArmsPostExitTelemetry { internal PlayerControllerB Player; internal Transform ArmsRoot; internal Transform LeftHand; internal Transform LeftTarget; internal Transform RightShoulder; internal Transform RightTarget; internal Renderer ArmsRenderer; internal int NextIndex = 1; internal int LastLoggedFrame = -1; } private sealed class ManualArmIkChain { internal string Side; internal Transform Root; internal Transform Mid; internal Transform Tip; internal Transform Target; internal float UpperLength; internal float LowerLength; internal Quaternion TargetToTipRotation = Quaternion.identity; internal int LastSolvedFrame = -1; internal float LastTipTargetDistance = -1f; internal Vector3 LastRootPosition; internal float LastRootTargetDistance = -1f; internal float LastReach = -1f; internal string LastPoleHint = ""; internal bool HasStablePole; internal Transform StablePoleReference; internal Vector3 StablePoleReferenceDirection; } private readonly struct AuthoredLeftHandStationPose { internal readonly Vector3 Position; internal readonly Quaternion Rotation; internal AuthoredLeftHandStationPose(float positionX, float positionY, float positionZ, float rotationX, float rotationY, float rotationZ, float rotationW) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_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) Position = new Vector3(positionX, positionY, positionZ); Rotation = new Quaternion(rotationX, rotationY, rotationZ, rotationW); } } private struct PoseTuningApplication { internal Transform Target; internal Vector3 BaseLocalPosition; internal Quaternion BaseLocalRotation; internal Vector3 AppliedLocalPosition; internal Quaternion AppliedLocalRotation; internal bool Active; } private sealed class TransformPoseSnapshot { private readonly TransformPose[] _poses; internal int Count => _poses.Length; private TransformPoseSnapshot(TransformPose[] poses) { _poses = poses ?? Array.Empty(); } internal static TransformPoseSnapshot CaptureDescendants(Transform root) { if ((Object)(object)root == (Object)null) { return new TransformPoseSnapshot(Array.Empty()); } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); List list = new List(Math.Max(0, componentsInChildren.Length - 1)); foreach (Transform val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)root)) { list.Add(new TransformPose(val)); } } return new TransformPoseSnapshot(list.ToArray()); } internal int Restore() { int num = 0; for (int i = 0; i < _poses.Length; i++) { if (_poses[i].Restore()) { num++; } } return num; } } private readonly struct TransformPose { private readonly Transform _transform; private readonly Vector3 _localPosition; private readonly Quaternion _localRotation; private readonly Vector3 _localScale; internal TransformPose(Transform transform) { //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_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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) _transform = transform; _localPosition = transform.localPosition; _localRotation = transform.localRotation; _localScale = transform.localScale; } internal bool Restore() { //IL_0017: 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_0039: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_transform == (Object)null) { return false; } _transform.localPosition = _localPosition; _transform.localRotation = _localRotation; _transform.localScale = _localScale; return true; } } private struct SavedAnimatorParameter { private readonly string _name; private readonly int _hash; private readonly AnimatorControllerParameterType _type; private readonly float _floatValue; private readonly int _intValue; private readonly bool _boolValue; internal SavedAnimatorParameter(Animator animator, AnimatorControllerParameter parameter) { //IL_001a: 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) //IL_003e: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected I4, but got Unknown _name = parameter.name; _hash = parameter.nameHash; _type = parameter.type; _floatValue = 0f; _intValue = 0; _boolValue = false; AnimatorControllerParameterType type = _type; switch (type - 1) { case 0: _floatValue = animator.GetFloat(_hash); break; case 2: _intValue = animator.GetInteger(_hash); break; case 3: _boolValue = animator.GetBool(_hash); break; case 1: break; } } internal void Restore(Animator animator, Dictionary parameterTypes) { //IL_001d: 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) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected I4, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 if ((Object)(object)animator == (Object)null || parameterTypes == null || !parameterTypes.TryGetValue(_hash, out var value) || value != _type) { return; } AnimatorControllerParameterType type = _type; switch (type - 1) { case 0: animator.SetFloat(_hash, _floatValue); return; case 2: animator.SetInteger(_hash, _intValue); return; case 3: animator.SetBool(_hash, _boolValue); return; case 1: return; } if ((int)type == 9) { animator.ResetTrigger(_hash); } } public override string ToString() { return _name; } } private struct SavedAnimatorState { internal readonly int StateHash; internal readonly float NormalizedTime; internal SavedAnimatorState(int stateHash, float normalizedTime) { StateHash = stateHash; NormalizedTime = normalizedTime; } } private const float JoystickIdleAfterSeconds = 0.16f; private const float ButtonPressLayerSeconds = 1.15f; private const int DeferredVanillaRigRebuildFrames = 3; private const float GracefulExitNeutralizeSeconds = 0.18f; private const float GracefulRestoreSeconds = 0.85f; private const float ApiLeftParentStationPositionX = -0.373f; private const float ApiLeftParentStationPositionY = 0.669f; private const float ApiLeftParentStationPositionZ = 2.192f; private const float ApiLeftParentStationEulerX = 354.9f; private const float ApiLeftParentStationEulerY = 106.55f; private const float ApiLeftParentStationEulerZ = 359.12f; private const float ApiArmsRootStationPinTelemetryIntervalSeconds = 1f; private const float ApiAuthoredTrajectoryFps = 30f; private const float ApiCameraAnchorEnterBlendStartRawT = 0.85f; private const float ApiCameraAnchorExitBlendEndRawT = 0.15f; private static readonly AuthoredLeftHandStationPose[] ApiLeftEnterAuthoredTable = new AuthoredLeftHandStationPose[33] { new AuthoredLeftHandStationPose(0.47f, 1.25f, 0.8f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.49309f, 1.25499f, 0.81357f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.55309f, 1.26784f, 0.84857f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.63609f, 1.28542f, 0.89643f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.59819f, 1.30458f, 0.94857f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.55548f, 1.32216f, 0.99643f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.49405f, 1.33501f, 1.03143f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.4f, 1.34f, 1.045f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.41156f, 1.32891f, 1.045f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.4175f, 1.30375f, 1.045f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.41969f, 1.27672f, 1.045f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.42f, 1.26f, 1.045f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.42f, 1.25422f, 1.045f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.42f, 1.25125f, 1.045f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.42f, 1.25016f, 1.045f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.42f, 1.25f, 1.045f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.44318f, 1.325f, 0.9967f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.48f, 1.4f, 0.9f, -0.1941f, -0.75013f, -0.21893f, 0.59304f), new AuthoredLeftHandStationPose(0.50464f, 1.39982f, 0.81172f, -0.18978f, -0.74789f, -0.21951f, 0.59705f), new AuthoredLeftHandStationPose(0.52441f, 1.39929f, 0.73944f, -0.17788f, -0.74155f, -0.22108f, 0.60793f), new AuthoredLeftHandStationPose(0.5399f, 1.39842f, 0.68156f, -0.1599f, -0.73163f, -0.22331f, 0.62393f), new AuthoredLeftHandStationPose(0.55168f, 1.39721f, 0.63648f, -0.13742f, -0.7186f, -0.22586f, 0.64321f), new AuthoredLeftHandStationPose(0.56036f, 1.39567f, 0.60261f, -0.1121f, -0.70313f, -0.22844f, 0.66398f), new AuthoredLeftHandStationPose(0.56652f, 1.39381f, 0.57834f, -0.08571f, -0.68612f, -0.23079f, 0.68456f), new AuthoredLeftHandStationPose(0.57074f, 1.39164f, 0.56207f, -0.06012f, -0.66878f, -0.23275f, 0.70352f), new AuthoredLeftHandStationPose(0.57361f, 1.38917f, 0.5522f, -0.03718f, -0.65254f, -0.23424f, 0.71968f), new AuthoredLeftHandStationPose(0.57572f, 1.3864f, 0.54713f, -0.01869f, -0.63897f, -0.23527f, 0.73214f), new AuthoredLeftHandStationPose(0.57765f, 1.38334f, 0.54527f, -0.00636f, -0.62968f, -0.23586f, 0.74016f), new AuthoredLeftHandStationPose(0.58f, 1.38f, 0.545f, -0.00188f, -0.62626f, -0.23606f, 0.74302f), new AuthoredLeftHandStationPose(0.58311f, 1.37648f, 0.545f, -0.00188f, -0.62626f, -0.23606f, 0.74302f), new AuthoredLeftHandStationPose(0.58637f, 1.37326f, 0.545f, -0.00188f, -0.62626f, -0.23606f, 0.74302f), new AuthoredLeftHandStationPose(0.58895f, 1.37091f, 0.545f, -0.00188f, -0.62626f, -0.23606f, 0.74302f), new AuthoredLeftHandStationPose(0.59f, 1.37f, 0.545f, -0.00188f, -0.62626f, -0.23606f, 0.74302f) }; private static readonly AuthoredLeftHandStationPose[] ApiLeftExitAuthoredTable = new AuthoredLeftHandStationPose[26] { new AuthoredLeftHandStationPose(0.59f, 1.37f, 0.545f, -0.00188f, -0.62626f, -0.23606f, 0.74302f), new AuthoredLeftHandStationPose(0.58749f, 1.37592f, 0.545f, -0.00188f, -0.62626f, -0.23606f, 0.74302f), new AuthoredLeftHandStationPose(0.57914f, 1.39163f, 0.545f, -0.00188f, -0.62626f, -0.23606f, 0.74302f), new AuthoredLeftHandStationPose(0.56373f, 1.41402f, 0.545f, -0.00188f, -0.62626f, -0.23606f, 0.74302f), new AuthoredLeftHandStationPose(0.54f, 1.44f, 0.545f, -0.00188f, -0.62626f, -0.23606f, 0.74302f), new AuthoredLeftHandStationPose(0.50732f, 1.46672f, 0.54693f, -0.02576f, -0.62108f, -0.22535f, 0.7502f), new AuthoredLeftHandStationPose(0.46736f, 1.4923f, 0.5524f, -0.09074f, -0.60386f, -0.19504f, 0.76752f), new AuthoredLeftHandStationPose(0.42238f, 1.51506f, 0.56092f, -0.18612f, -0.57036f, -0.14744f, 0.78633f), new AuthoredLeftHandStationPose(0.37466f, 1.53337f, 0.57201f, -0.2978f, -0.5176f, -0.08658f, 0.79744f), new AuthoredLeftHandStationPose(0.32644f, 1.54557f, 0.5852f, -0.40891f, -0.44726f, -0.01929f, 0.79523f), new AuthoredLeftHandStationPose(0.28f, 1.55f, 0.6f, -0.50478f, -0.36579f, 0.04662f, 0.78052f), new AuthoredLeftHandStationPose(0.23717f, 1.54279f, 0.61596f, -0.58374f, -0.28338f, 0.1067f, 0.75336f), new AuthoredLeftHandStationPose(0.19811f, 1.52325f, 0.63277f, -0.65153f, -0.2043f, 0.16142f, 0.71254f), new AuthoredLeftHandStationPose(0.16255f, 1.4945f, 0.65016f, -0.7077f, -0.12963f, 0.21023f, 0.66194f), new AuthoredLeftHandStationPose(0.13023f, 1.45968f, 0.66786f, -0.7511f, -0.06268f, 0.25143f, 0.60721f), new AuthoredLeftHandStationPose(0.10087f, 1.4219f, 0.68558f, -0.78124f, -0.00824f, 0.28305f, 0.5563f), new AuthoredLeftHandStationPose(0.07422f, 1.3843f, 0.70305f, -0.79882f, 0.02836f, 0.30333f, 0.51872f), new AuthoredLeftHandStationPose(0.115f, 1.35f, 0.72f, -0.80473f, 0.04175f, 0.31056f, 0.5042f), new AuthoredLeftHandStationPose(0.15803f, 1.3215f, 0.73614f, -0.80473f, 0.04175f, 0.31056f, 0.5042f), new AuthoredLeftHandStationPose(0.2034f, 1.29882f, 0.75117f, -0.80473f, 0.04175f, 0.31056f, 0.5042f), new AuthoredLeftHandStationPose(0.2513f, 1.28132f, 0.76476f, -0.80473f, 0.04175f, 0.31056f, 0.5042f), new AuthoredLeftHandStationPose(0.30191f, 1.26839f, 0.7766f, -0.80473f, 0.04175f, 0.31056f, 0.5042f), new AuthoredLeftHandStationPose(0.35541f, 1.25942f, 0.78636f, -0.80473f, 0.04175f, 0.31056f, 0.5042f), new AuthoredLeftHandStationPose(0.41197f, 1.25377f, 0.79372f, -0.80473f, 0.04175f, 0.31056f, 0.5042f), new AuthoredLeftHandStationPose(0.47177f, 1.25084f, 0.79838f, -0.80473f, 0.04175f, 0.31056f, 0.5042f), new AuthoredLeftHandStationPose(0.47f, 1.25f, 0.8f, -0.80473f, 0.04175f, 0.31056f, 0.5042f) }; private static readonly Vector3 ApiRightHandRestStationPosition = new Vector3(0.47f, 1.25f, 0.4f); private static readonly Quaternion ApiRightHandRestStationRotation = new Quaternion(-0.48309f, 0.40693f, 0.70802f, 0.3158f); private const float HandEnterHoverAtSeconds = 0.4f; private const float HandEnterContactAtSeconds = 0.56f; private const float HandEnterPressHoldEndSeconds = 0.66f; private const float HandEnterReleaseEndSeconds = 0.8f; private const float HandEnterSweepEndSeconds = 1.38f; private const float HandEnterSettleEndSeconds = 1.7f; private static readonly Vector3 HandEnterPressWristStationOffset = new Vector3(-0.07f, 0f, 0.015f); private const float HandEnterPressWristHeightMeters = 0.17f; private const float HandEnterHoverLiftMeters = 0.1f; private const float HandEnterPressDepthMeters = 0.012f; private const float HandEnterReleaseLiftMeters = 0.08f; private const float HandEnterSweepLiftMeters = 0.13f; private const float HandEnterSweepPullMeters = 0.05f; private static readonly Quaternion HandEnterPressStationRotation = new Quaternion(-0.1941f, -0.75013f, -0.21893f, 0.59304f); private static readonly Quaternion HandEnterLeverStationRotation = new Quaternion(-0.00188f, -0.62626f, -0.23606f, 0.74302f); private const float HandExitLiftEndSeconds = 0.24f; private const float HandExitReturnEndSeconds = 0.62f; private const float HandExitLiftMeters = 0.14f; private const float HandExitPullMeters = 0.1f; private static readonly float[] HandTraceMilestonesSeconds = new float[7] { 0f, 0.34f, 0.56f, 0.8f, 0.94f, 1.38f, 1.7f }; private const string FirstPersonLeftHandPath = "ScavengerModelArmsOnly/metarig/spine.003/shoulder.L/arm.L_upper/arm.L_lower/hand.L"; private const string FirstPersonRightHandPath = "ScavengerModelArmsOnly/metarig/spine.003/shoulder.R/arm.R_upper/arm.R_lower/hand.R"; private const string FirstPersonLeftUpperArmPath = "ScavengerModelArmsOnly/metarig/spine.003/shoulder.L/arm.L_upper"; private const string FirstPersonRightUpperArmPath = "ScavengerModelArmsOnly/metarig/spine.003/shoulder.R/arm.R_upper"; private const float PresentationHiddenScale = 0.0001f; private const float PresentationScaleSanityEpsilon = 0.001f; private static readonly string[] LocalThirdPersonHeadSpineChain = new string[6] { "metarig", "spine", "spine.001", "spine.002", "spine.003", "spine.004" }; private static readonly int SeatedHash = Animator.StringToHash("Y4NGZ_CCTV_Seated"); private static readonly int CameraControlHash = Animator.StringToHash("Y4NGZ_CCTV_CameraControl"); private static readonly int RadarLookHash = Animator.StringToHash("Y4NGZ_CCTV_RadarLook"); private static readonly int JoystickXHash = Animator.StringToHash("Y4NGZ_CCTV_JoystickX"); private static readonly int JoystickYHash = Animator.StringToHash("Y4NGZ_CCTV_JoystickY"); private static readonly int ActiveSlotHash = Animator.StringToHash("Y4NGZ_CCTV_ActiveSlot"); private static readonly int ActionButtonHash = Animator.StringToHash("Y4NGZ_CCTV_ActionButton"); private static readonly int EnterHash = Animator.StringToHash("Y4NGZ_CCTV_Enter"); private static readonly int ExitHash = Animator.StringToHash("Y4NGZ_CCTV_Exit"); private static readonly int SelectCameraHash = Animator.StringToHash("Y4NGZ_CCTV_SelectCamera"); private static readonly int JoystickGrabHash = Animator.StringToHash("Y4NGZ_CCTV_JoystickGrab"); private static readonly int JoystickReleaseHash = Animator.StringToHash("Y4NGZ_CCTV_JoystickRelease"); private static readonly int ButtonPressHash = Animator.StringToHash("Y4NGZ_CCTV_ButtonPress"); private static readonly int OperatorIdleStateHash = Animator.StringToHash("CCTVOperatorFullBody.OperatorIdle"); private static readonly int RealArmsIdleStateHash = Animator.StringToHash("CCTVFirstPersonArms.RealArmsIdle"); private static readonly int OperatorIdleShortStateHash = Animator.StringToHash("OperatorIdle"); private static readonly int RealArmsIdleShortStateHash = Animator.StringToHash("RealArmsIdle"); private static readonly int WalkingHash = Animator.StringToHash("Walking"); private static readonly int SprintingHash = Animator.StringToHash("Sprinting"); private static readonly int SidewaysHash = Animator.StringToHash("Sideways"); private static readonly int CrouchingHash = Animator.StringToHash("crouching"); private static readonly int JumpingHash = Animator.StringToHash("Jumping"); private static readonly int FallNoJumpHash = Animator.StringToHash("FallNoJump"); private static readonly int ClimbingLadderHash = Animator.StringToHash("ClimbingLadder"); private static readonly int AnimationSpeedHash = Animator.StringToHash("animationSpeed"); private static readonly int PressBlueCameraSwitchStateHash = Animator.StringToHash("PressBlueCameraSwitch"); private static readonly int PressGreenActionStateHash = Animator.StringToHash("PressGreenAction"); private static Animator _deferredVanillaRigRebuildAnimator; private static PlayerControllerB _deferredVanillaRigRebuildPlayer; private static Component[] _deferredVanillaRigRebuildBuilders = Array.Empty(); private static int _deferredVanillaRigRebuildQueuedFrame = -1; private static int _deferredVanillaRigRebuildEarliestFrame = -1; private static InteractionBeginPresentationState _interactionBeginPresentation; private static Transform _lastKnownHeadPresentationBone; private static Vector3 _lastKnownHeadPresentationLocalScale = Vector3.one; private static bool _lastKnownHeadPresentationScaleValid; private readonly bool _isLocal; private Animator _animator; private RuntimeAnimatorController _savedController; private bool _controllerApplied; private bool _interactionsApiMode; private bool _interactionsApiUsesDedicatedViewmodel; private object _interactionsApiHandle; private float _interactionsApiStartedAt; private float _interactionsApiExitStartedAt; private bool _interactionsApiFeedFlipFired; private SavedAnimatorParameter[] _savedParameters = Array.Empty(); private SavedAnimatorState[] _savedStates = Array.Empty(); private readonly Dictionary _parameterTypes = new Dictionary(); private bool _active; private bool _cameraControlActive; private Vector2 _joystickSmoothed; private readonly CCTVJoystickPhaseDriver _joystickPhase = new CCTVJoystickPhaseDriver(); private const float ApiReachAssistUsableReachFraction = 0.97f; private const float ApiLeverControlReachAssistMaxMeters = 0.24f; private const float ApiLeverControlReachAssistSlewMetersPerSecond = 2f; private float _apiLeverControlReachAssistSmoothed; private Vector3 _apiLeverControlReachAssistLastDirection = Vector3.zero; private bool _apiLeverControlReachAssistLogged; private const int ApiEnterPressContactRowIndex = 15; private const float ApiEnterPressContactFrameStart = 8f; private const float ApiEnterPressContactFrameEnd = 16f; private const float ApiEnterPressContactRampFrames = 3f; private static readonly Vector3 ApiEnterPressLocalIndexTipOffset = new Vector3(-0.045f, 0.178f, -0.076f); private const int ApiEnterPressTelemetryFrame = 15; private const float ApiEnterLeverContactFrameStart = 26f; private const float ApiEnterLeverContactRampFrames = 3f; private const float ApiExitLeverContactHoldFrames = 2f; private const float ApiExitLeverContactFadeFrames = 4f; private const float ApiLeverGripPalmOffsetMeters = 0.025f; private const float ApiLeverPalmKnuckleFraction = 0.58f; private static readonly Vector3 ApiLeverFallbackLocalPalmOffset = new Vector3(0f, 0.08f, 0f); private static readonly string[] ApiLeverPalmKnuckleBoneNames = new string[4] { "finger2.L", "finger3.L", "finger4.L", "finger5.L" }; private bool _apiLeverContactLogged; private bool _apiLeverPalmOffsetResolved; private Vector3 _apiLeverPalmLocalOffset; private string _apiLeverPalmOffsetSource; private bool _apiLeverContactSamplePending; private bool _apiLeverContactPostSolveLogged; private Vector3 _apiLeverContactSampleLiveGrip; private Vector3 _apiLeverContactSampleDesiredPalm; private Vector3 _apiLeverContactSampleWristTarget; private Vector3 _apiLeverContactSampleLocalPalmOffset; private const float ApiEnterHandRampInFrames = 6f; private bool _apiPressContactSnapLogged; private bool _apiPressContactSamplePending; private int _apiPressContactSampleFrame; private Vector3 _apiPressContactSampleCorrection; private Vector3 _apiPressContactSampleLiveButton; private Vector3 _apiPressContactSampleAuthoredContact; private float _lastJoystickMoveAt; private float _restoreAt; private float _exitReleaseAt; private bool _windingDown; private bool _exitTriggered; private CCTVOperatorRuntimePose _runtimePose; private string _savedControllerName; private int _operatorFullBodyLayer = -1; private int _firstPersonArmsLayer = -1; private int _buttonPressLayer = -1; private int _glanceLayer = -1; private float _buttonPressLayerUntil; private int _buttonPressActionId; private int _rightHandEditPreviewActionId = -1; private Transform _firstPersonRightHandTarget; private Transform _firstPersonLeftHandTarget; private PoseTuningApplication _firstPersonRightHandTuningApplication; private PoseTuningApplication _firstPersonLeftHandTuningApplication; private bool _firstPersonRightHandTargetMissingLogged; private bool _firstPersonLeftHandTargetMissingLogged; private Component[] _firstPersonRightHandRigBuilders = Array.Empty(); private bool _firstPersonRightHandRigBuildersResolved; private bool _firstPersonRightHandRigBuilderMissingLogged; private TransformPoseSnapshot _scopedFirstPersonPoseSnapshot; private bool _radarLookActive; private bool _handDriveEnterActive; private float _handDriveEnterStartedAt; private bool _handDriveContactFired; private bool _handDriveEnterLogged; private bool _handDriveLeverGripCaptureAttempted; private bool _handDriveLeverGripCaptured; private Transform _handDriveMovingLever; private Vector3 _handDriveLeverGripLocalPosition; private Quaternion _handDriveLeverGripLocalRotation = Quaternion.identity; private Transform _handDriveLeverNeutralGripFrame; private Vector3 _handDriveLeverNeutralGripFramePosition; private Quaternion _handDriveLeverNeutralGripFrameRotation = Quaternion.identity; private Vector3 _handDriveLeverHandoffPosition; private Quaternion _handDriveLeverHandoffRotation = Quaternion.identity; private bool _handDriveLeverHandoffPoseCaptured; private bool _handDriveLeverFirstFollowLogged; private bool _handDriveExitActive; private Vector3 _handDriveExitFromPosition; private Quaternion _handDriveExitFromRotation; private bool _windDownTargetHoldCaptured; private Vector3 _windDownLeftTargetHoldPosition; private Quaternion _windDownLeftTargetHoldRotation = Quaternion.identity; private Vector3 _windDownRightTargetHoldPosition; private Quaternion _windDownRightTargetHoldRotation = Quaternion.identity; private Vector3 _handDriveStartLeftPosition; private Quaternion _handDriveStartLeftRotation; private Vector3 _handDriveStartRightPosition; private Quaternion _handDriveStartRightRotation; private bool _handRestFirstPinLogged; private float _exitTriggeredAt; private bool _handTraceEnabled; private int _handTraceNextMilestoneIndex; private int _handTraceFrame = -1; private float _handTraceMilestoneSeconds; private int _handTraceDriverEntryCount; private int _handTraceDriveApplicationCount; private int _handTraceRigEvaluateCount; private bool _handTraceBaselineCaptured; private Vector3 _handTraceBaselineTargetPosition; private Vector3 _handTraceBaselineWristPosition; private Vector3 _handTraceBaselineTipPosition; private ManualArmIkChain _manualLeftArmIk; private ManualArmIkChain _manualRightArmIk; private bool _apiManualArmIkChainsUnavailableLogged; private bool _apiManualArmIkFirstSolvedLogged; private float _apiManualArmIkNextCaptureAttemptAt; private Transform _firstPersonArmsRoot; private Vector3 _savedFirstPersonArmsRootLocalPosition; private Quaternion _savedFirstPersonArmsRootLocalRotation = Quaternion.identity; private bool _firstPersonArmsRootPoseCaptured; private Transform _apiArmsRootStationPinRoot; private Transform _apiArmsRootStationPinLeftTarget; private Transform _apiArmsRootStationPinLeftParent; private Transform _apiArmsRootStationPinRightTarget; private bool _apiArmsRootStationPinActive; private float _apiArmsRootStationPinNextTelemetryAt; private string _apiArmsRootStationPinUnavailableReason; private Renderer _firstPersonArmsRenderer; private bool _firstPersonArmsHiddenForMissingAnchor; private bool _firstPersonArmsEnabledBeforeMissingAnchor; private Transform _rightArmPresentationShoulder; private Vector3 _rightArmPresentationCachedLocalScale = Vector3.one; private bool _rightArmPresentationScaleCaptured; private bool _rightArmPresentationHidden; private Transform _headPresentationBone; private Vector3 _headPresentationCachedLocalScale = Vector3.one; private bool _headPresentationScaleCaptured; private bool _headPresentationHidden; private ApiPoseTransformSnapshot[] _apiPoseChainSnapshots = Array.Empty(); private GameObject _leftShoulderCapPlug; private GameObject _rightShoulderCapPlug; private bool _shoulderCapPlugUnavailableLogged; private int _shoulderAnchorAppliedFrame = -1; private float _leverLeftShoulderBlend; private bool _leverLeftShoulderFullOffsetLogged; private bool _exitArmsTelemetryEnabled; private int _exitArmsLastLoggedFrame = -1; private const int PostExitArmsTelemetryFrames = 15; private static ExitArmsPostExitTelemetry _postExitArmsTelemetry; private bool _presentationRemapValid; private Transform _presentationRoot; private Vector3 _presentationFinalPosition; private Quaternion _presentationFinalRotation = Quaternion.identity; private static bool _fpCalibrationLogged; internal PlayerControllerB Player { get; private set; } internal bool IsActive => _active; internal bool IsWindingDown => _windingDown; internal bool IsLocal => _isLocal; internal bool UsesInteractionsApi => _interactionsApiMode; internal bool UsesDedicatedLocalViewmodel { get { if (_interactionsApiMode) { return _interactionsApiUsesDedicatedViewmodel; } return false; } } internal bool CameraControlActive => _cameraControlActive; internal Vector2 JoystickSmoothed => _joystickSmoothed; internal Vector2 JoystickCommand => _joystickPhase.Requested; internal bool Begin(RuntimeAnimatorController controller, bool enterFlourish = false) { //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_053b: Unknown result type (might be due to invalid IL or missing references) //IL_0540: Unknown result type (might be due to invalid IL or missing references) //IL_0546: Unknown result type (might be due to invalid IL or missing references) //IL_054b: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) //IL_055d: Unknown result type (might be due to invalid IL or missing references) //IL_0563: Unknown result type (might be due to invalid IL or missing references) //IL_0568: Unknown result type (might be due to invalid IL or missing references) //IL_056e: Unknown result type (might be due to invalid IL or missing references) //IL_0573: Unknown result type (might be due to invalid IL or missing references) //IL_0579: Unknown result type (might be due to invalid IL or missing references) //IL_057e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player == (Object)null) { return false; } string reason; if (CCTVOperatorInteractionsBridge.ConfigEnabled && enterFlourish) { bool useDedicatedLocalViewmodel = _isLocal && !Y4NGZPlayerAnimationBridge.UseLiveArmsForLocalOperator; Transform shoulder = LiftRightArmPresentationHideForApiBoundary("api-start-window-lift"); bool flag; object handle; try { flag = CCTVOperatorInteractionsBridge.TryStart(Player, useDedicatedLocalViewmodel, out handle, out reason); } finally { ReapplyRightArmPresentationHideForApiBoundary(shoulder, "api-start-window-rehide"); } if (flag) { return BeginInteractionsApiSession(handle, useDedicatedLocalViewmodel); } } else { reason = (CCTVOperatorInteractionsBridge.ConfigEnabled ? "authored_enter_not_requested" : "kill_switch_disabled"); } RestorePendingHeadPresentationForApiFallback(Player); RestorePendingRightArmPresentationForApiFallback(Player); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][ApiPort] fallback_legacy scope=" + (_isLocal ? "local" : "remote") + " player=" + FormatPlayerForLog(Player) + " reason='" + reason + "'.")); } _animator = Player.playerBodyAnimator; if ((Object)(object)_animator == (Object)null) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)"[LethalCCTV] Operator anim session skipped; playerBodyAnimator is missing."); } return false; } if (_isLocal) { _postExitArmsTelemetry = null; } CaptureFirstPersonArmsRootPose(); LogFirstPersonLeftArmChainPose("pre-swap-vanilla"); CaptureScopedFirstPersonPose(); CaptureHandDriveStartPoseBeforeControllerSwap(); LogChainIkConstraintBindings("pre-swap"); CaptureManualArmIkChainsBeforeControllerSwap(); CaptureRightArmPresentationScale(); if ((Object)(object)controller != (Object)null) { ApplyRightArmPresentationHideImmediately(); } _savedController = _animator.runtimeAnimatorController; _savedControllerName = (((Object)(object)_savedController != (Object)null) ? ((Object)_savedController).name : ""); SaveAnimatorState(_animator); if ((Object)(object)controller != (Object)null) { try { _animator.runtimeAnimatorController = controller; _controllerApplied = true; RebuildArmsRigAfterControllerSwap("cctv-controller-applied"); EvaluateAnimatorAfterRigRebuild(_animator, "cctv-controller-applied"); LogChainIkConstraintBindings("post-build"); } catch (Exception ex) { _controllerApplied = false; RestoreRightArmPresentationScale("controller-apply-failed"); ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV] Operator anim controller apply failed for player " + FormatPlayerForLog(Player) + ": " + ex.Message)); } } } CacheParameters(_animator); if (_controllerApplied) { Y4NGZPlayerAnimationBridge.LogAnimatorControllerDiagnosticsOnce(_animator, controller); if (!Y4NGZPlayerAnimationBridge.ValidateAnimatorControllerContract(_animator, controller, _isLocal ? "local-session" : "remote-session")) { try { _animator.runtimeAnimatorController = _savedController; RestoreAnimatorState(_animator); RebuildArmsRigAfterControllerSwap("rejected-controller-restored"); EvaluateAnimatorAfterRigRebuild(_animator, "rejected-controller-restored"); } catch (Exception ex2) { ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogWarning((object)("[LethalCCTV] Operator anim rejected-controller restore failed for player " + FormatPlayerForLog(Player) + ": " + ex2.Message)); } } _controllerApplied = false; RestoreRightArmPresentationScale("controller-rejected"); CacheParameters(_animator); } } if (_isLocal && _controllerApplied) { MonitorFocus.RetainLocalPlayerVisualStateForControllerRestore(Player); } _active = true; _windingDown = false; _exitTriggered = false; _cameraControlActive = false; _radarLookActive = false; _joystickSmoothed = Vector2.zero; _joystickPhase.Reset(); _lastJoystickMoveAt = Time.unscaledTime; _restoreAt = 0f; _exitReleaseAt = 0f; _buttonPressLayerUntil = 0f; _buttonPressActionId = 0; _rightHandEditPreviewActionId = -1; _firstPersonRightHandTarget = null; _firstPersonLeftHandTarget = null; _firstPersonRightHandTuningApplication = default(PoseTuningApplication); _firstPersonLeftHandTuningApplication = default(PoseTuningApplication); _firstPersonRightHandTargetMissingLogged = false; _firstPersonLeftHandTargetMissingLogged = false; _firstPersonRightHandRigBuilders = Array.Empty(); _firstPersonRightHandRigBuildersResolved = false; _firstPersonRightHandRigBuilderMissingLogged = false; _windDownTargetHoldCaptured = false; _windDownLeftTargetHoldPosition = Vector3.zero; _windDownLeftTargetHoldRotation = Quaternion.identity; _windDownRightTargetHoldPosition = Vector3.zero; _windDownRightTargetHoldRotation = Quaternion.identity; _handRestFirstPinLogged = false; _leverLeftShoulderBlend = 0f; _leverLeftShoulderFullOffsetLogged = false; ResetHandTrace(); CacheCctvLayerIndices(); _runtimePose = CCTVOperatorRuntimePose.Attach(Player, _animator); if ((Object)(object)_runtimePose != (Object)null) { _runtimePose.BeginSession(Player, _animator, !_controllerApplied); } SetBool(SeatedHash, value: true); SetBool(CameraControlHash, value: false); SetBool(RadarLookHash, value: false); SetInt(ActiveSlotHash, MonitorFocus.ActiveSlot); SetInt(ActionButtonHash, 0); if (enterFlourish && _controllerApplied) { FireTrigger(EnterHash); if (_isLocal) { _handDriveEnterActive = true; _handDriveEnterStartedAt = Time.unscaledTime; _handDriveContactFired = false; _handDriveEnterLogged = false; _handDriveLeverGripCaptureAttempted = false; _handDriveLeverGripCaptured = false; _handDriveMovingLever = null; _handDriveLeverGripLocalPosition = Vector3.zero; _handDriveLeverGripLocalRotation = Quaternion.identity; _handDriveLeverNeutralGripFrame = null; _handDriveLeverNeutralGripFramePosition = Vector3.zero; _handDriveLeverNeutralGripFrameRotation = Quaternion.identity; _handDriveLeverHandoffPosition = Vector3.zero; _handDriveLeverHandoffRotation = Quaternion.identity; _handDriveLeverHandoffPoseCaptured = false; _handDriveLeverFirstFollowLogged = false; _leverLeftShoulderBlend = 0f; _leverLeftShoulderFullOffsetLogged = false; _handTraceEnabled = true; } } else { StartDirectOperatorIdlePose(); } ApplyOperatorAnimatorOverrides(); if (_handDriveEnterActive) { ApplyEnterHandDrive(); } ManualLogSource log5 = SurveillanceBootstrap.Log; if (log5 != null) { log5.LogInfo((object)("[LethalCCTV] Operator anim session began: scope=" + (_isLocal ? "local" : "remote") + ", " + $"player={FormatPlayerForLog(Player)}, controllerApplied={_controllerApplied}, " + "requestedController='" + (((Object)(object)controller != (Object)null) ? ((Object)controller).name : "") + "', " + $"savedController='{_savedControllerName}', layerCount={_animator.layerCount}, " + $"cctvLayers=full:{_operatorFullBodyLayer} fpArms:{_firstPersonArmsLayer} " + $"button:{_buttonPressLayer} glance:{_glanceLayer}.")); } return true; } private bool BeginInteractionsApiSession(object handle, bool useDedicatedLocalViewmodel) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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) _interactionsApiMode = true; _interactionsApiUsesDedicatedViewmodel = useDedicatedLocalViewmodel; _interactionsApiHandle = handle; _interactionsApiStartedAt = Time.unscaledTime; _interactionsApiExitStartedAt = 0f; _interactionsApiFeedFlipFired = false; _active = true; _windingDown = false; _exitTriggered = false; _cameraControlActive = false; _radarLookActive = false; _joystickSmoothed = Vector2.zero; _joystickPhase.Reset(); _lastJoystickMoveAt = Time.unscaledTime; _animator = ((useDedicatedLocalViewmodel || (Object)(object)Player == (Object)null) ? null : Player.playerBodyAnimator); CacheParameters(_animator); _apiLeverControlReachAssistSmoothed = 0f; _apiLeverControlReachAssistLastDirection = Vector3.zero; _apiLeverControlReachAssistLogged = false; _apiPressContactSnapLogged = false; _apiPressContactSamplePending = false; _apiLeverContactLogged = false; _apiLeverPalmOffsetResolved = false; _apiLeverPalmOffsetSource = null; _apiLeverContactSamplePending = false; _apiLeverContactPostSolveLogged = false; _firstPersonLeftHandTarget = null; _firstPersonRightHandTarget = null; _firstPersonLeftHandTargetMissingLogged = false; _firstPersonRightHandTargetMissingLogged = false; _apiManualArmIkChainsUnavailableLogged = false; _apiManualArmIkFirstSolvedLogged = false; _apiManualArmIkNextCaptureAttemptAt = 0f; if (!useDedicatedLocalViewmodel) { CaptureFirstPersonArmsRootPose(); CaptureManualArmIkChainsBeforeControllerSwap(); CaptureRightArmPresentationScale(); CaptureHeadPresentationScale(); if (Y4NGZPlayerAnimationBridge.UseManualFirstPersonArmIk) { EnsureInteractionsApiManualArmIkChains("session-begin"); } ApplyRightArmPresentationHideImmediately("session-begin"); ApplyHeadPresentationHideImmediately("session-begin"); CaptureInteractionsApiPoseChain(); SyncApiShoulderCapPlugs(); } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ApiPort] session_started scope=" + (_isLocal ? "local" : "remote") + " presentation=" + (useDedicatedLocalViewmodel ? "dedicated-viewmodel" : "world-body") + " player=" + FormatPlayerForLog(Player) + " handle=" + CCTVOperatorInteractionsBridge.FormatHandle(handle) + " " + $"clipLength={1.1f:0.000}s.")); } return true; } private void CaptureFirstPersonArmsRootPose() { //IL_0031: 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_003c: 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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0105: 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_0148: Unknown result type (might be due to invalid IL or missing references) _firstPersonArmsRoot = null; _firstPersonArmsRenderer = (Renderer)(object)(((Object)(object)Player != (Object)null) ? Player.thisPlayerModelArms : null); _firstPersonArmsRootPoseCaptured = false; _savedFirstPersonArmsRootLocalPosition = Vector3.zero; _savedFirstPersonArmsRootLocalRotation = Quaternion.identity; if (!_isLocal || (Object)(object)_animator == (Object)null) { return; } try { Transform val = ((Component)_animator).transform.Find("ScavengerModelArmsOnly"); if ((Object)(object)val == (Object)null) { Transform val2 = (((Object)(object)_firstPersonArmsRenderer != (Object)null) ? ((Component)_firstPersonArmsRenderer).transform : null); while ((Object)(object)val2 != (Object)null) { if (string.Equals(((Object)val2).name, "ScavengerModelArmsOnly", StringComparison.OrdinalIgnoreCase)) { val = val2; break; } val2 = val2.parent; } } if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("ScavengerModelArmsOnly is missing"); } _firstPersonArmsRoot = val; if (!MonitorFocus.TryGetFirstPersonArmsFocusStartRootPose(val, out _savedFirstPersonArmsRootLocalPosition, out _savedFirstPersonArmsRootLocalRotation)) { _savedFirstPersonArmsRootLocalPosition = val.localPosition; _savedFirstPersonArmsRootLocalRotation = val.localRotation; } _firstPersonArmsRootPoseCaptured = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ExitVisualRestore] Captured pre-focus arms-root pose: localPosition=" + FormatTraceVector(_savedFirstPersonArmsRootLocalPosition) + " localEulerAngles=" + FormatTraceVector(((Quaternion)(ref _savedFirstPersonArmsRootLocalRotation)).eulerAngles) + ".")); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][ExitVisualRestore] Arms-root pose capture failed: " + ex.Message)); } } } private void RestoreFirstPersonArmsRootPose() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (!_firstPersonArmsRootPoseCaptured || (Object)(object)_firstPersonArmsRoot == (Object)null) { return; } try { _firstPersonArmsRoot.localPosition = _savedFirstPersonArmsRootLocalPosition; _firstPersonArmsRoot.localRotation = _savedFirstPersonArmsRootLocalRotation; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ExitVisualRestore] Restored pre-focus arms-root pose before vanilla rig rebuild: localPosition=" + FormatTraceVector(_firstPersonArmsRoot.localPosition) + " localEulerAngles=" + FormatTraceVector(_firstPersonArmsRoot.localEulerAngles) + ".")); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][ExitVisualRestore] Arms-root pose restore failed: " + ex.Message)); } } } private void CaptureScopedFirstPersonPose() { _scopedFirstPersonPoseSnapshot = null; if (!_isLocal || (Object)(object)Player == (Object)null || (Object)(object)Player.playerModelArmsMetarig == (Object)null) { return; } try { _scopedFirstPersonPoseSnapshot = TransformPoseSnapshot.CaptureDescendants(Player.playerModelArmsMetarig); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Scoped first-person pose captured before controller swap: " + $"transforms={_scopedFirstPersonPoseSnapshot.Count}.")); } } catch (Exception ex) { _scopedFirstPersonPoseSnapshot = null; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Scoped first-person pose capture failed: " + ex.Message)); } } } private void RestoreScopedFirstPersonPose() { if (_scopedFirstPersonPoseSnapshot == null) { return; } try { int num = _scopedFirstPersonPoseSnapshot.Restore(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Scoped first-person pose restored before vanilla rig rebuild: " + $"restored={num}/{_scopedFirstPersonPoseSnapshot.Count}.")); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Scoped first-person pose restore failed: " + ex.Message)); } } } private static void EvaluateAnimatorAfterRigRebuild(Animator animator, string reason) { if ((Object)(object)animator == (Object)null) { return; } try { animator.Update(0f); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Animator zero-delta evaluation failed after rig rebuild (" + reason + "): " + ex.Message)); } } } private static void ScheduleDeferredVanillaRigRebuild(Animator animator, PlayerControllerB player, Component[] rigBuilders) { if ((Object)(object)_deferredVanillaRigRebuildAnimator != (Object)null) { TickDeferredVanillaRigRebuild(force: true, "superseded-exit-rebuild"); } _deferredVanillaRigRebuildAnimator = animator; _deferredVanillaRigRebuildPlayer = player; _deferredVanillaRigRebuildBuilders = rigBuilders ?? Array.Empty(); _deferredVanillaRigRebuildQueuedFrame = Time.frameCount; _deferredVanillaRigRebuildEarliestFrame = Time.frameCount + 3; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Vanilla rig rebuild deferred until the exit posture settles: " + $"earliestFrame={_deferredVanillaRigRebuildEarliestFrame} " + $"builders={_deferredVanillaRigRebuildBuilders.Length}.")); } } internal static void TickDeferredVanillaRigRebuild(bool force = false, string forcedReason = null) { Animator deferredVanillaRigRebuildAnimator = _deferredVanillaRigRebuildAnimator; if ((Object)(object)deferredVanillaRigRebuildAnimator == (Object)null) { ClearDeferredVanillaRigRebuild(); } else { if (!force && Time.frameCount < _deferredVanillaRigRebuildEarliestFrame) { return; } PlayerControllerB deferredVanillaRigRebuildPlayer = _deferredVanillaRigRebuildPlayer; bool flag = false; bool flag2 = false; try { flag = (Object)(object)deferredVanillaRigRebuildPlayer != (Object)null && (deferredVanillaRigRebuildPlayer.inSpecialInteractAnimation || deferredVanillaRigRebuildPlayer.enteringSpecialAnimation); Camera val = (((Object)(object)deferredVanillaRigRebuildPlayer != (Object)null) ? deferredVanillaRigRebuildPlayer.gameplayCamera : null); CCTVLocalCameraPositionStabilizer cCTVLocalCameraPositionStabilizer = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); flag2 = (Object)(object)cCTVLocalCameraPositionStabilizer != (Object)null && ((Behaviour)cCTVLocalCameraPositionStabilizer).enabled; } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Deferred vanilla rig readiness check failed: " + ex.Message)); } } if (!force && (flag || flag2)) { return; } Component[] deferredVanillaRigRebuildBuilders = _deferredVanillaRigRebuildBuilders; int num = ((_deferredVanillaRigRebuildQueuedFrame >= 0) ? (Time.frameCount - _deferredVanillaRigRebuildQueuedFrame) : 0); string text = ((!force) ? "exit-settled" : (string.IsNullOrWhiteSpace(forcedReason) ? "forced" : forcedReason)); ClearDeferredVanillaRigRebuild(); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] Running deferred vanilla rig rebuild: " + $"reason={text} waitedFrames={num} " + $"inSpecialAnimation={flag} " + $"cameraStabilizerActive={flag2}.")); } float num2 = ReadGameplayCameraLocalYaw(deferredVanillaRigRebuildPlayer); string text2 = DescribeDeferredExitRotationPose(deferredVanillaRigRebuildPlayer); RebuildArmsRigComponents(deferredVanillaRigRebuildBuilders, "vanilla-controller-restored-deferred-" + text); float num3 = ReadGameplayCameraLocalYaw(deferredVanillaRigRebuildPlayer); string text3 = DescribeDeferredExitRotationPose(deferredVanillaRigRebuildPlayer); EvaluateAnimatorAfterRigRebuild(deferredVanillaRigRebuildAnimator, "vanilla-controller-restored-deferred-" + text); float num4 = ReadGameplayCameraLocalYaw(deferredVanillaRigRebuildPlayer); string text4 = DescribeDeferredExitRotationPose(deferredVanillaRigRebuildPlayer); float num5 = Mathf.DeltaAngle(num2, num3); float num6 = Mathf.DeltaAngle(num3, num4); ((Mathf.Abs(num5) > 0.05f || Mathf.Abs(num6) > 0.05f) ? ((Action)delegate(string message) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)message); } }) : ((Action)delegate(string message) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)message); } }))("[LethalCCTV][ExitYawWriter] deferred rebuild attribution: " + $"Build.localYawDelta={num5:F2} " + $"Animator.Update(0f).localYawDelta={num6:F2} | " + "beforeBuild=" + text2 + " | afterBuild=" + text3 + " | afterAnimatorUpdate=" + text4 + "."); MonitorFocus.EnforceExitCameraLocalYawInvariant(deferredVanillaRigRebuildPlayer, "deferred-rig-rebuild-" + text, reassertNextFrame: true); } } private static float ReadGameplayCameraLocalYaw(PlayerControllerB player) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player != (Object)null) || !((Object)(object)player.gameplayCamera != (Object)null)) { return 0f; } return ((Component)player.gameplayCamera).transform.localEulerAngles.y; } private static string DescribeDeferredExitRotationPose(PlayerControllerB player) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return ""; } Transform val = (((Object)(object)player.gameplayCamera != (Object)null) ? ((Component)player.gameplayCamera).transform : null); Transform val2 = (((Object)(object)val != (Object)null) ? val.parent : null); Transform playerModelArmsMetarig = player.playerModelArmsMetarig; return "cameraLocalEuler=" + (((Object)(object)val != (Object)null) ? FormatVector(val.localEulerAngles) : "") + "/cameraWorldEuler=" + (((Object)(object)val != (Object)null) ? FormatVector(val.eulerAngles) : "") + "/cameraParent=" + (((Object)(object)val2 != (Object)null) ? GetTransformPath(val2) : "") + "/parentLocalEuler=" + (((Object)(object)val2 != (Object)null) ? FormatVector(val2.localEulerAngles) : "") + "/bodyWorldEuler=" + FormatVector(((Component)player).transform.eulerAngles) + "/armsLocalEuler=" + (((Object)(object)playerModelArmsMetarig != (Object)null) ? FormatVector(playerModelArmsMetarig.localEulerAngles) : ""); } private static void ClearDeferredVanillaRigRebuild() { _deferredVanillaRigRebuildAnimator = null; _deferredVanillaRigRebuildPlayer = null; _deferredVanillaRigRebuildBuilders = Array.Empty(); _deferredVanillaRigRebuildQueuedFrame = -1; _deferredVanillaRigRebuildEarliestFrame = -1; } private void CaptureHandDriveStartPoseBeforeControllerSwap() { //IL_006c: 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_0078: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: 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_0183: Unknown result type (might be due to invalid IL or missing references) if (!_isLocal || (Object)(object)_animator == (Object)null) { return; } Transform val = FindChildRecursive(((Component)_animator).transform, "ArmsLeftArm_target"); Transform val2 = FindChildRecursive(((Component)_animator).transform, "ArmsRightArm_target"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV][EnterAnim] Could not capture the vanilla lowered FP hand targets before the controller swap; telemetry is unavailable; designed hand rests remain authoritative."); } return; } _handDriveStartLeftPosition = val.position; _handDriveStartLeftRotation = val.rotation; _handDriveStartRightPosition = val2.position; _handDriveStartRightRotation = val2.rotation; Camera val3 = (((Object)(object)Player != (Object)null) ? Player.gameplayCamera : null); Vector3 value = (((Object)(object)val3 != (Object)null) ? val3.WorldToViewportPoint(_handDriveStartLeftPosition) : Vector3.zero); Vector3 value2 = (((Object)(object)val3 != (Object)null) ? val3.WorldToViewportPoint(_handDriveStartRightPosition) : Vector3.zero); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV][EnterAnim] captured vanilla lowered hands (telemetry-only parked targets): left=" + FormatVector(_handDriveStartLeftPosition) + " leftEuler=" + FormatVector(((Quaternion)(ref _handDriveStartLeftRotation)).eulerAngles) + " leftViewport=" + FormatVector(value) + " right=" + FormatVector(_handDriveStartRightPosition) + " rightEuler=" + FormatVector(((Quaternion)(ref _handDriveStartRightRotation)).eulerAngles) + " rightViewport=" + FormatVector(value2) + ".")); } } internal OperatorAnimSession(PlayerControllerB player, bool isLocal) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0070: 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) //IL_007b: 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_0086: 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_0097: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) Player = player; _isLocal = isLocal; } private void ResetHandTrace() { //IL_003d: 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_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) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) _handTraceEnabled = false; _handTraceNextMilestoneIndex = 0; _handTraceFrame = -1; _handTraceMilestoneSeconds = 0f; _handTraceDriverEntryCount = 0; _handTraceDriveApplicationCount = 0; _handTraceRigEvaluateCount = 0; _handTraceBaselineCaptured = false; _handTraceBaselineTargetPosition = Vector3.zero; _handTraceBaselineWristPosition = Vector3.zero; _handTraceBaselineTipPosition = Vector3.zero; } private void TryBeginHandTraceMilestone() { if (_handTraceEnabled && _handDriveEnterActive && _handTraceNextMilestoneIndex < HandTraceMilestonesSeconds.Length) { float num = Mathf.Max(0f, Time.unscaledTime - _handDriveEnterStartedAt); float num2 = HandTraceMilestonesSeconds[_handTraceNextMilestoneIndex]; if (!(num + 0.0001f < num2)) { _handTraceMilestoneSeconds = num2; _handTraceNextMilestoneIndex++; _handTraceFrame = Time.frameCount; _handTraceBaselineCaptured = false; TraceHandSnapshot("A-post-animator/pre-camera"); } } } private void TraceHandSnapshot(string stage) { //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: 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_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_047d: Unknown result type (might be due to invalid IL or missing references) if (_handTraceEnabled && _handTraceFrame == Time.frameCount && !((Object)(object)_animator == (Object)null) && !((Object)(object)Player == (Object)null)) { if ((stage.StartsWith("A-", StringComparison.Ordinal) || stage.StartsWith("C-", StringComparison.Ordinal)) && (Mathf.Abs(_handTraceMilestoneSeconds - 0.56f) < 0.0001f || Mathf.Abs(_handTraceMilestoneSeconds - 1.38f) < 0.0001f)) { LogFirstPersonLeftArmChainPose($"{stage}@{_handTraceMilestoneSeconds:0.00}"); } Camera gameplayCamera = Player.gameplayCamera; Transform val = ResolveFirstPersonLeftHandTarget(); Transform val2 = ((Component)_animator).transform.Find("ScavengerModelArmsOnly/metarig/spine.003/shoulder.L/arm.L_upper/arm.L_lower/hand.L"); Transform val3 = (((Object)(object)val2 != (Object)null) ? val2.Find("finger2.L") : null); Transform val4 = (((Object)(object)val3 != (Object)null) ? val3.Find("finger2.L.001") : null); Transform val5 = (((Object)(object)val4 != (Object)null && val4.childCount > 0) ? val4.GetChild(0) : null); Transform transform = ((Component)_animator).transform.Find("ScavengerModelArmsOnly"); Transform transform2 = (((Object)(object)_manualLeftArmIk?.Root != (Object)null) ? _manualLeftArmIk.Root.parent : null); Transform transform3 = (((Object)(object)_manualRightArmIk?.Root != (Object)null) ? _manualRightArmIk.Root.parent : null); Transform val6 = (((Object)(object)CCTVOperatorStation.RightHandTarget != (Object)null) ? CCTVOperatorStation.RightHandTarget : CCTVOperatorStation.JoystickTiltPivot); Vector3 point; Vector3 normal; bool flag = Y4NGZPlayerAnimationBridge.TryResolveAccessButtonPressSurface(out point, out normal); if (!_handTraceBaselineCaptured && stage.StartsWith("A-", StringComparison.Ordinal)) { _handTraceBaselineCaptured = true; _handTraceBaselineTargetPosition = (((Object)(object)val != (Object)null) ? val.position : Vector3.zero); _handTraceBaselineWristPosition = (((Object)(object)val2 != (Object)null) ? val2.position : Vector3.zero); _handTraceBaselineTipPosition = (((Object)(object)val5 != (Object)null) ? val5.position : Vector3.zero); } string text = (((Object)(object)val != (Object)null && _handTraceBaselineCaptured) ? FormatTraceVector(val.position - _handTraceBaselineTargetPosition) : ""); string text2 = (((Object)(object)val2 != (Object)null && _handTraceBaselineCaptured) ? FormatTraceVector(val2.position - _handTraceBaselineWristPosition) : ""); string text3 = (((Object)(object)val5 != (Object)null && _handTraceBaselineCaptured) ? FormatTraceVector(val5.position - _handTraceBaselineTipPosition) : ""); float num = Mathf.Max(0f, Time.unscaledTime - _handDriveEnterStartedAt); float value = (((Object)(object)val5 != (Object)null && flag) ? Vector3.Distance(val5.position, point) : (-1f)); float value2 = (((Object)(object)val2 != (Object)null && (Object)(object)val != (Object)null) ? Vector3.Distance(val2.position, val.position) : (-1f)); float value3 = (((Object)(object)val2 != (Object)null && (Object)(object)val6 != (Object)null) ? Vector3.Distance(val2.position, val6.position) : (-1f)); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][HandTrace] milestone={_handTraceMilestoneSeconds:0.00}s " + $"frame={Time.frameCount} elapsed={num:0.000}s stage={stage} " + $"calls=hook:{_handTraceDriverEntryCount}/drive:{_handTraceDriveApplicationCount}/rig:{_handTraceRigEvaluateCount} " + FormatTraceAnimatorState() + " camera=" + FormatTracePose(((Object)(object)gameplayCamera != (Object)null) ? ((Component)gameplayCamera).transform : null, gameplayCamera) + " armsRoot=" + FormatTracePose(transform, gameplayCamera) + " shoulder.L=" + FormatTracePose(transform2, gameplayCamera) + " shoulder.R=" + FormatTracePose(transform3, gameplayCamera) + " target=" + FormatTracePose(val, gameplayCamera) + " wrist=" + FormatTracePose(val2, gameplayCamera) + " tip=" + FormatTracePose(val5, gameplayCamera) + " button=" + (flag ? FormatTracePoint(point, gameplayCamera) : "") + " lever=" + FormatTracePose(val6, gameplayCamera) + " distance=tip-button:" + FormatTraceDistance(value) + "/wrist-target:" + FormatTraceDistance(value2) + "/wrist-lever:" + FormatTraceDistance(value3) + " deltaFromA=target:" + text + "/wrist:" + text2 + "/tip:" + text3 + " " + BuildManualIkTrace() + " " + BuildRigDiagTrace() + " " + BuildFingerTrace(val2))); } } } private string BuildManualIkTrace() { return $"[ManualIK] config:{Y4NGZPlayerAnimationBridge.UseManualFirstPersonArmIk}/" + "L:" + DescribeManualIkChainTrace(_manualLeftArmIk) + "/R:" + DescribeManualIkChainTrace(_manualRightArmIk); } private static string DescribeManualIkChainTrace(ManualArmIkChain chain) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) if (chain == null) { return ""; } string arg = ((chain.LastTipTargetDistance >= 0f) ? (chain.LastTipTargetDistance.ToString("0.0000") + "m") : ""); string text = ((chain.LastRootTargetDistance >= 0f) ? (chain.LastRootTargetDistance.ToString("0.000") + "m") : ""); string text2 = ((chain.LastReach >= 0f) ? (chain.LastReach.ToString("0.000") + "m") : ""); return $"tip-target:{arg}@frame:{chain.LastSolvedFrame}" + "/root:" + FormatTraceVector(chain.LastRootPosition) + "/rootTarget:" + text + "/reach:" + text2 + $"/fresh:{chain.LastSolvedFrame == Time.frameCount}" + "/pole:" + chain.LastPoleHint; } private void LogFirstPersonLeftArmChainPose(string phase) { //IL_00a4: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_animator == (Object)null) { throw new InvalidOperationException("animator is missing"); } string[] array = new string[7] { "ScavengerModelArmsOnly", "ScavengerModelArmsOnly/metarig", "ScavengerModelArmsOnly/metarig/spine.003", "ScavengerModelArmsOnly/metarig/spine.003/shoulder.L", "ScavengerModelArmsOnly/metarig/spine.003/shoulder.L/arm.L_upper", "ScavengerModelArmsOnly/metarig/spine.003/shoulder.L/arm.L_upper/arm.L_lower", "ScavengerModelArmsOnly/metarig/spine.003/shoulder.L/arm.L_upper/arm.L_lower/hand.L" }; for (int i = 0; i < array.Length; i++) { Transform val = ((Component)_animator).transform.Find(array[i]); if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("node is missing: " + array[i]); } string text = ((i == array.Length - 1) ? (" lossyScale=" + FormatTraceVector(val.lossyScale)) : string.Empty); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ChainPose] phase=" + phase + " node=" + ((Object)val).name + " worldPos=" + FormatTraceVector(val.position) + " localPosition=" + FormatTraceVector(val.localPosition) + " localEulerAngles=" + FormatTraceVector(val.localEulerAngles) + text)); } } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][ChainPose] phase=" + phase + " failed: " + ex.Message)); } } } private string FormatTraceAnimatorState() { //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_005c: 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) if (_firstPersonArmsLayer < 0 || _firstPersonArmsLayer >= _animator.layerCount) { return "fpLayer="; } try { AnimatorStateInfo currentAnimatorStateInfo = _animator.GetCurrentAnimatorStateInfo(_firstPersonArmsLayer); bool flag = _animator.IsInTransition(_firstPersonArmsLayer); string arg = ""; if (flag) { AnimatorStateInfo nextAnimatorStateInfo = _animator.GetNextAnimatorStateInfo(_firstPersonArmsLayer); arg = $"{((AnimatorStateInfo)(ref nextAnimatorStateInfo)).fullPathHash}@{((AnimatorStateInfo)(ref nextAnimatorStateInfo)).normalizedTime:0.000}"; } AnimatorClipInfo[] currentAnimatorClipInfo = _animator.GetCurrentAnimatorClipInfo(_firstPersonArmsLayer); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < currentAnimatorClipInfo.Length; i++) { if (i > 0) { stringBuilder.Append(','); } stringBuilder.Append(((Object)(object)((AnimatorClipInfo)(ref currentAnimatorClipInfo[i])).clip != (Object)null) ? ((Object)((AnimatorClipInfo)(ref currentAnimatorClipInfo[i])).clip).name : ""); stringBuilder.Append('@').Append(((AnimatorClipInfo)(ref currentAnimatorClipInfo[i])).weight.ToString("0.00")); } return $"fpLayer=index:{_firstPersonArmsLayer}/weight:{_animator.GetLayerWeight(_firstPersonArmsLayer):0.000}/" + $"state:{((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash}/short:{((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash}/time:{((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime:0.000}/" + $"transition:{flag}/next:{arg}/clips:[{stringBuilder}]"; } catch (Exception ex) { return "fpLayer="; } } private string BuildRigDiagTrace() { try { Component[] array = ResolveFirstPersonRightHandRigBuilders(); if (array == null || array.Length == 0 || (Object)(object)array[0] == (Object)null) { return "rig="; } Component val = array[0]; StringBuilder stringBuilder = new StringBuilder("rig=graph:"); stringBuilder.Append(DescribeRigGraph(val)); stringBuilder.Append("/builderEnabled:").Append(DescribeBehaviourEnabled(val)); if (ReadReflectedMemberNoByRef(val, "layers") is IEnumerable enumerable) { stringBuilder.Append("/layers:["); bool flag = true; bool flag2 = default(bool); foreach (object item in enumerable) { if (item != null) { if (!flag) { stringBuilder.Append(';'); } flag = false; object obj = ReadReflectedMemberNoByRef(item, "rig"); object obj2 = ReadReflectedMemberNoByRef(item, "active"); Component val2 = (Component)((obj is Component) ? obj : null); string value = ((val2 != null) ? ((Object)val2).name : ""); string value2 = "?"; if (ReadReflectedMemberNoByRef(obj, "weight") is float num) { value2 = num.ToString("0.00"); } StringBuilder stringBuilder2 = stringBuilder.Append(value).Append("@w:").Append(value2); int num2; if (obj2 is bool) { flag2 = (bool)obj2; num2 = 1; } else { num2 = 0; } stringBuilder2.Append((((uint)num2 & (flag2 ? 1u : 0u)) != 0) ? "/on" : "/off"); } } stringBuilder.Append(']'); } AppendConstraintDiag(stringBuilder, "/L:", "LeftArm"); AppendConstraintDiag(stringBuilder, "/R:", "RightArm"); return stringBuilder.ToString(); } catch (Exception ex) { return "rig="; } } private void AppendConstraintDiag(StringBuilder text, string label, string nodeName) { text.Append(label); Transform val = FindChildRecursive(((Object)(object)_animator != (Object)null) ? ((Component)_animator).transform.Find("ScavengerModelArmsOnly") : null, nodeName); if ((Object)(object)val == (Object)null) { text.Append(""); return; } bool flag = false; Component[] components = ((Component)val).GetComponents(); foreach (Component val2 in components) { if (!((Object)(object)val2 == (Object)null) && !(val2 is Transform) && ReadReflectedMemberNoByRef(val2, "weight") is float num) { if (flag) { text.Append(','); } flag = true; try { text.Append(((object)val2).GetType().Name).Append("@w:").Append(num.ToString("0.00")); } catch { text.Append(((object)val2).GetType().Name).Append("@w:"); } } } if (!flag) { text.Append(""); } } private static string BuildFingerTrace(Transform wrist) { //IL_0090: 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)wrist == (Object)null) { return "fingers=0/10"; } int num = 0; StringBuilder stringBuilder = new StringBuilder("fingerLocalQ=["); for (int i = 1; i <= 5; i++) { Transform val = wrist.Find($"finger{i}.L"); Transform val2 = (((Object)(object)val != (Object)null) ? val.Find($"finger{i}.L.001") : null); if (i > 1) { stringBuilder.Append(';'); } stringBuilder.Append('f').Append(i).Append(':'); if ((Object)(object)val != (Object)null) { num++; stringBuilder.Append(FormatTraceQuaternion(val.localRotation)); } else { stringBuilder.Append(""); } stringBuilder.Append('/'); if ((Object)(object)val2 != (Object)null) { num++; stringBuilder.Append(FormatTraceQuaternion(val2.localRotation)); } else { stringBuilder.Append(""); } } stringBuilder.Append(']'); return $"fingers={num}/10 {stringBuilder}"; } private static string FormatTracePose(Transform transform, Camera camera) { //IL_0020: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform == (Object)null) { return ""; } return "w:" + FormatTraceVector(transform.position) + "/v:" + FormatTraceViewport(transform.position, camera) + "/l:" + FormatTraceVector(transform.localPosition) + "/lq:" + FormatTraceQuaternion(transform.localRotation); } private static string FormatTracePoint(Vector3 point, Camera camera) { //IL_0005: 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) return "w:" + FormatTraceVector(point) + "/v:" + FormatTraceViewport(point, camera); } private static string FormatTraceViewport(Vector3 point, Camera camera) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)camera != (Object)null)) { return ""; } return FormatTraceVector(camera.WorldToViewportPoint(point)); } private static string FormatTraceVector(Vector3 value) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"({value.x:0.000},{value.y:0.000},{value.z:0.000})"; } private static string FormatTraceQuaternion(Quaternion value) { //IL_000d: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) return $"({value.x:0.000},{value.y:0.000},{value.z:0.000},{value.w:0.000})"; } private static string FormatTraceDistance(float value) { if (!(value >= 0f)) { return ""; } return value.ToString("0.000"); } private static void ApplyPoseTuning(Transform target, Y4NGZPlayerAnimationBridge.FirstPersonRightHandPoseTuning tuning, ref PoseTuningApplication previous) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_004c: 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_0058: 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_005c: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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) if ((Object)(object)target == (Object)null) { previous = default(PoseTuningApplication); return; } UndoPoseTuningIfStillApplied(target, ref previous); if (!(((Vector3)(ref tuning.Offset)).sqrMagnitude <= 1E-07f) || !(((Vector3)(ref tuning.Euler)).sqrMagnitude <= 1E-07f)) { Vector3 localPosition = target.localPosition; Quaternion localRotation = target.localRotation; Quaternion val = Quaternion.Euler(tuning.Euler); target.localPosition = localPosition + tuning.Offset; target.localRotation = localRotation * val; previous.Target = target; previous.BaseLocalPosition = localPosition; previous.BaseLocalRotation = localRotation; previous.AppliedLocalPosition = target.localPosition; previous.AppliedLocalRotation = target.localRotation; previous.Active = true; } } private static void UndoPoseTuningIfStillApplied(Transform target, ref PoseTuningApplication previous) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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) //IL_0031: 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) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (!previous.Active) { return; } if ((Object)(object)previous.Target == (Object)(object)target && (Object)(object)target != (Object)null) { Vector3 val = target.localPosition - previous.AppliedLocalPosition; bool num = ((Vector3)(ref val)).sqrMagnitude <= 1E-06f; bool flag = Quaternion.Angle(target.localRotation, previous.AppliedLocalRotation) <= 0.1f; if (num && flag) { target.localPosition = previous.BaseLocalPosition; target.localRotation = previous.BaseLocalRotation; } } previous = default(PoseTuningApplication); } private Transform ResolveFirstPersonRightHandTarget() { if ((Object)(object)_firstPersonRightHandTarget != (Object)null) { return _firstPersonRightHandTarget; } Transform root = (((Object)(object)_animator != (Object)null) ? ((Component)_animator).transform : null); _firstPersonRightHandTarget = FindChildRecursive(root, "ArmsRightArm_target"); if ((Object)(object)_firstPersonRightHandTarget == (Object)null && !_firstPersonRightHandTargetMissingLogged) { _firstPersonRightHandTargetMissingLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] First-person right-hand tuning target not found: ArmsRightArm_target."); } } else if ((Object)(object)_firstPersonRightHandTarget != (Object)null) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] First-person right-hand tuning target resolved: " + GetTransformPath(_firstPersonRightHandTarget))); } } return _firstPersonRightHandTarget; } private Transform ResolveFirstPersonLeftHandTarget() { if ((Object)(object)_firstPersonLeftHandTarget != (Object)null) { return _firstPersonLeftHandTarget; } Transform root = (((Object)(object)_animator != (Object)null) ? ((Component)_animator).transform : null); _firstPersonLeftHandTarget = FindChildRecursive(root, "ArmsLeftArm_target"); if ((Object)(object)_firstPersonLeftHandTarget == (Object)null && !_firstPersonLeftHandTargetMissingLogged) { _firstPersonLeftHandTargetMissingLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] First-person left-hand tuning target not found: ArmsLeftArm_target."); } } else if ((Object)(object)_firstPersonLeftHandTarget != (Object)null) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] First-person left-hand tuning target resolved: " + GetTransformPath(_firstPersonLeftHandTarget))); } } return _firstPersonLeftHandTarget; } private void LogChainIkConstraintBindings(string phase) { if (!_isLocal || (Object)(object)_animator == (Object)null) { return; } try { Transform val = FindChildRecursive(((Component)_animator).transform, "RigArms"); if ((Object)(object)val == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][RigBinding] phase=" + phase + " RigArms transform is missing; ChainIK target binding could not be inspected.")); } } else { LogChainIkConstraintBindingsForArm(phase, val, "LeftArm", ResolveFirstPersonLeftHandTarget()); LogChainIkConstraintBindingsForArm(phase, val, "RightArm", ResolveFirstPersonRightHandTarget()); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][RigBinding] phase=" + phase + " ChainIK inspection failed: " + ex.Message)); } } } private static void LogChainIkConstraintBindingsForArm(string phase, Transform rigArms, string armNodeName, Transform driverTarget) { Transform val = FindChildRecursive(rigArms, armNodeName); if ((Object)(object)val == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][RigBinding] phase=" + phase + " arm=" + armNodeName + " node is missing under " + GetTransformPath(rigArms) + ".")); } return; } bool flag = false; Component[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Component val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || !string.Equals(((object)val2).GetType().Name, "ChainIKConstraint", StringComparison.Ordinal)) { continue; } flag = true; try { string readResult; object boxedData = ReadConstraintDataField(val2, out readResult); string readResult2; Transform val3 = ReadConstraintDataTransform(boxedData, "m_Target", "target", out readResult2); string readResult3; Transform val4 = ReadConstraintDataTransform(boxedData, "m_Root", "root", out readResult3); string readResult4; Transform val5 = ReadConstraintDataTransform(boxedData, "m_Tip", "tip", out readResult4); string text = ((ReadReflectedMemberNoByRef(val2, "weight") is float num) ? num.ToString("0.00") : ""); bool flag2 = (Object)(object)val3 != (Object)null && (Object)(object)driverTarget != (Object)null; bool flag3 = flag2 && val3 == driverTarget; string text2 = "phase=" + phase + " arm=" + armNodeName + " constraint=" + ((object)val2).GetType().Name + "@" + GetTransformPath(val2.transform) + " data=" + readResult + " data.target=" + GetTransformPath(val3) + "(" + readResult2 + ") data.root=" + (((Object)(object)val4 != (Object)null) ? ((Object)val4).name : "") + "(" + readResult3 + ") data.tip=" + (((Object)(object)val5 != (Object)null) ? ((Object)val5).name : "") + "(" + readResult4 + ") weight=" + text + " driverTarget=" + GetTransformPath(driverTarget) + " " + $"targetReferenceEqual={flag3}"; if (flag2 && !flag3) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][RigBinding][IK TARGET MISMATCH] " + text2 + ". THE DRIVER WRITES A DIFFERENT TRANSFORM; THIS CHAIN CANNOT FOLLOW THE DRIVER TARGET.")); } } else if (!flag2) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV][RigBinding][TARGET MISSING] " + text2 + ".")); } } else { ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogInfo((object)("[LethalCCTV][RigBinding] " + text2 + ".")); } } } catch (Exception ex) { ManualLogSource log5 = SurveillanceBootstrap.Log; if (log5 != null) { log5.LogWarning((object)("[LethalCCTV][RigBinding] phase=" + phase + " arm=" + armNodeName + " constraint=" + ((object)val2).GetType().Name + "@" + GetTransformPath(val2.transform) + " inspection failed: " + ex.Message)); } } } if (!flag) { ManualLogSource log6 = SurveillanceBootstrap.Log; if (log6 != null) { log6.LogWarning((object)("[LethalCCTV][RigBinding] phase=" + phase + " arm=" + armNodeName + " has no ChainIKConstraint component in its descendants.")); } } } private static object ReadConstraintDataField(object constraint, out string readResult) { readResult = ""; if (constraint == null) { return null; } try { Type type = constraint.GetType(); FieldInfo field = type.GetField("m_Data", BindingFlags.Instance | BindingFlags.NonPublic); Type type2 = type; while (field == null && type2 != null) { field = type2.GetField("m_Data", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); type2 = type2.BaseType; } if (field == null) { readResult = ""; return null; } object? value = field.GetValue(constraint); readResult = "field:" + field.DeclaringType?.Name + ".m_Data"; return value; } catch (Exception ex) { readResult = ""; return null; } } private static Transform ReadConstraintDataTransform(object boxedData, string serializedFieldName, string propertyName, out string readResult) { readResult = ""; if (boxedData == null) { return null; } Type type = boxedData.GetType(); try { FieldInfo field = type.GetField(serializedFieldName, BindingFlags.Instance | BindingFlags.NonPublic); if (field == null) { field = type.GetField(serializedFieldName, BindingFlags.Instance | BindingFlags.Public); } if (field != null) { object? value = field.GetValue(boxedData); readResult = "field:" + serializedFieldName; return (Transform)((value is Transform) ? value : null); } } catch (Exception ex) { readResult = ""; return null; } try { PropertyInfo property = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public); if (property == null) { readResult = "<" + serializedFieldName + "/" + propertyName + "-missing>"; return null; } MethodInfo getMethod = property.GetGetMethod(nonPublic: true); if (property.PropertyType.IsByRef || getMethod == null || getMethod.ReturnType.IsByRef) { readResult = ""; return null; } object? value2 = property.GetValue(boxedData); readResult = "property:" + propertyName; return (Transform)((value2 is Transform) ? value2 : null); } catch (Exception ex2) { readResult = ""; return null; } } private static object ReadReflectedMemberNoByRef(object owner, string memberName) { if (owner == null || string.IsNullOrEmpty(memberName)) { return null; } try { Type type = owner.GetType(); FieldInfo field = type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(owner); } PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo methodInfo = property?.GetGetMethod(nonPublic: true); if (property == null || property.PropertyType.IsByRef || methodInfo == null || methodInfo.ReturnType.IsByRef) { return null; } return property.GetValue(owner); } catch { return null; } } internal void BeginGracefulEnd(string reason) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) if (!_active || _windingDown) { if (!_windingDown) { EndImmediate(reason); } } else if (_interactionsApiMode) { _active = false; _windingDown = true; _cameraControlActive = false; _radarLookActive = false; _joystickPhase.SetRequested(Vector2.zero); _interactionsApiExitStartedAt = Time.unscaledTime; CCTVOperatorInteractionsBridge.TrySetBool(_interactionsApiHandle, "Y4NGZ_CCTV_Seated", value: false); if (CCTVOperatorInteractionsBridge.TryBeginExit(_interactionsApiHandle, out var reason2)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ApiPort] exit_begun handle=" + CCTVOperatorInteractionsBridge.FormatHandle(_interactionsApiHandle) + " " + $"exitSeconds={0.87f:0.00} " + "reason='" + reason + "'.")); } } else { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][ApiPort] exit_begin_failed handle=" + CCTVOperatorInteractionsBridge.FormatHandle(_interactionsApiHandle) + " reason='" + reason2 + "'; forcing immediate stop.")); } EndImmediate(reason + "-api-exit-failed"); } } else if (!_controllerApplied || (Object)(object)_animator == (Object)null || (Object)(object)Player == (Object)null || Player.isPlayerDead || !Player.isPlayerControlled) { EndImmediate(reason); } else { CaptureWindDownHandTargetHoldPose(); _active = false; _windingDown = true; _exitArmsTelemetryEnabled = _isLocal && _controllerApplied; _exitArmsLastLoggedFrame = -1; float unscaledTime = Time.unscaledTime; _restoreAt = unscaledTime + 0.85f; _exitReleaseAt = unscaledTime + 0.18f; _cameraControlActive = false; _radarLookActive = false; _joystickPhase.SetRequested(Vector2.zero); SetBool(SeatedHash, value: true); SetBool(CameraControlHash, value: false); SetBool(RadarLookHash, value: false); ApplyOperatorAnimatorOverrides(); ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)("[LethalCCTV] Operator anim session winding down (" + reason + "); " + $"neutralize={0.18f:0.00}s restore={0.85f:0.00}s.")); } } } private void TriggerExitPose() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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) if (_exitTriggered) { return; } _exitTriggered = true; _exitTriggeredAt = Time.unscaledTime; FireTrigger(JoystickReleaseHash); FireTrigger(ExitHash); _runtimePose?.BeginEaseOut(); if (_isLocal && _controllerApplied) { if (_windDownTargetHoldCaptured) { _handDriveExitActive = true; _handDriveExitFromPosition = _windDownLeftTargetHoldPosition; _handDriveExitFromRotation = _windDownLeftTargetHoldRotation; } _handDriveEnterActive = false; } } private void CaptureWindDownHandTargetHoldPose() { //IL_0076: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) _windDownTargetHoldCaptured = false; if (!_isLocal || !_controllerApplied) { return; } Transform val = ResolveFirstPersonLeftHandTarget(); Transform val2 = ResolveFirstPersonRightHandTarget(); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][ExitArms] Could not capture both hand targets at wind-down start; " + $"left={(Object)(object)val != (Object)null} right={(Object)(object)val2 != (Object)null}.")); } } else { _windDownLeftTargetHoldPosition = val.position; _windDownLeftTargetHoldRotation = val.rotation; _windDownRightTargetHoldPosition = val2.position; _windDownRightTargetHoldRotation = val2.rotation; _windDownTargetHoldCaptured = true; } } private void HoldWindDownHandTargets() { //IL_003d: 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_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) if (!_windDownTargetHoldCaptured || !_isLocal || !_controllerApplied) { return; } Transform val = ResolveFirstPersonLeftHandTarget(); Transform val2 = ResolveFirstPersonRightHandTarget(); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return; } try { val.SetPositionAndRotation(_windDownLeftTargetHoldPosition, _windDownLeftTargetHoldRotation); val2.SetPositionAndRotation(_windDownRightTargetHoldPosition, _windDownRightTargetHoldRotation); _handTraceDriveApplicationCount++; } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Wind-down hand-target hold failed: " + ex.Message)); } } } private void HoldWindDownLeftHandTargetDuringRightHandPress() { //IL_002d: 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) if (!_windDownTargetHoldCaptured || !_isLocal || !_controllerApplied) { return; } Transform val = ResolveFirstPersonLeftHandTarget(); if ((Object)(object)val == (Object)null) { return; } try { val.SetPositionAndRotation(_windDownLeftTargetHoldPosition, _windDownLeftTargetHoldRotation); _handTraceDriveApplicationCount++; } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Wind-down left hand-target hold failed during right-hand press: " + ex.Message)); } } } internal void EndImmediate(string reason) { //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) if (_interactionsApiMode) { CompleteInteractionsApiSession(reason, requestStop: true, string.Equals(reason, "shutdown", StringComparison.Ordinal) ? "Shutdown" : "Interrupted"); return; } if (!_active && !_windingDown && (Object)(object)_animator == (Object)null) { RestoreRightArmPresentationScale("abort"); return; } Animator animator = _animator; bool controllerApplied = _controllerApplied; bool flag = (Object)(object)animator != (Object)null && controllerApplied; bool flag2 = !flag; bool flag3 = IsFinalSessionEndReason(reason); bool flag4 = flag3 && !string.Equals(reason, "wind-down-complete", StringComparison.Ordinal); string text = (string.Equals(reason, "wind-down-complete", StringComparison.Ordinal) ? "restore" : "abort"); if ((Object)(object)_runtimePose != (Object)null) { _runtimePose.EndSession(reason); _runtimePose = null; } if (_isLocal && flag4) { MonitorFocus.RestoreStationPoseForImmediateControllerRestore(Player, reason); } if ((Object)(object)animator != (Object)null && _controllerApplied) { try { animator.runtimeAnimatorController = _savedController; RestoreAnimatorState(animator); RestoreFirstPersonControllerExitVisualState(flag3, text); if (_isLocal && string.Equals(reason, "wind-down-complete", StringComparison.Ordinal)) { ScheduleDeferredVanillaRigRebuild(animator, Player, ResolveFirstPersonRightHandRigBuilders()); } else { RebuildArmsRigAfterControllerSwap("vanilla-controller-restored"); EvaluateAnimatorAfterRigRebuild(animator, "vanilla-controller-restored"); } flag2 = true; } catch (Exception ex) { flag2 = false; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Operator anim session restore failed: " + ex.Message)); } RestoreFirstPersonControllerExitVisualState(flag3, text); } } if (controllerApplied && !flag && flag3) { RestoreFirstPersonControllerExitVisualState(flag3, text); } RestoreRightArmPresentationScale(text); if (_isLocal && flag4) { MonitorFocus.ReassertCameraStabilizerAfterImmediateControllerRestore(Player, reason); MonitorFocus.EnforceExitCameraLocalYawInvariant(Player, "immediate-controller-restored-" + reason, reassertNextFrame: true); } if (controllerApplied && flag3) { StartPostExitArmsTelemetry(); } string text2 = (((Object)(object)animator != (Object)null && (Object)(object)animator.runtimeAnimatorController != (Object)null) ? ((Object)animator.runtimeAnimatorController).name : ""); Player = null; _animator = null; _savedController = null; _savedControllerName = null; _controllerApplied = false; _savedParameters = Array.Empty(); _savedStates = Array.Empty(); _parameterTypes.Clear(); _active = false; _windingDown = false; _cameraControlActive = false; _radarLookActive = false; _handDriveEnterActive = false; _handDriveEnterStartedAt = 0f; _handDriveContactFired = false; _handDriveEnterLogged = false; _handDriveLeverGripCaptureAttempted = false; _handDriveLeverGripCaptured = false; _handDriveMovingLever = null; _handDriveLeverGripLocalPosition = Vector3.zero; _handDriveLeverGripLocalRotation = Quaternion.identity; _handDriveLeverNeutralGripFrame = null; _handDriveLeverNeutralGripFramePosition = Vector3.zero; _handDriveLeverNeutralGripFrameRotation = Quaternion.identity; _handDriveLeverHandoffPosition = Vector3.zero; _handDriveLeverHandoffRotation = Quaternion.identity; _handDriveLeverHandoffPoseCaptured = false; _handDriveLeverFirstFollowLogged = false; _leverLeftShoulderBlend = 0f; _leverLeftShoulderFullOffsetLogged = false; _handDriveExitActive = false; _windDownTargetHoldCaptured = false; _windDownLeftTargetHoldPosition = Vector3.zero; _windDownLeftTargetHoldRotation = Quaternion.identity; _windDownRightTargetHoldPosition = Vector3.zero; _windDownRightTargetHoldRotation = Quaternion.identity; _handDriveStartLeftPosition = Vector3.zero; _handDriveStartLeftRotation = Quaternion.identity; _handDriveStartRightPosition = Vector3.zero; _handDriveStartRightRotation = Quaternion.identity; _handRestFirstPinLogged = false; _joystickSmoothed = Vector2.zero; _joystickPhase.Reset(); _restoreAt = 0f; _exitReleaseAt = 0f; _buttonPressLayerUntil = 0f; _buttonPressActionId = 0; _rightHandEditPreviewActionId = -1; _firstPersonRightHandTarget = null; _firstPersonLeftHandTarget = null; _firstPersonRightHandTuningApplication = default(PoseTuningApplication); _firstPersonLeftHandTuningApplication = default(PoseTuningApplication); _firstPersonRightHandTargetMissingLogged = false; _firstPersonLeftHandTargetMissingLogged = false; _firstPersonRightHandRigBuilders = Array.Empty(); _firstPersonRightHandRigBuildersResolved = false; _firstPersonRightHandRigBuilderMissingLogged = false; _scopedFirstPersonPoseSnapshot = null; _manualLeftArmIk = null; _manualRightArmIk = null; _firstPersonArmsRoot = null; _savedFirstPersonArmsRootLocalPosition = Vector3.zero; _savedFirstPersonArmsRootLocalRotation = Quaternion.identity; _firstPersonArmsRootPoseCaptured = false; _firstPersonArmsRenderer = null; _firstPersonArmsHiddenForMissingAnchor = false; _firstPersonArmsEnabledBeforeMissingAnchor = false; _rightArmPresentationShoulder = null; _rightArmPresentationCachedLocalScale = Vector3.one; _rightArmPresentationScaleCaptured = false; _rightArmPresentationHidden = false; _shoulderAnchorAppliedFrame = -1; _exitArmsTelemetryEnabled = false; _exitArmsLastLoggedFrame = -1; ResetHandTrace(); _operatorFullBodyLayer = -1; _firstPersonArmsLayer = -1; _buttonPressLayer = -1; _glanceLayer = -1; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] Operator anim session ended: " + reason + "; " + $"restoreAttempted={flag}, restoreSucceeded={flag2}, " + "currentController='" + text2 + "'.")); } } private void CompleteInteractionsApiSession(string reason, bool requestStop, string stopReasonName) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) object interactionsApiHandle = _interactionsApiHandle; PlayerControllerB player = Player; string reason2 = ((!requestStop && _windingDown) ? "session-teardown" : "abort"); RestoreRightArmPresentationScale(reason2); bool flag = !requestStop || CCTVOperatorInteractionsBridge.TryStop(interactionsApiHandle, stopReasonName); RestoreRightArmPresentationScale(reason2); DestroyApiShoulderCapPlugs(); RestoreInteractionsApiPoseChain(reason); ReleaseInteractionsApiArmsRootStationPin(reason); ReleaseInteractionsApiManualArmIkChains(); _rightArmPresentationShoulder = null; _rightArmPresentationCachedLocalScale = Vector3.one; _rightArmPresentationScaleCaptured = false; _rightArmPresentationHidden = false; _apiPoseChainSnapshots = Array.Empty(); Player = null; _interactionsApiMode = false; _interactionsApiUsesDedicatedViewmodel = false; _interactionsApiHandle = null; _interactionsApiStartedAt = 0f; _interactionsApiExitStartedAt = 0f; _interactionsApiFeedFlipFired = false; _active = false; _windingDown = false; _cameraControlActive = false; _radarLookActive = false; _joystickSmoothed = Vector2.zero; _joystickPhase.Reset(); RestoreHeadPresentationScale(reason2); RestorePendingHeadPresentationForPlayer(player, reason2); ClearHeadPresentationState(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ApiPort] restored handle=" + CCTVOperatorInteractionsBridge.FormatHandle(interactionsApiHandle) + " " + $"reason='{reason}' requestStop={requestStop} stopSucceeded={flag}.")); } if (_isLocal) { MonitorFocus.ReleaseLocalPlayerObstructorsAfterInteractionsApiRestore(player, reason); if (IsFinalSessionEndReason(reason) && !string.Equals(reason, "shutdown", StringComparison.Ordinal) && (Object)(object)player != (Object)null && !player.isPlayerDead && player.isPlayerControlled) { MonitorFocus.EnforceExitCameraLocalYawInvariant(player, "interactions-api-restored-" + reason, reassertNextFrame: true); } } } private void ReleaseInteractionsApiManualArmIkChains() { _manualLeftArmIk = null; _manualRightArmIk = null; _firstPersonLeftHandTarget = null; _firstPersonRightHandTarget = null; _animator = null; _apiManualArmIkChainsUnavailableLogged = false; _apiManualArmIkFirstSolvedLogged = false; _apiManualArmIkNextCaptureAttemptAt = 0f; } private static bool IsFinalSessionEndReason(string reason) { if (!string.Equals(reason, "replaced", StringComparison.Ordinal)) { if (!string.IsNullOrEmpty(reason)) { return !reason.EndsWith("-restart", StringComparison.Ordinal); } return true; } return false; } private void RestoreFirstPersonControllerExitVisualState(bool finalSessionEnd, string rightArmRestoreReason) { RestoreScopedFirstPersonPose(); RestoreFirstPersonArmsRootPose(); RestoreRightArmPresentationScale(rightArmRestoreReason); RestoreFirstPersonArmsRendererAfterMissingAnchor(); if (_isLocal && finalSessionEnd) { MonitorFocus.RestoreLocalPlayerVisualStateAtControllerRestore(Player); } } private void CacheCctvLayerIndices() { _operatorFullBodyLayer = FindLayerIndex("CCTVOperatorFullBody"); _firstPersonArmsLayer = FindLayerIndex("CCTVFirstPersonArms"); _buttonPressLayer = FindLayerIndex("CCTVLeftHand"); _glanceLayer = FindLayerIndex("CCTVGlance"); } private void StartDirectOperatorIdlePose() { if ((Object)(object)_animator == (Object)null || !_controllerApplied) { return; } PlayLayerState(_operatorFullBodyLayer, OperatorIdleStateHash, OperatorIdleShortStateHash); PlayLayerState(_firstPersonArmsLayer, RealArmsIdleStateHash, RealArmsIdleShortStateHash); try { _animator.Update(0f); } catch { } } private void PlayLayerState(int layerIndex, int stateHash, int fallbackStateHash) { if ((Object)(object)_animator == (Object)null || layerIndex < 0 || layerIndex >= _animator.layerCount) { return; } try { int num = (_animator.HasState(layerIndex, stateHash) ? stateHash : (_animator.HasState(layerIndex, fallbackStateHash) ? fallbackStateHash : 0)); if (num != 0) { _animator.Play(num, layerIndex, 0f); } } catch { } } private int FindLayerIndex(string layerName) { if ((Object)(object)_animator == (Object)null || string.IsNullOrEmpty(layerName)) { return -1; } try { for (int i = 0; i < _animator.layerCount; i++) { if (string.Equals(_animator.GetLayerName(i), layerName, StringComparison.Ordinal)) { return i; } } } catch { } return -1; } private void ApplyOperatorAnimatorOverrides() { if (!((Object)(object)_animator == (Object)null) && _controllerApplied) { SetBool(WalkingHash, value: false); SetBool(SprintingHash, value: false); SetBool(SidewaysHash, value: false); SetBool(CrouchingHash, value: false); SetBool(JumpingHash, value: false); SetBool(FallNoJumpHash, value: false); SetBool(ClimbingLadderHash, value: false); SetFloat(AnimationSpeedHash, 0f); SetLayerWeight(_operatorFullBodyLayer, 1f); SetLayerWeight(_firstPersonArmsLayer, ShouldShowFirstPersonArmsLayer() ? 1f : 0f); SetLayerWeight(_buttonPressLayer, (Time.unscaledTime <= _buttonPressLayerUntil) ? 1f : 0f); SetLayerWeight(_glanceLayer, _radarLookActive ? 1f : 0f); } } internal void Tick() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (_interactionsApiMode) { TickInteractionsApiSession(); } else if (_windingDown) { TickWindingDown(); } else { if (!_active || (Object)(object)_animator == (Object)null) { return; } if ((Object)(object)Player == (Object)null || Player.isPlayerDead || !Player.isPlayerControlled) { EndImmediate("player-invalid"); return; } if (!_cameraControlActive || Time.unscaledTime - _lastJoystickMoveAt > 0.16f) { _joystickPhase.SetRequested(Vector2.zero); } TickJoystickPose(_cameraControlActive); TryBeginHandTraceMilestone(); } } private void TickInteractionsApiSession() { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) if (!_active && !_windingDown) { return; } if ((Object)(object)Player == (Object)null || Player.isPlayerDead || !Player.isPlayerControlled) { EndImmediate("player-invalid"); return; } if (!_interactionsApiUsesDedicatedViewmodel) { SyncApiShoulderCapPlugs(); } float num = ResolveEnterClipPresentationSeconds(); if (_isLocal && !_interactionsApiFeedFlipFired && num >= 11f / 30f) { _interactionsApiFeedFlipFired = true; bool isStationFeedFlipPending = MonitorFocus.IsStationFeedFlipPending; MonitorFocus.CompleteStationFeedFlipAtPressContact(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ApiPort] feed_flip_fired handle=" + CCTVOperatorInteractionsBridge.FormatHandle(_interactionsApiHandle) + " " + $"clipTime={num:0.000}s pendingBefore={isStationFeedFlipPending}.")); } } if (!CCTVOperatorInteractionsBridge.IsActive(_interactionsApiHandle)) { CompleteInteractionsApiSession(_windingDown ? "graceful-exit-complete" : "api-session-inactive", requestStop: false, null); return; } if (!_cameraControlActive || Time.unscaledTime - _lastJoystickMoveAt > 0.16f) { _joystickPhase.SetRequested(Vector2.zero); } _joystickSmoothed = _joystickPhase.Tick(Mathf.Max(Time.unscaledDeltaTime, 0.004166667f)); if (!_interactionsApiUsesDedicatedViewmodel) { SetFloat(JoystickXHash, _joystickSmoothed.x); SetFloat(JoystickYHash, _joystickSmoothed.y); } } private void RefreshFirstPersonPresentationRemap() { _presentationRemapValid = MonitorFocus.TryGetFirstPersonArmsPresentationThisFrame(out _presentationRoot, out var _, out var _, out _presentationFinalPosition, out _presentationFinalRotation); } private void ReassertFirstPersonArmsPresentation() { //IL_0025: 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) RefreshFirstPersonPresentationRemap(); if (!_presentationRemapValid || (Object)(object)_presentationRoot == (Object)null) { return; } try { _presentationRoot.SetPositionAndRotation(_presentationFinalPosition, _presentationFinalRotation); } catch { } } private void ApplyFirstPersonShoulderAnchor() { //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_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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_0102: 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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011d: 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) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_014d: 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_0162: 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_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018c: 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_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) if (!Y4NGZPlayerAnimationBridge.UseFirstPersonShoulderAnchor || !_presentationRemapValid || (Object)(object)_presentationRoot == (Object)null || (Object)(object)_manualLeftArmIk?.Root == (Object)null || (Object)(object)_manualRightArmIk?.Root == (Object)null || (Object)(object)Player?.gameplayCamera == (Object)null) { return; } bool flag = _handTraceFrame == Time.frameCount; try { Transform transform = ((Component)Player.gameplayCamera).transform; Vector3 val = Vector3.ProjectOnPlane(transform.forward, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.ProjectOnPlane(transform.up, Vector3.up); } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = ((Component)Player).transform.forward; } Quaternion val2 = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); bool shoulderAnchorIgnoresCameraPitch = Y4NGZPlayerAnimationBridge.ShoulderAnchorIgnoresCameraPitch; Quaternion val3 = (shoulderAnchorIgnoresCameraPitch ? val2 : transform.rotation); Quaternion val4 = Quaternion.Inverse(val2) * _presentationFinalRotation; _presentationRoot.rotation = val3 * val4; Vector3 val5 = transform.position + val3 * Y4NGZPlayerAnimationBridge.FirstPersonShoulderAnchorCameraOffset; Vector3 val6 = (_manualLeftArmIk.Root.position + _manualRightArmIk.Root.position) * 0.5f; Vector3 val7 = val5 - val6; Transform presentationRoot = _presentationRoot; presentationRoot.position += val7; _shoulderAnchorAppliedFrame = Time.frameCount; if (flag) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ShoulderAnchor] measured=" + FormatTraceVector(val6) + " desired=" + FormatTraceVector(val5) + " delta=" + FormatTraceVector(val7) + " frame=" + (shoulderAnchorIgnoresCameraPitch ? "yaw-flat" : "full-camera") + ".")); } } } catch (Exception ex) { if (flag) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][ShoulderAnchor] failed: " + ex.Message)); } } } } private void ApplyLeverPhaseLeftShoulderOffset() { //IL_0097: 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_00a6: 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_00bb: 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_00df: 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_00fb: 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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_013c: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) if (!_isLocal || !_controllerApplied || _shoulderAnchorAppliedFrame != Time.frameCount || (Object)(object)_manualLeftArmIk?.Root == (Object)null || (Object)(object)Player?.gameplayCamera == (Object)null) { return; } float num = (_leverLeftShoulderBlend = ResolveLeverPhaseLeftShoulderBlend()); if (num <= 0f) { return; } Transform parent = _manualLeftArmIk.Root.parent; if ((Object)(object)parent == (Object)null) { return; } try { Transform transform = ((Component)Player.gameplayCamera).transform; Vector3 val = Vector3.ProjectOnPlane(transform.forward, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.ProjectOnPlane(transform.up, Vector3.up); } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = ((Component)Player).transform.forward; } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.forward; } Quaternion val2 = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); Quaternion val3 = (Y4NGZPlayerAnimationBridge.ShoulderAnchorIgnoresCameraPitch ? val2 : transform.rotation); Vector3 firstPersonLeverLeftShoulderOffset = Y4NGZPlayerAnimationBridge.FirstPersonLeverLeftShoulderOffset; Vector3 val4 = val3 * firstPersonLeverLeftShoulderOffset * num; parent.position += val4; if (!_leverLeftShoulderFullOffsetLogged && num >= 0.999f) { _leverLeftShoulderFullOffsetLogged = true; Transform target = _manualLeftArmIk.Target; float num2 = (((Object)(object)target != (Object)null) ? Vector3.Distance(_manualLeftArmIk.Root.position, target.position) : (-1f)); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][LeverShoulder] full offset applied: configured=" + FormatTraceVector(firstPersonLeverLeftShoulderOffset) + " worldDelta=" + FormatTraceVector(val4) + " shoulder.viewport=" + FormatTraceViewport(parent.position, Player.gameplayCamera) + " root.viewport=" + FormatTraceViewport(_manualLeftArmIk.Root.position, Player.gameplayCamera) + " " + $"rootTarget={num2:F4}m " + $"reach={_manualLeftArmIk.UpperLength + _manualLeftArmIk.LowerLength:F4}m " + $"blendWindow={0.8f:0.00}-{1.38f:0.00}s " + "frame=" + (Y4NGZPlayerAnimationBridge.ShoulderAnchorIgnoresCameraPitch ? "yaw-flat" : "full-camera") + ".")); } } } catch (Exception ex) { if (!_leverLeftShoulderFullOffsetLogged) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][LeverShoulder] offset failed: " + ex.Message)); } } } } private float ResolveLeverPhaseLeftShoulderBlend() { if (_windingDown) { return _leverLeftShoulderBlend; } if (_cameraControlActive) { return 1f; } if (!_handDriveEnterActive) { return _leverLeftShoulderBlend; } return Smooth01((Mathf.Max(0f, Time.unscaledTime - _handDriveEnterStartedAt) - 0.8f) / 0.58f); } private void EnforceFirstPersonArmsAnchoredOrHidden() { if (!_isLocal || !_controllerApplied) { RestoreFirstPersonArmsRendererAfterMissingAnchor(); return; } Renderer val = (Renderer)(((Object)(object)_firstPersonArmsRenderer != (Object)null) ? ((object)_firstPersonArmsRenderer) : ((object)(((Object)(object)Player != (Object)null) ? Player.thisPlayerModelArms : null))); if ((Object)(object)val == (Object)null) { return; } if (_presentationRemapValid && _shoulderAnchorAppliedFrame == Time.frameCount) { RestoreFirstPersonArmsRendererAfterMissingAnchor(); return; } try { if (!_firstPersonArmsHiddenForMissingAnchor) { _firstPersonArmsEnabledBeforeMissingAnchor = val.enabled; _firstPersonArmsHiddenForMissingAnchor = true; } val.enabled = false; } catch { } } private void RestoreFirstPersonArmsRendererAfterMissingAnchor() { if (!_firstPersonArmsHiddenForMissingAnchor) { return; } Renderer val = (Renderer)(((Object)(object)_firstPersonArmsRenderer != (Object)null) ? ((object)_firstPersonArmsRenderer) : ((object)(((Object)(object)Player != (Object)null) ? Player.thisPlayerModelArms : null))); if ((Object)(object)val != (Object)null) { try { val.enabled = _firstPersonArmsEnabledBeforeMissingAnchor; } catch { } } _firstPersonArmsHiddenForMissingAnchor = false; _firstPersonArmsEnabledBeforeMissingAnchor = false; } private void CaptureManualArmIkChainsBeforeControllerSwap() { _manualLeftArmIk = null; _manualRightArmIk = null; if (_isLocal && !((Object)(object)_animator == (Object)null)) { _manualLeftArmIk = CaptureManualArmIkChain("L", "ScavengerModelArmsOnly/metarig/spine.003/shoulder.L/arm.L_upper/arm.L_lower/hand.L", ResolveFirstPersonLeftHandTarget()); _manualRightArmIk = CaptureManualArmIkChain("R", "ScavengerModelArmsOnly/metarig/spine.003/shoulder.R/arm.R_upper/arm.R_lower/hand.R", ResolveFirstPersonRightHandTarget()); } } private void CaptureRightArmPresentationScale() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) _rightArmPresentationShoulder = null; _rightArmPresentationCachedLocalScale = Vector3.one; _rightArmPresentationScaleCaptured = false; _rightArmPresentationHidden = false; if (!_isLocal || TryAdoptInteractionBeginRightArmPresentation()) { return; } Transform val = (((Object)(object)_manualRightArmIk?.Root != (Object)null) ? _manualRightArmIk.Root.parent : null); bool flag = (Object)(object)val != (Object)null && (Object)(object)_firstPersonArmsRoot != (Object)null && val.IsChildOf(_firstPersonArmsRoot); bool flag2 = (Object)(object)val != (Object)null && string.Equals(((Object)val).name, "shoulder.R", StringComparison.Ordinal); if (!flag || !flag2) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][RightArmHide] shoulder.R scale cache rejected: shoulder=" + GetTransformPath(val) + " armsOnlyRoot=" + GetTransformPath(_firstPersonArmsRoot) + " " + $"verifiedUnderScavengerModelArmsOnly={flag} " + $"verifiedName={flag2}.")); } return; } _rightArmPresentationShoulder = val; _rightArmPresentationCachedLocalScale = val.localScale; _rightArmPresentationScaleCaptured = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV][RightArmHide] cached local arms-only shoulder scale: shoulder=" + GetTransformPath(val) + " verifiedUnderScavengerModelArmsOnly=True cachedLocalScale=" + FormatTraceVector(_rightArmPresentationCachedLocalScale) + ".")); } } private void CaptureHeadPresentationScale() { //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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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) ClearHeadPresentationState(); if (!_isLocal || !_interactionsApiMode || !Y4NGZPlayerAnimationBridge.HideLocalPlayerHeadDuringApiSession) { RestorePendingHeadPresentationForApiFallback(Player); } else { if (TryAdoptInteractionBeginHeadPresentation()) { return; } Transform val = ResolveLocalThirdPersonHeadBone(Player); if ((Object)(object)val == (Object)null) { return; } Vector3 localScale = val.localScale; if (TryResolveHeadPresentationBaseline(val, localScale, "session-begin", out var baselineLocalScale)) { _headPresentationBone = val; _headPresentationCachedLocalScale = baselineLocalScale; _headPresentationScaleCaptured = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][HeadHide] cached local third-person head scale: head=" + GetTransformPath(val) + " cachedLocalScale=" + FormatTraceVector(_headPresentationCachedLocalScale) + ".")); } } } } private void SyncApiShoulderCapPlugs() { try { SyncApiShoulderCapPlugsCore(); } catch (Exception ex) { bool num = !_shoulderCapPlugUnavailableLogged; DestroyApiShoulderCapPlugs(); _shoulderCapPlugUnavailableLogged = true; if (num) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][ShoulderCapPlug] synchronization failed: " + ex.Message)); } } } } private void SyncApiShoulderCapPlugsCore() { if (!_isLocal || !_interactionsApiMode || !Y4NGZPlayerAnimationBridge.UseApiShoulderCapPlugs) { DestroyApiShoulderCapPlugs(); return; } Transform val = ResolveApiShoulderCapBone(_manualLeftArmIk, "ScavengerModelArmsOnly/metarig/spine.003/shoulder.L/arm.L_upper", "arm.L_upper"); Transform val2 = ResolveApiShoulderCapBone(_manualRightArmIk, "ScavengerModelArmsOnly/metarig/spine.003/shoulder.R/arm.R_upper", "arm.R_upper"); SkinnedMeshRenderer val3 = ResolveApiShoulderCapArmsRenderer(); Material val4 = (((Object)(object)val3 != (Object)null) ? ((Renderer)val3).sharedMaterial : null); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null) { if (!_shoulderCapPlugUnavailableLogged) { _shoulderCapPlugUnavailableLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][ShoulderCapPlug] spawn deferred: leftBone=" + GetTransformPath(val) + " rightBone=" + GetTransformPath(val2) + " armsRenderer=" + GetTransformPath(((Object)(object)val3 != (Object)null) ? ((Component)val3).transform : null) + " sharedMaterial=" + (((Object)(object)val4 != (Object)null) ? ((Object)val4).name : "") + ".")); } } } else { _shoulderCapPlugUnavailableLogged = false; float diameter = Mathf.Max(0f, Y4NGZPlayerAnimationBridge.ApiShoulderCapPlugDiameter); float thickness = Mathf.Max(0f, Y4NGZPlayerAnimationBridge.ApiShoulderCapPlugThickness); EnsureApiShoulderCapPlug(ref _leftShoulderCapPlug, "L", val, ResolveApiShoulderCapLowerBone(_manualLeftArmIk, val, "arm.L_lower"), val3, val4, diameter, thickness); EnsureApiShoulderCapPlug(ref _rightShoulderCapPlug, "R", val2, ResolveApiShoulderCapLowerBone(_manualRightArmIk, val2, "arm.R_lower"), val3, val4, diameter, thickness); } } private Transform ResolveApiShoulderCapBone(ManualArmIkChain chain, string path, string expectedName) { Transform val = chain?.Root; if ((Object)(object)val == (Object)null && (Object)(object)_animator != (Object)null) { val = ((Component)_animator).transform.Find(path); } if ((Object)(object)val == (Object)null || !string.Equals(((Object)val).name, expectedName, StringComparison.Ordinal) || (Object)(object)_firstPersonArmsRoot == (Object)null || !val.IsChildOf(_firstPersonArmsRoot)) { return null; } return val; } private static Transform ResolveApiShoulderCapLowerBone(ManualArmIkChain chain, Transform upperBone, string expectedName) { Transform val = chain?.Mid; if ((Object)(object)val != (Object)null && val.parent == upperBone) { return val; } if ((Object)(object)upperBone == (Object)null) { return null; } for (int i = 0; i < upperBone.childCount; i++) { Transform child = upperBone.GetChild(i); if (string.Equals(((Object)child).name, expectedName, StringComparison.Ordinal)) { return child; } } return null; } private SkinnedMeshRenderer ResolveApiShoulderCapArmsRenderer() { SkinnedMeshRenderer val = (((Object)(object)_firstPersonArmsRoot != (Object)null) ? ((Component)_firstPersonArmsRoot).GetComponentInChildren(true) : null); if ((Object)(object)val == (Object)null) { Renderer firstPersonArmsRenderer = _firstPersonArmsRenderer; val = (SkinnedMeshRenderer)(object)((firstPersonArmsRenderer is SkinnedMeshRenderer) ? firstPersonArmsRenderer : null); } return val; } private static void EnsureApiShoulderCapPlug(ref GameObject plug, string side, Transform upperBone, Transform lowerBone, SkinnedMeshRenderer armsRenderer, Material armsMaterial, float diameter, float thickness) { //IL_0149: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)plug != (Object)null && plug.transform.parent != upperBone) { Object.Destroy((Object)(object)plug); plug = null; } bool flag = false; if ((Object)(object)plug == (Object)null) { Vector3 val = (((Object)(object)lowerBone != (Object)null) ? (lowerBone.position - upperBone.position) : upperBone.forward); if (((Vector3)(ref val)).sqrMagnitude < 1E-06f) { val = upperBone.forward; } ((Vector3)(ref val)).Normalize(); Vector3 val2 = upperBone.up; if (((Vector3)(ref val2)).sqrMagnitude < 1E-06f || Mathf.Abs(Vector3.Dot(val, ((Vector3)(ref val2)).normalized)) > 0.98f) { val2 = upperBone.right; } plug = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)plug).name = "LethalCCTV_ApiShoulderCapPlug_" + side; plug.layer = ((Component)armsRenderer).gameObject.layer; plug.transform.SetPositionAndRotation(upperBone.position, Quaternion.LookRotation(val, val2)); plug.transform.SetParent(upperBone, true); plug.transform.localPosition = Vector3.zero; Collider component = plug.GetComponent(); if ((Object)(object)component != (Object)null) { component.enabled = false; Object.Destroy((Object)(object)component); } flag = true; } plug.layer = ((Component)armsRenderer).gameObject.layer; plug.transform.localPosition = Vector3.zero; plug.transform.localScale = new Vector3(diameter, diameter, thickness); Renderer component2 = plug.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.sharedMaterial = armsMaterial; component2.shadowCastingMode = (ShadowCastingMode)0; component2.receiveShadows = false; } if (flag) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ShoulderCapPlug] arm=" + side + " bone=" + GetTransformPath(upperBone) + " worldPosition=" + FormatTraceVector(plug.transform.position) + " " + $"diameter={diameter:F3} thickness={thickness:F3}.")); } } } private void DestroyApiShoulderCapPlugs() { DestroyApiShoulderCapPlug(ref _leftShoulderCapPlug); DestroyApiShoulderCapPlug(ref _rightShoulderCapPlug); _shoulderCapPlugUnavailableLogged = false; } private static void DestroyApiShoulderCapPlug(ref GameObject plug) { if ((Object)(object)plug != (Object)null) { Object.Destroy((Object)(object)plug); } plug = null; } private ManualArmIkChain CaptureManualArmIkChain(string side, string tipPath, Transform target, string capturePhase = "pre-swap", bool logDetails = true) { //IL_0124: 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_0137: 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_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) try { Transform val = ((Component)_animator).transform.Find(tipPath); Transform val2 = (((Object)(object)val != (Object)null) ? val.parent : null); int num = 0; while ((Object)(object)val2 != (Object)null && num++ < 4 && ((Object)val2).name.IndexOf("_lower", StringComparison.OrdinalIgnoreCase) < 0) { val2 = val2.parent; } Transform val3 = (((Object)(object)val2 != (Object)null) ? val2.parent : null); if ((Object)(object)val3 == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val == (Object)null || (Object)(object)target == (Object)null) { if (logDetails) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][ManualIK] arm=" + side + " " + capturePhase + " chain capture failed: root=" + GetTransformPath(val3) + " mid=" + GetTransformPath(val2) + " tip=" + GetTransformPath(val) + " target=" + GetTransformPath(target) + ".")); } } return null; } float num2 = Vector3.Distance(val3.position, val2.position); float num3 = Vector3.Distance(val2.position, val.position); if (num2 <= 0.0001f || num3 <= 0.0001f) { if (logDetails) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][ManualIK] arm=" + side + " " + capturePhase + " chain has invalid lengths: " + $"upper={num2:F4} lower={num3:F4}.")); } } return null; } ManualArmIkChain manualArmIkChain = new ManualArmIkChain { Side = side, Root = val3, Mid = val2, Tip = val, Target = target, UpperLength = num2, LowerLength = num3, TargetToTipRotation = Quaternion.Inverse(target.rotation) * val.rotation }; if (logDetails) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)("[LethalCCTV][ManualIK] arm=" + side + " captured " + capturePhase + ": root=" + ((Object)val3).name + "@" + GetTransformPath(val3) + " mid=" + ((Object)val2).name + "@" + GetTransformPath(val2) + " tip=" + ((Object)val).name + "@" + GetTransformPath(val) + " target=" + GetTransformPath(target) + " " + $"lengths={num2:F4}+{num3:F4} " + "targetToTipEuler=" + FormatVector(((Quaternion)(ref manualArmIkChain.TargetToTipRotation)).eulerAngles) + " pole=station-space config when enabled; fallback=current/last-frame elbow plane then down-and-toward-body " + $"configEnabled={Y4NGZPlayerAnimationBridge.UseManualFirstPersonArmIk}.")); } } return manualArmIkChain; } catch (Exception ex) { if (logDetails) { ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogWarning((object)("[LethalCCTV][ManualIK] arm=" + side + " " + capturePhase + " chain capture failed: " + ex.Message)); } } return null; } } private void ApplyManualFirstPersonArmIk() { if (!_isLocal || (!_controllerApplied && !_interactionsApiMode) || (!_active && !_windingDown) || !Y4NGZPlayerAnimationBridge.UseManualFirstPersonArmIk || !ShouldSolveFirstPersonArms() || (_interactionsApiMode && !EnsureInteractionsApiManualArmIkChains("frame-recapture"))) { return; } SolveManualArmIk(_manualLeftArmIk); SolveManualArmIk(_manualRightArmIk); if (_interactionsApiMode && !_apiManualArmIkFirstSolvedLogged && _manualLeftArmIk != null && _manualRightArmIk != null && _manualLeftArmIk.LastSolvedFrame == Time.frameCount && _manualRightArmIk.LastSolvedFrame == Time.frameCount && _manualLeftArmIk.LastTipTargetDistance >= 0f && _manualRightArmIk.LastTipTargetDistance >= 0f) { _apiManualArmIkFirstSolvedLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV]" + BuildManualIkTrace() + " api_first_solved=true.")); } } } private bool EnsureInteractionsApiManualArmIkChains(string reason) { //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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 (!_isLocal || !Y4NGZPlayerAnimationBridge.UseManualFirstPersonArmIk) { return false; } if (IsManualArmIkChainAvailable(_manualLeftArmIk) && IsManualArmIkChainAvailable(_manualRightArmIk)) { return true; } if (Time.unscaledTime < _apiManualArmIkNextCaptureAttemptAt) { return false; } _apiManualArmIkNextCaptureAttemptAt = Time.unscaledTime + 0.5f; _animator = (((Object)(object)Player != (Object)null) ? Player.playerBodyAnimator : null); _manualLeftArmIk = null; _manualRightArmIk = null; _firstPersonLeftHandTarget = null; _firstPersonRightHandTarget = null; bool logDetails = !_apiManualArmIkChainsUnavailableLogged; if ((Object)(object)_animator != (Object)null) { bool flag = _rightArmPresentationHidden && (Object)(object)_rightArmPresentationShoulder != (Object)null; if (flag) { _rightArmPresentationShoulder.localScale = _rightArmPresentationCachedLocalScale; } try { _manualLeftArmIk = CaptureManualArmIkChain("L", "ScavengerModelArmsOnly/metarig/spine.003/shoulder.L/arm.L_upper/arm.L_lower/hand.L", ResolveFirstPersonLeftHandTarget(), "api-session", logDetails); _manualRightArmIk = CaptureManualArmIkChain("R", "ScavengerModelArmsOnly/metarig/spine.003/shoulder.R/arm.R_upper/arm.R_lower/hand.R", ResolveFirstPersonRightHandTarget(), "api-session", logDetails); } finally { if (flag) { _rightArmPresentationShoulder.localScale = Vector3.one * 0.0001f; } } } if (IsManualArmIkChainAvailable(_manualLeftArmIk) && IsManualArmIkChainAvailable(_manualRightArmIk)) { return true; } if (!_apiManualArmIkChainsUnavailableLogged) { _apiManualArmIkChainsUnavailableLogged = true; string text = (((Object)(object)_animator == (Object)null) ? "animator-missing" : (reason + ":left=" + ((_manualLeftArmIk != null) ? "available" : "missing") + ",right=" + ((_manualRightArmIk != null) ? "available" : "missing"))); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][ManualIK] api_chains_unavailable reason=" + text + ".")); } } return false; } private static bool IsManualArmIkChainAvailable(ManualArmIkChain chain) { if (chain != null && (Object)(object)chain.Root != (Object)null && (Object)(object)chain.Mid != (Object)null && (Object)(object)chain.Tip != (Object)null) { return (Object)(object)chain.Target != (Object)null; } return false; } private void ApplyRightArmPresentationHideAfterManualIk() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_00da: 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) if (!_isLocal || (!_controllerApplied && !_interactionsApiMode) || !_rightArmPresentationScaleCaptured || (Object)(object)_rightArmPresentationShoulder == (Object)null) { return; } bool flag = _active && !MonitorFocus.IsEnterCameraPathComplete; bool flag2 = _windingDown || flag; if (Y4NGZPlayerAnimationBridge.HideRightFirstPersonArmDuringEnterAndExit && flag2) { string arg = (_interactionsApiMode ? "api-session" : (_windingDown ? "wind-down" : "enter-start")); Vector3 localScale = Vector3.one * 0.0001f; _rightArmPresentationShoulder.localScale = localScale; if (!_rightArmPresentationHidden) { _rightArmPresentationHidden = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][RightArmHide] frame={Time.frameCount} reason={arg} " + "cachedLocalScale=" + FormatTraceVector(_rightArmPresentationCachedLocalScale) + " appliedLocalScale=" + FormatTraceVector(_rightArmPresentationShoulder.localScale) + ".")); } } } else if (_rightArmPresentationHidden) { string reason = (Y4NGZPlayerAnimationBridge.HideRightFirstPersonArmDuringEnterAndExit ? "enter-complete" : "restore"); RestoreRightArmPresentationScale(reason); } } private void ApplyRightArmPresentationHideImmediately(string reason = "begin-immediate") { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0097: Unknown result type (might be due to invalid IL or missing references) if (!_isLocal || !Y4NGZPlayerAnimationBridge.HideRightFirstPersonArmDuringEnterAndExit || !_rightArmPresentationScaleCaptured || (Object)(object)_rightArmPresentationShoulder == (Object)null) { return; } try { _rightArmPresentationShoulder.localScale = Vector3.one * 0.0001f; _rightArmPresentationHidden = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][RightArmHide] frame={Time.frameCount} reason={reason} " + "cachedLocalScale=" + FormatTraceVector(_rightArmPresentationCachedLocalScale) + " appliedLocalScale=" + FormatTraceVector(_rightArmPresentationShoulder.localScale) + ".")); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][RightArmHide] immediate Begin hide failed: " + ex.Message)); } } } private void ApplyHeadPresentationHideAfterManualIk() { //IL_004d: 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_00a3: 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) if (!_isLocal || !_interactionsApiMode || !_headPresentationScaleCaptured || (Object)(object)_headPresentationBone == (Object)null) { return; } if (Y4NGZPlayerAnimationBridge.HideLocalPlayerHeadDuringApiSession && (_active || _windingDown)) { try { _headPresentationBone.localScale = Vector3.one * 0.0001f; if (!_headPresentationHidden) { _headPresentationHidden = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][HeadHide] frame={Time.frameCount} reason=api-session " + "cachedLocalScale=" + FormatTraceVector(_headPresentationCachedLocalScale) + " appliedLocalScale=" + FormatTraceVector(_headPresentationBone.localScale) + ".")); } } return; } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][HeadHide] frame reassert failed: " + ex.Message)); } return; } } if (_headPresentationHidden) { RestoreHeadPresentationScale("config-disabled"); } } private void ApplyHeadPresentationHideImmediately(string reason) { //IL_0035: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (!_isLocal || !_interactionsApiMode || !Y4NGZPlayerAnimationBridge.HideLocalPlayerHeadDuringApiSession || !_headPresentationScaleCaptured || (Object)(object)_headPresentationBone == (Object)null) { return; } try { _headPresentationBone.localScale = Vector3.one * 0.0001f; _headPresentationHidden = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][HeadHide] frame={Time.frameCount} reason={reason} " + "cachedLocalScale=" + FormatTraceVector(_headPresentationCachedLocalScale) + " appliedLocalScale=" + FormatTraceVector(_headPresentationBone.localScale) + ".")); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][HeadHide] immediate hide failed reason=" + reason + ": " + ex.Message)); } } } private void RestoreHeadPresentationScale(string reason) { //IL_0025: 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_0081: Unknown result type (might be due to invalid IL or missing references) if (!_headPresentationScaleCaptured || (Object)(object)_headPresentationBone == (Object)null) { return; } bool headPresentationHidden = _headPresentationHidden; try { _headPresentationBone.localScale = _headPresentationCachedLocalScale; if (headPresentationHidden) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][HeadHide] frame={Time.frameCount} reason={reason} " + "cachedLocalScale=" + FormatTraceVector(_headPresentationCachedLocalScale) + " appliedLocalScale=" + FormatTraceVector(_headPresentationBone.localScale) + ".")); } } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][HeadHide] exact scale restore failed reason=" + reason + ": " + ex.Message)); } } finally { _headPresentationHidden = false; } } private void ClearHeadPresentationState() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) _headPresentationBone = null; _headPresentationCachedLocalScale = Vector3.one; _headPresentationScaleCaptured = false; _headPresentationHidden = false; } private void RestoreRightArmPresentationScale(string reason) { //IL_0025: 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_0081: Unknown result type (might be due to invalid IL or missing references) if (!_rightArmPresentationScaleCaptured || (Object)(object)_rightArmPresentationShoulder == (Object)null) { return; } bool rightArmPresentationHidden = _rightArmPresentationHidden; try { _rightArmPresentationShoulder.localScale = _rightArmPresentationCachedLocalScale; if (rightArmPresentationHidden) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][RightArmHide] frame={Time.frameCount} reason={reason} " + "cachedLocalScale=" + FormatTraceVector(_rightArmPresentationCachedLocalScale) + " appliedLocalScale=" + FormatTraceVector(_rightArmPresentationShoulder.localScale) + ".")); } } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][RightArmHide] exact scale restore failed reason=" + reason + ": " + ex.Message)); } } finally { _rightArmPresentationHidden = false; } } private void SolveManualArmIk(ManualArmIkChain chain) { //IL_0043: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_0092: 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_00dc: 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_00e0: 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_0123: 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_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0243: 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_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019c: 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_01a3: 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_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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_048c: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04a9: Unknown result type (might be due to invalid IL or missing references) //IL_04ae: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0501: Unknown result type (might be due to invalid IL or missing references) //IL_0507: Unknown result type (might be due to invalid IL or missing references) //IL_050c: Unknown result type (might be due to invalid IL or missing references) //IL_0528: Unknown result type (might be due to invalid IL or missing references) //IL_0533: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_04d7: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Unknown result type (might be due to invalid IL or missing references) if (chain == null || (Object)(object)chain.Root == (Object)null || (Object)(object)chain.Mid == (Object)null || (Object)(object)chain.Tip == (Object)null || (Object)(object)chain.Target == (Object)null) { return; } try { Vector3 position = chain.Root.position; Vector3 val = chain.Target.position - position; float magnitude = ((Vector3)(ref val)).magnitude; chain.LastRootPosition = position; chain.LastRootTargetDistance = magnitude; chain.LastReach = chain.UpperLength + chain.LowerLength; Vector3 val2 = ((magnitude > 1E-06f) ? (val / magnitude) : chain.Root.forward); float num = Mathf.Abs(chain.UpperLength - chain.LowerLength) + 0.0001f; float num2 = chain.UpperLength + chain.LowerLength - 0.0001f; float num3 = Mathf.Clamp(magnitude, num, num2); Vector3 val3 = position + val2 * num3; Transform val4 = (((Object)(object)Player != (Object)null) ? Player.playerModelArmsMetarig : null); Transform val5 = (((Object)(object)val4 != (Object)null) ? val4 : chain.Root.parent); Vector3 val6 = Vector3.zero; string lastPoleHint = ""; bool useApiElbowPoleHints = Y4NGZPlayerAnimationBridge.UseApiElbowPoleHints; if (useApiElbowPoleHints) { Transform operatorPoseAnchor = CCTVOperatorStation.OperatorPoseAnchor; Transform obj = (((Object)(object)operatorPoseAnchor != (Object)null) ? operatorPoseAnchor.parent : null); if ((Object)(object)obj == (Object)null) { throw new InvalidOperationException("Configured station-space elbow pole cannot resolve the CCTV station root for arm " + chain.Side + "."); } Vector3 val7 = (string.Equals(chain.Side, "R", StringComparison.OrdinalIgnoreCase) ? Y4NGZPlayerAnimationBridge.ApiRightElbowPoleStation : Y4NGZPlayerAnimationBridge.ApiLeftElbowPoleStation); val6 = obj.TransformPoint(val7) - position; val6 -= val2 * Vector3.Dot(val6, val2); if (((Vector3)(ref val6)).sqrMagnitude <= 1E-06f) { throw new InvalidOperationException("Configured station-space elbow pole is collinear with the shoulder-target line for arm " + chain.Side + "."); } lastPoleHint = "station-pole-target(" + chain.Side + ")"; } else { if (chain.HasStablePole) { Vector3 val8 = (((Object)(object)chain.StablePoleReference != (Object)null) ? chain.StablePoleReference.TransformDirection(chain.StablePoleReferenceDirection) : chain.StablePoleReferenceDirection); val6 = val8 - val2 * Vector3.Dot(val8, val2); if (((Vector3)(ref val6)).sqrMagnitude > 1E-06f) { lastPoleHint = "last-frame-bend-plane"; } } if (((Vector3)(ref val6)).sqrMagnitude <= 1E-06f) { val6 = chain.Mid.position - position; val6 -= val2 * Vector3.Dot(val6, val2); if (((Vector3)(ref val6)).sqrMagnitude > 1E-06f) { lastPoleHint = "current-elbow-plane"; } } if (((Vector3)(ref val6)).sqrMagnitude <= 1E-06f) { Vector3 val9 = (((Object)(object)val5 != (Object)null) ? (-val5.forward) : (-chain.Root.forward)) * 0.75f + Vector3.down; val6 = val9 - val2 * Vector3.Dot(val9, val2); lastPoleHint = "body-fallback(down+toward-body)"; } if (((Vector3)(ref val6)).sqrMagnitude <= 1E-06f) { Vector3 val10 = ((Mathf.Abs(Vector3.Dot(val2, Vector3.up)) < 0.95f) ? Vector3.up : Vector3.right); val6 = val10 - val2 * Vector3.Dot(val10, val2); lastPoleHint = "world-axis-fallback"; } } ((Vector3)(ref val6)).Normalize(); if (!useApiElbowPoleHints) { chain.HasStablePole = true; chain.StablePoleReference = val5; chain.StablePoleReferenceDirection = (((Object)(object)val5 != (Object)null) ? val5.InverseTransformDirection(val6) : val6); } float num4 = chain.UpperLength * chain.UpperLength; float num5 = chain.LowerLength * chain.LowerLength; float num6 = Mathf.Clamp((num4 + num3 * num3 - num5) / (2f * chain.UpperLength * num3), -1f, 1f); float num7 = chain.UpperLength * num6; float num8 = Mathf.Sqrt(Mathf.Max(0f, num4 - num7 * num7)); Vector3 val11 = position + val2 * num7 + val6 * num8; Vector3 val12 = chain.Mid.position - position; Vector3 val13 = val11 - position; if (((Vector3)(ref val12)).sqrMagnitude > 1E-06f && ((Vector3)(ref val13)).sqrMagnitude > 1E-06f) { SetWorldRotationThroughLocal(chain.Root, Quaternion.FromToRotation(val12, val13) * chain.Root.rotation); } Vector3 val14 = chain.Tip.position - chain.Mid.position; Vector3 val15 = val3 - chain.Mid.position; if (((Vector3)(ref val14)).sqrMagnitude > 1E-06f && ((Vector3)(ref val15)).sqrMagnitude > 1E-06f) { SetWorldRotationThroughLocal(chain.Mid, Quaternion.FromToRotation(val14, val15) * chain.Mid.rotation); } chain.Tip.rotation = chain.Target.rotation * chain.TargetToTipRotation; chain.LastSolvedFrame = Time.frameCount; chain.LastTipTargetDistance = Vector3.Distance(chain.Tip.position, chain.Target.position); chain.LastPoleHint = lastPoleHint; } catch (Exception ex) { chain.LastSolvedFrame = Time.frameCount; chain.LastTipTargetDistance = -1f; chain.LastPoleHint = "error:" + ex.GetType().Name; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV][ManualIK] arm=" + chain.Side + " solve failed: " + ex.Message)); } } } private static void SetWorldRotationThroughLocal(Transform transform, Quaternion worldRotation) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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) //IL_002d: 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) if (!((Object)(object)transform == (Object)null)) { transform.localRotation = (((Object)(object)transform.parent != (Object)null) ? (Quaternion.Inverse(transform.parent.rotation) * worldRotation) : worldRotation); } } internal void TickFirstPersonHandsAfterCamera() { if (_interactionsApiMode) { if (!_interactionsApiUsesDedicatedViewmodel) { ApplyInteractionsApiArmsRootStationPin(); if (_active && !_windingDown && MonitorFocus.IsEnterCameraPathComplete) { ApplyFirstPersonLeftHandTuning(allowInteractionsApi: true); } ApplyInteractionsApiLeverControlReachAssist(); ApplyManualFirstPersonArmIk(); LogApiPressContactPostSolveSample(); LogApiLeverContactPostSolveSample(); ApplyRightArmPresentationHideAfterManualIk(); ApplyHeadPresentationHideAfterManualIk(); } } else { if (!_isLocal || (Object)(object)_animator == (Object)null) { return; } _handTraceDriverEntryCount++; RefreshFirstPersonPresentationRemap(); TraceHandSnapshot("B-post-camera/pre-driver"); ReassertFirstPersonArmsPresentation(); _shoulderAnchorAppliedFrame = -1; ApplyFirstPersonShoulderAnchor(); ApplyLeverPhaseLeftShoulderOffset(); EnforceFirstPersonArmsAnchoredOrHidden(); bool flag = IsRightHandActionPressWindowActive(); if (_windingDown) { if (_exitTriggered) { ApplyExitHandDrive(!flag); if (flag) { ApplyFirstPersonRightHandTuning(); } } else if (flag) { HoldWindDownLeftHandTargetDuringRightHandPress(); ApplyFirstPersonRightHandTuning(); } else { HoldWindDownHandTargets(); } FinishFirstPersonArmFrame(); TraceHandSnapshot("C-post-driver/final-manual-ik"); LogExitArmsFrame("winding-down"); } else if (_active) { ApplyEnterHandDrive(); ApplyFirstPersonLeftHandTuning(); if (flag) { ApplyFirstPersonRightHandTuning(); } else { PinRightHandToRestPose(ResolveFirstPersonRightHandTarget()); } LogFirstPersonTargetCalibrationOnce(); FinishFirstPersonArmFrame(); TraceHandSnapshot("C-post-driver/final-manual-ik"); } } } private bool IsRightHandActionPressWindowActive() { if (Time.unscaledTime <= _buttonPressLayerUntil) { if (!Y4NGZPlayerAnimationBridge.IsBlueRightHandAction(_buttonPressActionId)) { return Y4NGZPlayerAnimationBridge.IsGreenRightHandAction(_buttonPressActionId); } return true; } return false; } private void ApplyFirstPersonRightHandTuning() { if (!_isLocal || !_controllerApplied || !ShouldShowFirstPersonArmsLayer() || Time.unscaledTime > _buttonPressLayerUntil || (!Y4NGZPlayerAnimationBridge.IsBlueRightHandAction(_buttonPressActionId) && !Y4NGZPlayerAnimationBridge.IsGreenRightHandAction(_buttonPressActionId))) { return; } Y4NGZPlayerAnimationBridge.FirstPersonRightHandPoseTuning firstPersonRightHandPoseTuning = Y4NGZPlayerAnimationBridge.GetFirstPersonRightHandPoseTuning(_buttonPressActionId); Transform val = ResolveFirstPersonRightHandTarget(); if ((Object)(object)val == (Object)null) { return; } try { ApplyPoseTuning(val, firstPersonRightHandPoseTuning, ref _firstPersonRightHandTuningApplication); } catch { } } private void ApplyFirstPersonLeftHandTuning(bool allowInteractionsApi = false) { if (!_isLocal || (!_controllerApplied && !allowInteractionsApi) || (!allowInteractionsApi && !ShouldShowFirstPersonArmsLayer())) { return; } Y4NGZPlayerAnimationBridge.FirstPersonRightHandPoseTuning firstPersonLeftHandPoseTuning = Y4NGZPlayerAnimationBridge.GetFirstPersonLeftHandPoseTuning(); Transform val = ResolveFirstPersonLeftHandTarget(); if ((Object)(object)val == (Object)null) { return; } try { ApplyPoseTuning(val, firstPersonLeftHandPoseTuning, ref _firstPersonLeftHandTuningApplication); } catch { } } private static float Smooth01(float value) { value = Mathf.Clamp01(value); return value * value * (3f - 2f * value); } private static Vector3 EvaluateCubicBezier(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t) { //IL_0017: 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_0029: Unknown result type (might be due to invalid IL or missing references) //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_0041: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_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) t = Mathf.Clamp01(t); float num = 1f - t; return num * num * num * p0 + 3f * num * num * t * p1 + 3f * num * t * t * p2 + t * t * t * p3; } private void ApplyEnterHandDrive() { //IL_006f: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: 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_0126: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: 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_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: 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_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: 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_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0695: Unknown result type (might be due to invalid IL or missing references) //IL_0697: Unknown result type (might be due to invalid IL or missing references) //IL_0662: Unknown result type (might be due to invalid IL or missing references) //IL_0664: Unknown result type (might be due to invalid IL or missing references) //IL_0666: Unknown result type (might be due to invalid IL or missing references) //IL_0668: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04a8: Unknown result type (might be due to invalid IL or missing references) //IL_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_04c7: Unknown result type (might be due to invalid IL or missing references) //IL_04ce: Unknown result type (might be due to invalid IL or missing references) //IL_04d3: Unknown result type (might be due to invalid IL or missing references) //IL_04d8: Unknown result type (might be due to invalid IL or missing references) //IL_04da: Unknown result type (might be due to invalid IL or missing references) //IL_04dc: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_04e7: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_04f0: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_04f6: Unknown result type (might be due to invalid IL or missing references) //IL_04fb: Unknown result type (might be due to invalid IL or missing references) //IL_04fd: Unknown result type (might be due to invalid IL or missing references) //IL_04ff: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Unknown result type (might be due to invalid IL or missing references) //IL_0655: Unknown result type (might be due to invalid IL or missing references) //IL_065a: Unknown result type (might be due to invalid IL or missing references) //IL_065c: Unknown result type (might be due to invalid IL or missing references) //IL_065e: Unknown result type (might be due to invalid IL or missing references) //IL_056f: Unknown result type (might be due to invalid IL or missing references) //IL_0574: Unknown result type (might be due to invalid IL or missing references) //IL_0576: Unknown result type (might be due to invalid IL or missing references) //IL_0578: Unknown result type (might be due to invalid IL or missing references) //IL_059c: Unknown result type (might be due to invalid IL or missing references) //IL_05a1: Unknown result type (might be due to invalid IL or missing references) //IL_05ba: Unknown result type (might be due to invalid IL or missing references) //IL_05bf: Unknown result type (might be due to invalid IL or missing references) if (!_handDriveEnterActive) { return; } if (!_isLocal || !_controllerApplied) { _handDriveEnterActive = false; } else { if (!ShouldShowFirstPersonArmsLayer()) { return; } Transform val = ResolveFirstPersonLeftHandTarget(); if ((Object)(object)val == (Object)null) { return; } float num = Mathf.Max(0f, Time.unscaledTime - _handDriveEnterStartedAt); if (!TryResolveCurrentHandRestPoses(out var leftPosition, out var leftRotation, out var _, out var _)) { return; } if (Y4NGZPlayerAnimationBridge.TryResolveAccessButtonPressSurface(out var point, out var normal)) { Camera val2 = (((Object)(object)Player != (Object)null) ? Player.gameplayCamera : null); if (((Vector3)(ref normal)).sqrMagnitude < 0.0001f) { normal = Vector3.up; } else { ((Vector3)(ref normal)).Normalize(); } Transform val3 = (((Object)(object)CCTVAccessButton.Root != (Object)null) ? CCTVAccessButton.Root.parent : (((Object)(object)CCTVOperatorStation.OperatorPoseAnchor != (Object)null) ? CCTVOperatorStation.OperatorPoseAnchor.parent : null)); Quaternion val4 = (((Object)(object)val3 != (Object)null) ? val3.rotation : Quaternion.identity); Vector3 val5 = point + normal * 0.17f + val4 * HandEnterPressWristStationOffset; Vector3 val6 = val5 + normal * 0.1f; Vector3 val7 = val5 + normal * 0.08f; Vector3 val8 = -normal; Vector3 val9 = Vector3.zero; Transform operatorPoseAnchor = CCTVOperatorStation.OperatorPoseAnchor; if ((Object)(object)operatorPoseAnchor != (Object)null) { val9 = operatorPoseAnchor.position - point; val9 -= normal * Vector3.Dot(val9, normal); if (((Vector3)(ref val9)).sqrMagnitude > 0.0001f) { ((Vector3)(ref val9)).Normalize(); } } if (((Vector3)(ref val9)).sqrMagnitude < 0.0001f && (Object)(object)val2 != (Object)null) { val9 = ((Component)val2).transform.position - point; val9 -= normal * Vector3.Dot(val9, normal); if (((Vector3)(ref val9)).sqrMagnitude > 0.0001f) { ((Vector3)(ref val9)).Normalize(); } } Transform val10 = (((Object)(object)CCTVOperatorStation.RightHandTarget != (Object)null) ? CCTVOperatorStation.RightHandTarget : CCTVOperatorStation.JoystickTiltPivot); Quaternion val11 = val4 * HandEnterPressStationRotation; Quaternion val12 = val4 * HandEnterLeverStationRotation; if (!_handDriveEnterLogged) { _handDriveEnterLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][EnterAnim] hand driver active: capSurface=" + FormatVector(point) + " normal=" + FormatVector(normal) + " wristContact=" + FormatVector(val5) + " lever=" + (((Object)(object)val10 != (Object)null) ? FormatVector(val10.position) : "") + " " + $"designedRest=true contactAt={0.56f:0.00}s " + $"settleEnd={1.7f:0.00}s.")); } } Vector3 position; Quaternion rotation; if (num < 0.4f) { float num2 = Smooth01(num / 0.4f); Vector3 val13 = val6 - leftPosition; val13 -= normal * Vector3.Dot(val13, normal); if (((Vector3)(ref val13)).sqrMagnitude > 0.0001f) { ((Vector3)(ref val13)).Normalize(); } Vector3 p = leftPosition + normal * 0.1f + val13 * 0.1f; Vector3 p2 = val6 + val9 * 0.12f + normal * 0.02f; position = EvaluateCubicBezier(leftPosition, p, p2, val6, num2); rotation = Quaternion.Slerp(leftRotation, val11, num2); } else if (num < 0.56f) { float num3 = Smooth01((num - 0.4f) / 0.16f); position = Vector3.Lerp(val6, val5, num3); rotation = val11; } else if (num < 0.66f) { float num4 = Mathf.Clamp01((num - 0.56f) / 0.100000024f); position = val5 + val8 * (0.012f * Mathf.Sin(MathF.PI * num4)); rotation = val11; } else if (num < 0.8f) { float num5 = Smooth01((num - 0.66f) / 0.13999999f); position = Vector3.Lerp(val5, val7, num5); rotation = val11; } else if ((Object)(object)val10 != (Object)null && num < 1.38f) { float num6 = Smooth01((num - 0.8f) / 0.58f); Vector3 position2 = val10.position; Vector3 val14 = Vector3.Lerp(val7, position2, 0.5f) + normal * 0.13f + val9 * 0.05f; Vector3 val15 = Vector3.Lerp(val7, val14, num6); Vector3 val16 = Vector3.Lerp(val14, position2, num6); position = Vector3.Lerp(val15, val16, num6); rotation = Quaternion.Slerp(val11, val12, num6); } else if ((Object)(object)val10 != (Object)null) { if (_handDriveLeverGripCaptured && (Object)(object)_handDriveMovingLever != (Object)null) { float num7 = Smooth01((num - 1.38f) / 0.32000005f); float num8 = Mathf.Lerp(1f, Y4NGZPlayerAnimationBridge.FirstPersonLeverFollowMotionScale, num7); if (!TryResolveMovingLeverFollowPose(num8, out position, out rotation)) { position = val10.position; rotation = val12; } if (!_handDriveLeverFirstFollowLogged) { _handDriveLeverFirstFollowLogged = true; float num9 = (_handDriveLeverHandoffPoseCaptured ? Vector3.Distance(_handDriveLeverHandoffPosition, position) : (-1f)); float num10 = (_handDriveLeverHandoffPoseCaptured ? Quaternion.Angle(_handDriveLeverHandoffRotation, rotation) : (-1f)); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV][LeverHandoff] first followed frame: " + $"elapsed={num:F4}s appliedScale={num8:F4} " + $"handoffDelta={num9:F5}m/{num10:F3}deg " + $"targetScale={Y4NGZPlayerAnimationBridge.FirstPersonLeverFollowMotionScale:F2} " + $"easeEnd={1.7f:0.00}s.")); } } } else { position = val10.position; rotation = val12; } } else { position = val7; rotation = val11; } if (!_handDriveContactFired && num >= 0.56f) { _handDriveContactFired = true; MonitorFocus.CompleteStationFeedFlipAtPressContact(); } _handTraceDriveApplicationCount++; try { val.SetPositionAndRotation(position, rotation); if (num >= 1.38f && !_handDriveLeverGripCaptureAttempted) { CaptureMovingLeverGrip(val); } return; } catch (Exception ex) { _handDriveEnterActive = false; ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogDebug((object)("[LethalCCTV] Enter hand drive failed: " + ex.Message)); } return; } } val.SetPositionAndRotation(leftPosition, leftRotation); } } private void CaptureMovingLeverGrip(Transform handTarget) { //IL_003e: 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_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_0054: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) _handDriveLeverGripCaptureAttempted = true; Transform joystickTiltPivot = CCTVOperatorStation.JoystickTiltPivot; if ((Object)(object)joystickTiltPivot == (Object)null || (Object)(object)handTarget == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV][EnterAnim] moving-lever grip follow unavailable; using the static lever grip hold."); } return; } _handDriveMovingLever = joystickTiltPivot; _handDriveLeverGripLocalPosition = joystickTiltPivot.InverseTransformPoint(handTarget.position); _handDriveLeverGripLocalRotation = Quaternion.Inverse(joystickTiltPivot.rotation) * handTarget.rotation; _handDriveLeverNeutralGripFrame = joystickTiltPivot.parent; if ((Object)(object)_handDriveLeverNeutralGripFrame != (Object)null) { _handDriveLeverNeutralGripFramePosition = _handDriveLeverNeutralGripFrame.InverseTransformPoint(handTarget.position); _handDriveLeverNeutralGripFrameRotation = Quaternion.Inverse(_handDriveLeverNeutralGripFrame.rotation) * handTarget.rotation; } else { _handDriveLeverNeutralGripFramePosition = handTarget.position; _handDriveLeverNeutralGripFrameRotation = handTarget.rotation; } _handDriveLeverGripCaptured = true; _handDriveLeverHandoffPosition = handTarget.position; _handDriveLeverHandoffRotation = handTarget.rotation; _handDriveLeverHandoffPoseCaptured = true; if (TryResolveMovingLeverFollowPose(1f, out var position, out var rotation)) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV][LeverHandoff] boundary pose: " + $"sweepToFollow={Vector3.Distance(handTarget.position, position):F6}m/" + $"{Quaternion.Angle(handTarget.rotation, rotation):F4}deg " + $"firstScale=1.00 targetScale={Y4NGZPlayerAnimationBridge.FirstPersonLeverFollowMotionScale:F2} " + $"ease={1.38f:0.00}-{1.7f:0.00}s.")); } } ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)("[LethalCCTV][EnterAnim] moving-lever grip follow captured: lever='" + ((Object)joystickTiltPivot).name + "' localPos=" + FormatVector(_handDriveLeverGripLocalPosition) + " localEuler=" + FormatVector(((Quaternion)(ref _handDriveLeverGripLocalRotation)).eulerAngles) + " " + $"motionScale={Y4NGZPlayerAnimationBridge.FirstPersonLeverFollowMotionScale:F2}.")); } } private bool TryResolveMovingLeverFollowPose(float followScale, out Vector3 position, out Quaternion rotation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0092: 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) position = Vector3.zero; rotation = Quaternion.identity; if (!_handDriveLeverGripCaptured || (Object)(object)_handDriveMovingLever == (Object)null) { return false; } Vector3 val = _handDriveMovingLever.TransformPoint(_handDriveLeverGripLocalPosition); Quaternion val2 = _handDriveMovingLever.rotation * _handDriveLeverGripLocalRotation; ResolveNeutralLeverGripPose(out var position2, out var rotation2); position = position2 + (val - position2) * followScale; Quaternion val3 = val2 * Quaternion.Inverse(rotation2); rotation = Quaternion.SlerpUnclamped(Quaternion.identity, val3, followScale) * rotation2; return true; } private void ResolveNeutralLeverGripPose(out Vector3 position, out Quaternion rotation) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_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_0020: 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) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_handDriveLeverNeutralGripFrame != (Object)null) { position = _handDriveLeverNeutralGripFrame.TransformPoint(_handDriveLeverNeutralGripFramePosition); rotation = _handDriveLeverNeutralGripFrame.rotation * _handDriveLeverNeutralGripFrameRotation; } else { position = _handDriveLeverNeutralGripFramePosition; rotation = _handDriveLeverNeutralGripFrameRotation; } } private void ApplyExitHandDrive(bool pinRightHandToRest) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00ce: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_00e9: 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_00bc: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_018e: 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_0192: Unknown result type (might be due to invalid IL or missing references) //IL_014c: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0165: 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_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) if (!_exitTriggered) { return; } if (!_isLocal || !_controllerApplied) { _handDriveExitActive = false; return; } Transform val = ResolveFirstPersonLeftHandTarget(); Transform rightTarget = ResolveFirstPersonRightHandTarget(); if (!_handDriveExitActive || (Object)(object)val == (Object)null) { _handDriveExitActive = false; if (pinRightHandToRest) { PinRightHandToRestPose(rightTarget); } return; } float num = Mathf.Max(0f, Time.unscaledTime - _exitTriggeredAt); if (!TryResolveCurrentHandRestPoses(out var leftPosition, out var leftRotation, out var _, out var _)) { if (pinRightHandToRest) { PinRightHandToRestPose(rightTarget); } return; } Vector3 val2 = leftPosition - _handDriveExitFromPosition; Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(val2.x, 0f, val2.z); if (((Vector3)(ref val3)).sqrMagnitude > 0.0001f) { val3 = ((Vector3)(ref val3)).normalized * 0.1f; } Vector3 val4 = _handDriveExitFromPosition + Vector3.up * 0.14f + val3; Vector3 val5; Quaternion val6; if (num < 0.24f) { float num2 = Smooth01(num / 0.24f); val5 = Vector3.Lerp(_handDriveExitFromPosition, val4, num2); val6 = Quaternion.Slerp(_handDriveExitFromRotation, leftRotation, num2 * 0.45f); } else if (num < 0.62f) { float num3 = Smooth01((num - 0.24f) / 0.38f); Vector3 p = leftPosition + Vector3.up * 0.08f; val5 = EvaluateCubicBezier(val4, val4 + val3, p, leftPosition, num3); val6 = Quaternion.Slerp(_handDriveExitFromRotation, leftRotation, num3); } else { val5 = leftPosition; val6 = leftRotation; } try { val.SetPositionAndRotation(val5, val6); } catch (Exception ex) { _handDriveExitActive = false; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Exit hand drive failed: " + ex.Message)); } } if (pinRightHandToRest) { PinRightHandToRestPose(rightTarget); } } private bool TryResolveCurrentHandRestPoses(out Vector3 leftPosition, out Quaternion leftRotation, out Vector3 rightPosition, out Quaternion rightRotation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_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_0023: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_00d4: 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_00de: 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_00cc: 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_00b8: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_00f8: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: 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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) leftPosition = Vector3.zero; leftRotation = Quaternion.identity; rightPosition = Vector3.zero; rightRotation = Quaternion.identity; Camera val = (((Object)(object)Player != (Object)null) ? Player.gameplayCamera : null); if ((Object)(object)val == (Object)null) { return false; } Transform transform = ((Component)val).transform; Vector3 val2 = Vector3.ProjectOnPlane(transform.forward, Vector3.up); if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.ProjectOnPlane(transform.up, Vector3.up); } if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f && (Object)(object)Player != (Object)null) { val2 = ((Component)Player).transform.forward; } if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.forward; } Quaternion val3 = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up); Quaternion val4 = (Y4NGZPlayerAnimationBridge.ShoulderAnchorIgnoresCameraPitch ? val3 : transform.rotation); leftPosition = transform.position + val4 * Y4NGZPlayerAnimationBridge.FirstPersonLeftHandRestOffset; leftRotation = val4 * Quaternion.Euler(Y4NGZPlayerAnimationBridge.FirstPersonLeftHandRestEuler); rightPosition = transform.position + val4 * Y4NGZPlayerAnimationBridge.FirstPersonRightHandRestOffset; rightRotation = val4 * Quaternion.Euler(Y4NGZPlayerAnimationBridge.FirstPersonRightHandRestEuler); return true; } private void PinRightHandToRestPose(Transform rightTarget) { //IL_001c: 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_0089: 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_00ad: 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) if ((Object)(object)rightTarget == (Object)null || !TryResolveCurrentHandRestPoses(out var leftPosition, out var _, out var rightPosition, out var rightRotation)) { return; } try { rightTarget.SetPositionAndRotation(rightPosition, rightRotation); _firstPersonRightHandTuningApplication = default(PoseTuningApplication); _handTraceDriveApplicationCount++; if (!_handRestFirstPinLogged) { _handRestFirstPinLogged = true; Camera camera = (((Object)(object)Player != (Object)null) ? Player.gameplayCamera : null); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][EnterAnim] designed hand rests first pin: left.worldPos=" + FormatTraceVector(leftPosition) + " left.viewport=" + FormatTraceViewport(leftPosition, camera) + " right.worldPos=" + FormatTraceVector(rightPosition) + " right.viewport=" + FormatTraceViewport(rightPosition, camera) + ".")); } } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogDebug((object)("[LethalCCTV] Right-hand rest pin failed: " + ex.Message)); } } } private static string FormatVector(Vector3 value) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"({value.x:F2}, {value.y:F2}, {value.z:F2})"; } private void TickWindingDown() { //IL_007d: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_animator == (Object)null || (Object)(object)Player == (Object)null) { EndImmediate("wind-down-invalid"); return; } if (Player.isPlayerDead || !Player.isPlayerControlled) { EndImmediate("wind-down-player-invalid"); return; } float unscaledTime = Time.unscaledTime; if (unscaledTime >= _restoreAt) { EndImmediate("wind-down-complete"); return; } _cameraControlActive = false; _radarLookActive = false; _joystickPhase.SetRequested(Vector2.zero); TickJoystickPose(controllingCamera: false); SetBool(CameraControlHash, value: false); SetBool(RadarLookHash, value: false); if (!_exitTriggered && (unscaledTime >= _exitReleaseAt || ((Vector2)(ref _joystickSmoothed)).sqrMagnitude <= 0.0025f)) { _joystickPhase.SetImmediate(Vector2.zero); _joystickSmoothed = Vector2.zero; SetFloat(JoystickXHash, 0f); SetFloat(JoystickYHash, 0f); SetBool(SeatedHash, value: false); TriggerExitPose(); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Operator anim exit release triggered after joystick neutralized."); } } ApplyOperatorAnimatorOverrides(); } private void TickJoystickPose(bool controllingCamera) { //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_0067: Unknown result type (might be due to invalid IL or missing references) _joystickSmoothed = _joystickPhase.Tick(Mathf.Max(Time.unscaledDeltaTime, 0.004166667f)); SetFloat(JoystickXHash, _joystickSmoothed.x); SetFloat(JoystickYHash, _joystickSmoothed.y); ApplyOperatorAnimatorOverrides(); if ((Object)(object)_runtimePose != (Object)null) { _runtimePose.Tick(_joystickSmoothed, controllingCamera); } } internal void SelectCamera(int slot) { if (_interactionsApiMode) { CCTVOperatorInteractionsBridge.TrySetInt(_interactionsApiHandle, "Y4NGZ_CCTV_ActiveSlot", Mathf.Clamp(slot, 0, 3)); CCTVOperatorInteractionsBridge.TrySetInt(_interactionsApiHandle, "Y4NGZ_CCTV_ActionButton", 1); CCTVOperatorInteractionsBridge.TryFireTrigger(_interactionsApiHandle, "Y4NGZ_CCTV_SelectCamera"); CCTVOperatorInteractionsBridge.TryFireTrigger(_interactionsApiHandle, "Y4NGZ_CCTV_ButtonPress"); return; } SetInt(ActiveSlotHash, Mathf.Clamp(slot, 0, 3)); SetInt(ActionButtonHash, 1); _buttonPressActionId = 1; FireTrigger(SelectCameraHash); FireTrigger(ButtonPressHash); _buttonPressLayerUntil = Time.unscaledTime + 1.15f; ApplyOperatorAnimatorOverrides(); _runtimePose?.PulseButtonPress(); } internal void SetActiveSlotQuiet(int slot) { if (_interactionsApiMode) { CCTVOperatorInteractionsBridge.TrySetInt(_interactionsApiHandle, "Y4NGZ_CCTV_ActiveSlot", Mathf.Clamp(slot, 0, 3)); } else { SetInt(ActiveSlotHash, Mathf.Clamp(slot, 0, 3)); } } internal void SetCameraControl(bool controllingCamera) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) _cameraControlActive = controllingCamera; if (_interactionsApiMode) { CCTVOperatorInteractionsBridge.TrySetBool(_interactionsApiHandle, "Y4NGZ_CCTV_CameraControl", controllingCamera); CCTVOperatorInteractionsBridge.TryFireTrigger(_interactionsApiHandle, controllingCamera ? "Y4NGZ_CCTV_JoystickGrab" : "Y4NGZ_CCTV_JoystickRelease"); if (!controllingCamera) { _joystickPhase.SetRequested(Vector2.zero); } return; } SetBool(CameraControlHash, controllingCamera); FireTrigger(controllingCamera ? JoystickGrabHash : JoystickReleaseHash); if (!controllingCamera) { _joystickPhase.SetRequested(Vector2.zero); } _runtimePose?.SetCameraControl(controllingCamera); } internal void SetRadarLook(bool lookingAtRadar) { _radarLookActive = lookingAtRadar; if (_interactionsApiMode) { CCTVOperatorInteractionsBridge.TrySetBool(_interactionsApiHandle, "Y4NGZ_CCTV_RadarLook", lookingAtRadar); return; } SetBool(RadarLookHash, lookingAtRadar); ApplyOperatorAnimatorOverrides(); } internal void OnJoystickMoved(Vector2 appliedDeltaDeg) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) _lastJoystickMoveAt = Time.unscaledTime; _joystickPhase.SetRequested(appliedDeltaDeg); } internal void SetJoystickTargetAbsolute(Vector2 deflection, bool immediate = false) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) _lastJoystickMoveAt = Time.unscaledTime; Vector2 val = CCTVJoystickPhaseDriver.QuantizeCardinal(new Vector2(Mathf.Clamp(deflection.x, -1f, 1f), Mathf.Clamp(deflection.y, -1f, 1f))); if (immediate) { _joystickPhase.SetImmediate(val); } else { _joystickPhase.SetRequested(val); } } internal void PressButton(int buttonId, bool isStandUp) { if (_interactionsApiMode) { if (isStandUp) { BeginGracefulEnd("stand-up"); return; } CCTVOperatorInteractionsBridge.TrySetInt(_interactionsApiHandle, "Y4NGZ_CCTV_ActionButton", buttonId); CCTVOperatorInteractionsBridge.TryFireTrigger(_interactionsApiHandle, "Y4NGZ_CCTV_ButtonPress"); return; } SetInt(ActionButtonHash, buttonId); if (isStandUp) { BeginGracefulEnd("stand-up"); return; } _buttonPressActionId = buttonId; FireTrigger(ButtonPressHash); _buttonPressLayerUntil = Time.unscaledTime + 1.15f; ApplyOperatorAnimatorOverrides(); _runtimePose?.PulseButtonPress(); } internal void PreviewFirstPersonRightHandTune(int actionButton) { if (!_isLocal || !_active || _windingDown || (Object)(object)_animator == (Object)null || !_controllerApplied || !ShouldShowFirstPersonArmsLayer() || _buttonPressLayer < 0 || _buttonPressLayer >= _animator.layerCount) { return; } _buttonPressActionId = actionButton; SetInt(ActionButtonHash, actionButton); _buttonPressLayerUntil = Time.unscaledTime + 1f; ApplyOperatorAnimatorOverrides(); int num = (Y4NGZPlayerAnimationBridge.IsBlueRightHandAction(actionButton) ? PressBlueCameraSwitchStateHash : PressGreenActionStateHash); try { _animator.Play(num, _buttonPressLayer, 0.4f); if (_rightHandEditPreviewActionId != actionButton) { _rightHandEditPreviewActionId = actionButton; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Right-hand edit preview holding " + (Y4NGZPlayerAnimationBridge.IsBlueRightHandAction(actionButton) ? "blue" : "green") + " press pose.")); } } if (!Y4NGZPlayerAnimationBridge.UseManualFirstPersonArmIk) { _animator.Update(0f); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogDebug((object)("[LethalCCTV] Right-hand edit preview hold failed: " + ex.Message)); } } } private void CaptureInteractionsApiPoseChain() { _apiPoseChainSnapshots = Array.Empty(); if (!_isLocal || !_interactionsApiMode || (Object)(object)Player == (Object)null) { return; } Transform localArmsTransform = Player.localArmsTransform; if ((Object)(object)localArmsTransform == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV][ApiPose] capture-chain unavailable: localArmsTransform is missing."); } } else { Transform transform = FindChildRecursive(localArmsTransform, "ArmsLeftArm_target"); Transform transform2 = FindChildRecursive(localArmsTransform, "ArmsRightArm_target"); List list = new List(3); CaptureApiPoseTransform(list, "localArmsTransform", localArmsTransform); CaptureApiPoseTransform(list, "ArmsLeftArm_target", transform); CaptureApiPoseTransform(list, "ArmsRightArm_target", transform2); _apiPoseChainSnapshots = list.ToArray(); } } private static void CaptureApiPoseTransform(List snapshots, string label, Transform transform) { //IL_003e: 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_004a: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][ApiPose] capture-chain transform missing: " + label + ".")); } return; } ApiPoseTransformSnapshot apiPoseTransformSnapshot = new ApiPoseTransformSnapshot { Label = label, Transform = transform, LocalPosition = transform.localPosition, LocalRotation = transform.localRotation }; snapshots.Add(apiPoseTransformSnapshot); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV][ApiPose] capture-chain transform=" + label + " path=" + GetTransformPath(transform) + " localPosition=" + FormatTraceVector(apiPoseTransformSnapshot.LocalPosition) + " localEuler=" + FormatTraceVector(((Quaternion)(ref apiPoseTransformSnapshot.LocalRotation)).eulerAngles) + ".")); } } private void RestoreInteractionsApiPoseChain(string reason) { //IL_008d: 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) //IL_00ae: 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_00c5: 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) ApiPoseTransformSnapshot[] apiPoseChainSnapshots = _apiPoseChainSnapshots; _apiPoseChainSnapshots = Array.Empty(); foreach (ApiPoseTransformSnapshot apiPoseTransformSnapshot in apiPoseChainSnapshots) { if (apiPoseTransformSnapshot == null || (Object)(object)apiPoseTransformSnapshot.Transform == (Object)null) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][ApiPose] restore-chain skipped a destroyed transform reason='" + reason + "' label=" + (apiPoseTransformSnapshot?.Label ?? "") + ".")); } continue; } try { apiPoseTransformSnapshot.Transform.localPosition = apiPoseTransformSnapshot.LocalPosition; apiPoseTransformSnapshot.Transform.localRotation = apiPoseTransformSnapshot.LocalRotation; float num = Vector3.Distance(apiPoseTransformSnapshot.Transform.localPosition, apiPoseTransformSnapshot.LocalPosition); float num2 = Quaternion.Angle(apiPoseTransformSnapshot.Transform.localRotation, apiPoseTransformSnapshot.LocalRotation); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV][ApiPose] restore-chain reason='" + reason + "' transform=" + apiPoseTransformSnapshot.Label + " path=" + GetTransformPath(apiPoseTransformSnapshot.Transform) + " " + $"postRestoreResidual={num:F3}m/{num2:F3}deg.")); } } catch (Exception ex) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV][ApiPose] restore-chain failed reason='" + reason + "' transform=" + apiPoseTransformSnapshot.Label + ": " + ex.Message)); } } } } private void ApplyInteractionsApiArmsRootStationPin() { //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: 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_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_025a: 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_025f: 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_0266: 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_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0589: Unknown result type (might be due to invalid IL or missing references) //IL_058b: Unknown result type (might be due to invalid IL or missing references) //IL_04e3: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_04f0: Unknown result type (might be due to invalid IL or missing references) //IL_04f3: Unknown result type (might be due to invalid IL or missing references) //IL_04f8: Unknown result type (might be due to invalid IL or missing references) //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_04fc: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_0500: Unknown result type (might be due to invalid IL or missing references) //IL_0502: Unknown result type (might be due to invalid IL or missing references) //IL_0507: Unknown result type (might be due to invalid IL or missing references) //IL_050c: Unknown result type (might be due to invalid IL or missing references) //IL_0511: Unknown result type (might be due to invalid IL or missing references) //IL_0515: Unknown result type (might be due to invalid IL or missing references) //IL_0517: Unknown result type (might be due to invalid IL or missing references) //IL_051c: Unknown result type (might be due to invalid IL or missing references) //IL_0520: Unknown result type (might be due to invalid IL or missing references) //IL_0525: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Unknown result type (might be due to invalid IL or missing references) //IL_0533: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0566: Unknown result type (might be due to invalid IL or missing references) //IL_0568: Unknown result type (might be due to invalid IL or missing references) //IL_0546: Unknown result type (might be due to invalid IL or missing references) //IL_0555: Unknown result type (might be due to invalid IL or missing references) //IL_0557: Unknown result type (might be due to invalid IL or missing references) //IL_055a: Unknown result type (might be due to invalid IL or missing references) //IL_055c: Unknown result type (might be due to invalid IL or missing references) //IL_055e: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0621: Unknown result type (might be due to invalid IL or missing references) //IL_0626: Unknown result type (might be due to invalid IL or missing references) //IL_062a: Unknown result type (might be due to invalid IL or missing references) //IL_04cd: Unknown result type (might be due to invalid IL or missing references) //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_044b: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_06ac: Unknown result type (might be due to invalid IL or missing references) //IL_0642: Unknown result type (might be due to invalid IL or missing references) //IL_0647: Unknown result type (might be due to invalid IL or missing references) //IL_064b: Unknown result type (might be due to invalid IL or missing references) //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_04ac: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_04b5: Unknown result type (might be due to invalid IL or missing references) //IL_04b7: Unknown result type (might be due to invalid IL or missing references) //IL_04b9: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_04c5: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_06c0: Unknown result type (might be due to invalid IL or missing references) //IL_06fc: Unknown result type (might be due to invalid IL or missing references) //IL_0716: Unknown result type (might be due to invalid IL or missing references) //IL_074b: Unknown result type (might be due to invalid IL or missing references) //IL_0750: Unknown result type (might be due to invalid IL or missing references) //IL_0776: Unknown result type (might be due to invalid IL or missing references) //IL_079a: Unknown result type (might be due to invalid IL or missing references) //IL_079f: Unknown result type (might be due to invalid IL or missing references) //IL_080d: Unknown result type (might be due to invalid IL or missing references) //IL_0824: Unknown result type (might be due to invalid IL or missing references) //IL_0892: Unknown result type (might be due to invalid IL or missing references) //IL_0897: Unknown result type (might be due to invalid IL or missing references) //IL_089c: Unknown result type (might be due to invalid IL or missing references) //IL_08a0: Unknown result type (might be due to invalid IL or missing references) //IL_08a5: Unknown result type (might be due to invalid IL or missing references) //IL_08aa: Unknown result type (might be due to invalid IL or missing references) //IL_08af: Unknown result type (might be due to invalid IL or missing references) //IL_08b1: Unknown result type (might be due to invalid IL or missing references) //IL_08b6: Unknown result type (might be due to invalid IL or missing references) //IL_08c8: Unknown result type (might be due to invalid IL or missing references) //IL_08da: Unknown result type (might be due to invalid IL or missing references) //IL_08f1: Unknown result type (might be due to invalid IL or missing references) //IL_08f3: Unknown result type (might be due to invalid IL or missing references) //IL_0928: Unknown result type (might be due to invalid IL or missing references) //IL_0937: Unknown result type (might be due to invalid IL or missing references) //IL_09f4: Unknown result type (might be due to invalid IL or missing references) //IL_09f6: Unknown result type (might be due to invalid IL or missing references) //IL_0992: Unknown result type (might be due to invalid IL or missing references) //IL_0997: Unknown result type (might be due to invalid IL or missing references) //IL_099c: Unknown result type (might be due to invalid IL or missing references) //IL_09aa: Unknown result type (might be due to invalid IL or missing references) //IL_09af: Unknown result type (might be due to invalid IL or missing references) //IL_0a9f: Unknown result type (might be due to invalid IL or missing references) if (!_isLocal || (!_active && !_windingDown)) { return; } bool useApiStationShoulderAnchor = Y4NGZPlayerAnimationBridge.UseApiStationShoulderAnchor; if (useApiStationShoulderAnchor && (!IsManualArmIkChainAvailable(_manualLeftArmIk) || !IsManualArmIkChainAvailable(_manualRightArmIk))) { EnsureInteractionsApiManualArmIkChains("station-shoulder-anchor"); } Transform val = (((Object)(object)Player != (Object)null) ? Player.localArmsTransform : null); if ((Object)(object)val == (Object)null) { LogApiArmsRootStationPinUnavailable("localArmsTransform-missing"); return; } if ((Object)(object)_apiArmsRootStationPinRoot != (Object)(object)val) { _apiArmsRootStationPinRoot = val; _apiArmsRootStationPinLeftTarget = null; _apiArmsRootStationPinLeftParent = null; _apiArmsRootStationPinRightTarget = null; } if ((Object)(object)_apiArmsRootStationPinLeftTarget == (Object)null) { _apiArmsRootStationPinLeftTarget = FindChildRecursive(val, "ArmsLeftArm_target"); _apiArmsRootStationPinLeftParent = (((Object)(object)_apiArmsRootStationPinLeftTarget != (Object)null) ? _apiArmsRootStationPinLeftTarget.parent : null); } if ((Object)(object)_apiArmsRootStationPinRightTarget == (Object)null) { _apiArmsRootStationPinRightTarget = FindChildRecursive(val, "ArmsRightArm_target"); } Transform apiArmsRootStationPinLeftTarget = _apiArmsRootStationPinLeftTarget; Transform apiArmsRootStationPinLeftParent = _apiArmsRootStationPinLeftParent; Transform apiArmsRootStationPinRightTarget = _apiArmsRootStationPinRightTarget; if (useApiStationShoulderAnchor && (Object)(object)apiArmsRootStationPinLeftParent == (Object)null) { LogApiArmsRootStationPinUnavailable("ArmsLeftArm_target-parent-missing"); return; } Transform operatorPoseAnchor = CCTVOperatorStation.OperatorPoseAnchor; Transform val2 = (((Object)(object)operatorPoseAnchor != (Object)null) ? operatorPoseAnchor.parent : null); if ((Object)(object)val2 == (Object)null) { LogApiArmsRootStationPinUnavailable("station-root-missing"); return; } try { _apiArmsRootStationPinUnavailableReason = null; Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(-0.373f, 0.669f, 2.192f); Vector3 value = val3; float worldDeltaY; bool flag = MonitorFocus.TryGetApiOperatorFloorRootDelta(out worldDeltaY); if (flag) { value.y -= worldDeltaY; } Quaternion val4 = Quaternion.Euler(354.9f, 106.55f, 359.12f); Vector3 val5 = val2.TransformPoint(ApiRightHandRestStationPosition); Quaternion val6 = val2.rotation * ApiRightHandRestStationRotation; AuthoredLeftHandStationPose pose; string clip; int frame; bool flag2 = TryResolveApiLeftAuthoredStationPose(out pose, out clip, out frame); bool flag3 = !_windingDown && _active && !MonitorFocus.IsEnterCameraPathComplete; bool flag4 = _windingDown || flag3; Vector3 val7 = (flag2 ? val2.TransformPoint(pose.Position) : Vector3.zero); Quaternion val8 = (flag2 ? (val2.rotation * pose.Rotation) : Quaternion.identity); Vector3 value2 = (((Object)(object)apiArmsRootStationPinLeftParent != (Object)null) ? apiArmsRootStationPinLeftParent.position : Vector3.zero); Vector3 val9 = Vector3.zero; Vector3 val10 = Vector3.zero; Vector3 val11 = Vector3.zero; string mode = ""; float stationBlend = 1f; bool flag5 = false; Vector3 val12 = Vector3.zero; bool flag6 = false; if (useApiStationShoulderAnchor) { if (!IsManualArmIkChainAvailable(_manualLeftArmIk) || !IsManualArmIkChainAvailable(_manualRightArmIk)) { LogApiArmsRootStationPinUnavailable("station-shoulder-anchor-chains-missing"); return; } val9 = (_manualLeftArmIk.Root.position + _manualRightArmIk.Root.position) * 0.5f; val10 = ResolveApiShoulderAnchorTarget(val2, out mode, out stationBlend); val11 = val10 - val9; val.position += val11; flag5 = true; val12 = (_manualLeftArmIk.Root.position + _manualRightArmIk.Root.position) * 0.5f; flag6 = true; } string text = "none"; if (useApiStationShoulderAnchor && (Object)(object)apiArmsRootStationPinLeftTarget != (Object)null && (Object)(object)apiArmsRootStationPinLeftParent != (Object)null) { if (Y4NGZPlayerAnimationBridge.UseApiLeftTargetFromAuthoredTable && flag4 && flag2) { Vector3 val13 = val7; Vector3 rightPosition; if (flag3) { float num = ComputeEnterPressContactWeight(frame); if (num > 0f) { Vector3? val14 = Y4NGZPlayerAnimationBridge.ResolveAccessButtonPressPoint(); if (val14.HasValue) { Vector3 val15 = val2.TransformPoint(ApiLeftEnterAuthoredTable[15].Position); Vector3 val16 = (val14.Value - val8 * ApiEnterPressLocalIndexTipOffset - val15) * num; val13 += val16; ArmApiPressContactPostSolveSample(frame, val16, val14.Value, val15); } } float num2 = Smooth01(Mathf.Clamp01((float)frame / 6f)); if (num2 < 1f && TryResolveCurrentHandRestPoses(out var leftPosition, out var _, out rightPosition, out var _)) { val13 = Vector3.Lerp(leftPosition, val13, num2); } } float num3 = 0f; if (flag3) { num3 = ComputeEnterLeverContactWeight(frame); } else if (_windingDown) { num3 = ComputeExitLeverContactWeight(frame); } if (num3 > 0f && TryResolveLeverWristTarget(val8, out var wristTarget, out rightPosition, out var _)) { Vector3 val17 = val2.TransformPoint(ApiLeftEnterAuthoredTable[ApiLeftEnterAuthoredTable.Length - 1].Position); val13 += (wristTarget - val17) * num3; } apiArmsRootStationPinLeftTarget.SetPositionAndRotation(val13, val8); text = "authored-table"; } else { Vector3 localPosition = apiArmsRootStationPinLeftTarget.localPosition; Quaternion localRotation = apiArmsRootStationPinLeftTarget.localRotation; Vector3 lossyScale = apiArmsRootStationPinLeftParent.lossyScale; Vector3 val18 = val3 + val4 * Vector3.Scale(lossyScale, localPosition); Vector3 val19 = val2.TransformPoint(val18); Quaternion val20 = val2.rotation * val4 * localRotation; if (_active && !_windingDown && TryResolveLeverWristTarget(val20, out var wristTarget2, out var liveGrip, out var localPalmOffset2)) { val19 = wristTarget2; ArmApiLeverContactPostSolveSample(liveGrip, wristTarget2, localPalmOffset2); } apiArmsRootStationPinLeftTarget.SetPositionAndRotation(val19, val20); text = "round7-reconstruction"; } } if (Y4NGZPlayerAnimationBridge.PinRightHandRestToStationDuringApiSession && (Object)(object)apiArmsRootStationPinRightTarget != (Object)null) { apiArmsRootStationPinRightTarget.SetPositionAndRotation(val5, val6); } if (_windingDown && Y4NGZPlayerAnimationBridge.UseApiExitRetractToRest && _interactionsApiExitStartedAt > 0f && TryResolveCurrentHandRestPoses(out var leftPosition2, out var _, out var rightPosition2, out var _)) { float num4 = Mathf.Max(0.05f, Y4NGZPlayerAnimationBridge.ApiExitRetractSeconds); float num5 = Mathf.Max(0f, 0.87f - num4); float num6 = Smooth01(Mathf.Clamp01((Time.unscaledTime - _interactionsApiExitStartedAt - num5) / num4)); if (num6 > 0f) { if ((Object)(object)apiArmsRootStationPinLeftTarget != (Object)null) { apiArmsRootStationPinLeftTarget.position = Vector3.Lerp(apiArmsRootStationPinLeftTarget.position, leftPosition2, num6); } if ((Object)(object)apiArmsRootStationPinRightTarget != (Object)null) { apiArmsRootStationPinRightTarget.position = Vector3.Lerp(apiArmsRootStationPinRightTarget.position, rightPosition2, num6); } } } bool num7 = !_apiArmsRootStationPinActive || Time.unscaledTime >= _apiArmsRootStationPinNextTelemetryAt; _apiArmsRootStationPinActive = true; if (!num7) { return; } _apiArmsRootStationPinNextTelemetryAt = Time.unscaledTime + 1f; string text2 = (flag5 ? "station-shoulder-anchor" : "none"); string text3 = (flag5 ? FormatTraceVector(val9) : ""); string text4 = (flag5 ? FormatTraceVector(val10) : ""); string text5 = (flag5 ? $"{((Vector3)(ref val11)).magnitude:F3}m" : ""); string text6 = (((Object)(object)apiArmsRootStationPinLeftParent != (Object)null) ? FormatTraceVector(value2) : ""); string arg = (((Object)(object)apiArmsRootStationPinLeftTarget != (Object)null) ? FormatTraceVector(apiArmsRootStationPinLeftTarget.position) : ""); string text7 = (((Object)(object)apiArmsRootStationPinLeftTarget != (Object)null && flag2) ? $"{Vector3.Distance(apiArmsRootStationPinLeftTarget.position, val7):F3}m" : (((Object)(object)apiArmsRootStationPinLeftTarget == (Object)null) ? "" : "")); string text8 = (((Object)(object)apiArmsRootStationPinRightTarget != (Object)null) ? FormatTraceVector(apiArmsRootStationPinRightTarget.position) : ""); string text9 = (((Object)(object)apiArmsRootStationPinRightTarget != (Object)null) ? $"{Vector3.Distance(apiArmsRootStationPinRightTarget.position, val5):F3}m" : ""); Camera val21 = (((Object)(object)Player != (Object)null) ? Player.gameplayCamera : null); string text10 = ""; string text11 = ""; string text12 = ""; if ((Object)(object)val21 != (Object)null) { Transform transform = ((Component)val21).transform; text10 = "cameraWorldPos=" + FormatTraceVector(transform.position) + " cameraWorldEuler=" + FormatTraceVector(transform.eulerAngles) + " " + $"cameraFov={val21.fieldOfView:0.###} " + $"cameraAspect={val21.aspect:0.###} " + $"cameraNear={val21.nearClipPlane:0.###}"; if (flag5) { Vector3 val22 = Quaternion.Inverse(transform.rotation) * (val10 - transform.position); Vector3 apiCameraAnchorOffset = Y4NGZPlayerAnimationBridge.ApiCameraAnchorOffset; text11 = "anchorCamSpace=" + FormatTraceVector(val22) + " cameraFrameOffset=" + FormatTraceVector(apiCameraAnchorOffset) + " cameraFrame=yaw-flat " + $"offsetResidual={Vector3.Distance(val22, apiCameraAnchorOffset):F4}m"; float num8 = val21.fieldOfView * 0.5f * (MathF.PI / 180f); float num9 = Mathf.Cos(num8) * val22.y + Mathf.Sin(num8) * val22.z; text12 = $"shoulderMidBelowBottomPlane={num9:F4}m " + $"capRadiusNeeded={Y4NGZPlayerAnimationBridge.ApiShoulderCapPlugDiameter * 0.5f:F4}m"; } } string text13 = ""; Quaternion pinCameraInverse; Vector3 pinCameraPosition; if (flag5 && (Object)(object)val21 != (Object)null) { pinCameraInverse = Quaternion.Inverse(((Component)val21).transform.rotation); pinCameraPosition = ((Component)val21).transform.position; text13 = FormatArm("armUpperL", _manualLeftArmIk) + " " + FormatArm("armUpperR", _manualRightArmIk); } string text14 = (flag6 ? $"{Vector3.Distance(val12, val10):F4}m" : ""); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ApiPose] pin rootWriter=" + text2 + " " + text10 + " " + text11 + " " + text12 + " " + text13 + " postPinMidToAnchor=" + text14 + " floorRootDeltaWorldY=" + (flag ? worldDeltaY.ToString("F3") : "") + " pinStationTarget=" + FormatTraceVector(value) + " shoulderMidWorld=" + text3 + " anchorTarget=" + text4 + " anchorDelta=" + text5 + " " + $"anchorMode={mode} stationBlend={stationBlend:F3} " + "preLeftParentWorld=" + text6 + " legacyRootPin=removed leftTargetWriter=" + text + " authoredClip=" + clip + " " + $"authoredFrame={frame} leftTargetWorld={arg} " + "leftAuthoredResidual=" + text7 + " rightTargetWorld=" + text8 + " rightAuthoredResidual=" + text9 + ".")); } string FormatArm(string label, ManualArmIkChain chain) { //IL_0023: 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_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_0031: 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) //IL_0040: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if (chain == null || (Object)(object)chain.Root == (Object)null) { return label + "="; } Vector3 position = chain.Root.position; Vector3 value3 = pinCameraInverse * (position - pinCameraPosition); return label + "World=" + FormatTraceVector(position) + " " + label + "Cam=" + FormatTraceVector(value3) + " " + $"{label}LossyScale={chain.Root.lossyScale.x:0.###}"; } } catch (Exception ex) { LogApiArmsRootStationPinUnavailable("write-failed:" + ex.GetType().Name + ":" + ex.Message); } } private void ApplyInteractionsApiLeverControlReachAssist() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00ae: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: 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_0145: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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_017c: 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_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: 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_01b7: 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) Transform val = (((Object)(object)Player != (Object)null) ? Player.localArmsTransform : null); ManualArmIkChain manualLeftArmIk = _manualLeftArmIk; Transform apiArmsRootStationPinLeftTarget = _apiArmsRootStationPinLeftTarget; if ((Object)(object)val == (Object)null || !IsManualArmIkChainAvailable(manualLeftArmIk) || (Object)(object)apiArmsRootStationPinLeftTarget == (Object)null) { _apiLeverControlReachAssistSmoothed = 0f; return; } bool flag = _active && !_windingDown && MonitorFocus.IsEnterCameraPathComplete; float num = 0f; Vector3 val2 = _apiLeverControlReachAssistLastDirection; float num2 = 0f; float num3 = (manualLeftArmIk.UpperLength + manualLeftArmIk.LowerLength) * 0.97f; if (flag) { Vector3 val3 = apiArmsRootStationPinLeftTarget.position - manualLeftArmIk.Root.position; num2 = ((Vector3)(ref val3)).magnitude; if (num2 > num3 && num2 > 0.0001f) { num = Mathf.Min(num2 - num3, 0.24f); val2 = val3 / num2; } } _apiLeverControlReachAssistSmoothed = Mathf.MoveTowards(_apiLeverControlReachAssistSmoothed, num, 2f * Mathf.Max(Time.unscaledDeltaTime, 0.004166667f)); if (_apiLeverControlReachAssistSmoothed <= 0.0001f || ((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { return; } ((Vector3)(ref val2)).Normalize(); _apiLeverControlReachAssistLastDirection = val2; Vector3 position = apiArmsRootStationPinLeftTarget.position; Quaternion rotation = apiArmsRootStationPinLeftTarget.rotation; Transform apiArmsRootStationPinRightTarget = _apiArmsRootStationPinRightTarget; Vector3 val4 = (((Object)(object)apiArmsRootStationPinRightTarget != (Object)null) ? apiArmsRootStationPinRightTarget.position : Vector3.zero); Quaternion val5 = (((Object)(object)apiArmsRootStationPinRightTarget != (Object)null) ? apiArmsRootStationPinRightTarget.rotation : Quaternion.identity); val.position += val2 * _apiLeverControlReachAssistSmoothed; apiArmsRootStationPinLeftTarget.SetPositionAndRotation(position, rotation); if ((Object)(object)apiArmsRootStationPinRightTarget != (Object)null) { apiArmsRootStationPinRightTarget.SetPositionAndRotation(val4, val5); } if (flag && num > 0.005f && !_apiLeverControlReachAssistLogged) { _apiLeverControlReachAssistLogged = true; CCTVOperatorStation.TryResolveLeverGripPoint(out var _, out var source); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogMessage((object)("[LethalCCTV][LeverReach] source=" + source + " " + $"rootToTarget={num2:F3}m usableReach={num3:F3}m " + $"goal={num:F3}m cap={0.24f:F3}m; " + "cameraPose=unchanged.")); } } } private Vector3 ResolveApiShoulderAnchorTarget(Transform stationRoot, out string mode, out float stationBlend) { //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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0232: 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_0237: Unknown result type (might be due to invalid IL or missing references) Vector3 val = stationRoot.TransformPoint(Y4NGZPlayerAnimationBridge.ApiShoulderAnchorStation); mode = "station"; stationBlend = 1f; bool apiKeepCameraAnchorDuringControl = Y4NGZPlayerAnimationBridge.ApiKeepCameraAnchorDuringControl; if (!Y4NGZPlayerAnimationBridge.UseApiCameraRelativeIntroAnchor && !apiKeepCameraAnchorDuringControl) { return val; } bool flag = _windingDown && _interactionsApiExitStartedAt > 0f; bool flag2 = !flag && _active && !MonitorFocus.IsEnterCameraPathComplete; if (!flag2 && !flag && !apiKeepCameraAnchorDuringControl) { return val; } Camera val2 = (((Object)(object)Player != (Object)null) ? Player.gameplayCamera : null); if ((Object)(object)val2 == (Object)null) { mode = "station-camera-missing"; return val; } Transform transform = ((Component)val2).transform; Vector3 val3 = Vector3.ProjectOnPlane(transform.forward, Vector3.up); if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { val3 = Vector3.ProjectOnPlane(transform.up, Vector3.up); } if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f && (Object)(object)Player != (Object)null) { val3 = Vector3.ProjectOnPlane(((Component)Player).transform.forward, Vector3.up); } if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { val3 = Vector3.forward; } Quaternion val4 = Quaternion.LookRotation(((Vector3)(ref val3)).normalized, Vector3.up); Vector3 val5 = transform.position + val4 * Y4NGZPlayerAnimationBridge.ApiCameraAnchorOffset; if (apiKeepCameraAnchorDuringControl) { stationBlend = 0f; mode = (flag2 ? "camera-enter-hold" : (flag ? "camera-exit-hold" : "camera-control-hold")); return val5; } if (flag2) { float num = Mathf.Clamp01((Time.unscaledTime - _interactionsApiStartedAt) / 1.1f); stationBlend = Smooth01(Mathf.InverseLerp(0.85f, 1f, num)); mode = ((stationBlend <= 0f) ? "camera-enter" : ((stationBlend >= 1f) ? "station-enter-settle" : "camera-station-enter-blend")); } else { float num2 = Mathf.Clamp01((Time.unscaledTime - _interactionsApiExitStartedAt) / 0.87f); stationBlend = 1f - Smooth01(Mathf.InverseLerp(0f, 0.15f, num2)); mode = ((stationBlend >= 1f) ? "station-exit-start" : ((stationBlend <= 0f) ? "camera-exit" : "station-camera-exit-blend")); } return Vector3.Lerp(val5, val, stationBlend); } private bool TryResolveApiLeftAuthoredStationPose(out AuthoredLeftHandStationPose pose, out string clip, out int frame) { bool flag = _windingDown && _interactionsApiExitStartedAt > 0f; AuthoredLeftHandStationPose[] array = (flag ? ApiLeftExitAuthoredTable : ApiLeftEnterAuthoredTable); clip = (flag ? "exit" : "enter"); frame = -1; pose = default(AuthoredLeftHandStationPose); if (array == null || array.Length == 0) { return false; } float num = (flag ? Mathf.Max(0f, Time.unscaledTime - _interactionsApiExitStartedAt) : ResolveEnterClipPresentationSeconds()); frame = Mathf.Clamp(Mathf.CeilToInt(num * 30f), 1, array.Length); pose = array[frame - 1]; return true; } private float ResolveEnterClipPresentationSeconds() { float enterPresentationClockSeconds = MonitorFocus.EnterPresentationClockSeconds; if (enterPresentationClockSeconds >= 0f) { return enterPresentationClockSeconds; } return Mathf.Max(0f, Time.unscaledTime - _interactionsApiStartedAt); } private static float ComputeEnterPressContactWeight(int frame) { float value = Mathf.Clamp01(((float)frame - 5f) / 3f); float value2 = 1f - Mathf.Clamp01(((float)frame - 16f) / 3f); return Smooth01(value) * Smooth01(value2); } private static float ComputeEnterLeverContactWeight(int frame) { return Smooth01(Mathf.Clamp01(((float)frame - 23f) / 3f)); } private static float ComputeExitLeverContactWeight(int frame) { return 1f - Smooth01(Mathf.Clamp01(((float)frame - 2f) / 4f)); } private bool TryResolveLeverWristTarget(Quaternion targetRotation, out Vector3 wristTarget, out Vector3 liveGrip, out Vector3 localPalmOffset) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) wristTarget = Vector3.zero; liveGrip = Vector3.zero; localPalmOffset = ResolveApiLeverPalmLocalOffset(); Vector3? val = Y4NGZPlayerAnimationBridge.ResolveLeverGripPoint(); if (!val.HasValue) { return false; } liveGrip = val.Value; Quaternion val2 = targetRotation; if (_manualLeftArmIk != null) { val2 *= _manualLeftArmIk.TargetToTipRotation; } Vector3 val3 = liveGrip + Vector3.up * 0.025f; wristTarget = val3 - val2 * localPalmOffset; if (!_apiLeverContactLogged) { _apiLeverContactLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogMessage((object)("[LethalCCTV][LeverContact] source=" + _apiLeverPalmOffsetSource + " localPalm=" + FormatTraceVector(localPalmOffset) + " liveGrip=" + FormatTraceVector(liveGrip) + " desiredPalm=" + FormatTraceVector(val3) + " wristTarget=" + FormatTraceVector(wristTarget) + ".")); } } return true; } private Vector3 ResolveApiLeverPalmLocalOffset() { //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_0009: 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_0058: 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) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00d5: 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_00df: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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) if (_apiLeverPalmOffsetResolved) { return _apiLeverPalmLocalOffset; } _apiLeverPalmOffsetResolved = true; _apiLeverPalmLocalOffset = ApiLeverFallbackLocalPalmOffset; _apiLeverPalmOffsetSource = "fallback"; Transform val = ((_manualLeftArmIk != null) ? _manualLeftArmIk.Tip : null); if ((Object)(object)val == (Object)null) { return _apiLeverPalmLocalOffset; } Vector3 val2 = Vector3.zero; int num = 0; for (int i = 0; i < ApiLeverPalmKnuckleBoneNames.Length; i++) { Transform val3 = FindChildRecursive(val, ApiLeverPalmKnuckleBoneNames[i]); if (!((Object)(object)val3 == (Object)null)) { val2 += val3.position; num++; } } if (num < 2) { return _apiLeverPalmLocalOffset; } val2 /= (float)num; Vector3 val4 = Vector3.Lerp(val.position, val2, 0.58f); Vector3 apiLeverPalmLocalOffset = Quaternion.Inverse(val.rotation) * (val4 - val.position); float magnitude = ((Vector3)(ref apiLeverPalmLocalOffset)).magnitude; if (magnitude < 0.035f || magnitude > 0.14f) { return _apiLeverPalmLocalOffset; } _apiLeverPalmLocalOffset = apiLeverPalmLocalOffset; _apiLeverPalmOffsetSource = $"finger-roots:{num}"; return _apiLeverPalmLocalOffset; } private void ArmApiLeverContactPostSolveSample(Vector3 liveGrip, Vector3 wristTarget, Vector3 localPalmOffset) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0023: 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_002d: 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_0034: 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_003b: Unknown result type (might be due to invalid IL or missing references) if (!_apiLeverContactPostSolveLogged) { _apiLeverContactSamplePending = true; _apiLeverContactSampleLiveGrip = liveGrip; _apiLeverContactSampleDesiredPalm = liveGrip + Vector3.up * 0.025f; _apiLeverContactSampleWristTarget = wristTarget; _apiLeverContactSampleLocalPalmOffset = localPalmOffset; } } private void ArmApiPressContactPostSolveSample(int frame, Vector3 correction, Vector3 liveButton, Vector3 authoredContactWorld) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0035: Unknown result type (might be due to invalid IL or missing references) if (!_apiPressContactSnapLogged && !_apiPressContactSamplePending && frame >= 15) { _apiPressContactSamplePending = true; _apiPressContactSampleFrame = frame; _apiPressContactSampleCorrection = correction; _apiPressContactSampleLiveButton = liveButton; _apiPressContactSampleAuthoredContact = authoredContactWorld; } } private void LogApiPressContactPostSolveSample() { //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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) if (_apiPressContactSamplePending) { _apiPressContactSamplePending = false; _apiPressContactSnapLogged = true; Vector3 apiPressContactSampleLiveButton = _apiPressContactSampleLiveButton; Transform val = ((_manualLeftArmIk != null) ? _manualLeftArmIk.Tip : null); object obj; if (!((Object)(object)val != (Object)null)) { obj = ""; } else { string[] obj2 = new string[5] { FormatTraceVector(val.position), " rotEuler=", null, null, null }; Quaternion rotation = val.rotation; obj2[2] = FormatTraceVector(((Quaternion)(ref rotation)).eulerAngles); obj2[3] = " "; obj2[4] = $"tipToButton={Vector3.Distance(val.position, apiPressContactSampleLiveButton):F3}m"; obj = string.Concat(obj2); } string text = (string)obj; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { string[] obj3 = new string[10] { $"[LethalCCTV][PressContact] press-bottom(post-solve) frame={_apiPressContactSampleFrame}: ", $"correction={((Vector3)(ref _apiPressContactSampleCorrection)).magnitude:F3}m ", "liveButton=", FormatTraceVector(apiPressContactSampleLiveButton), " authoredContact=", FormatTraceVector(_apiPressContactSampleAuthoredContact), " solvedWrist=", text, " (expect tipToButton~", null }; Vector3 apiEnterPressLocalIndexTipOffset = ApiEnterPressLocalIndexTipOffset; obj3[9] = $"{((Vector3)(ref apiEnterPressLocalIndexTipOffset)).magnitude:0.00}m, index tip closest at ~0.00-0.02m)."; log.LogInfo((object)string.Concat(obj3)); } if ((Object)(object)val != (Object)null) { LogApiPressContactFingerChain(val, val, apiPressContactSampleLiveButton); } } } private void LogApiLeverContactPostSolveSample() { //IL_004b: 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_0057: 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_0061: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00d7: 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_00f5: 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_0114: Unknown result type (might be due to invalid IL or missing references) if (!_apiLeverContactSamplePending || _apiLeverContactPostSolveLogged) { return; } ManualArmIkChain manualLeftArmIk = _manualLeftArmIk; Transform val = manualLeftArmIk?.Tip; if (!((Object)(object)val == (Object)null) && manualLeftArmIk.LastSolvedFrame == Time.frameCount) { _apiLeverContactSamplePending = false; _apiLeverContactPostSolveLogged = true; Vector3 val2 = val.position + val.rotation * _apiLeverContactSampleLocalPalmOffset; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogMessage((object)("[LethalCCTV][LeverContact] control(post-solve) liveGrip=" + FormatTraceVector(_apiLeverContactSampleLiveGrip) + " desiredPalm=" + FormatTraceVector(_apiLeverContactSampleDesiredPalm) + " solvedPalm=" + FormatTraceVector(val2) + " wristTarget=" + FormatTraceVector(_apiLeverContactSampleWristTarget) + " solvedWrist=" + FormatTraceVector(val.position) + " " + $"palmToDesired={Vector3.Distance(val2, _apiLeverContactSampleDesiredPalm):F3}m " + $"palmToGrip={Vector3.Distance(val2, _apiLeverContactSampleLiveGrip):F3}m " + $"wristToTarget={manualLeftArmIk.LastTipTargetDistance:F3}m " + $"rootToTarget={manualLeftArmIk.LastRootTargetDistance:F3}m " + $"reach={manualLeftArmIk.LastReach:F3}m.")); } } } private void LogApiPressContactFingerChain(Transform hand, Transform current, Vector3 liveButton) { //IL_001c: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_00b6: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < current.childCount; i++) { Transform child = current.GetChild(i); if (!((Object)(object)child == (Object)null)) { Vector3 position = child.position; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][PressContact] finger bone='" + ((Object)child).name + "' world=" + FormatTraceVector(position) + " handLocal=" + FormatTraceVector(hand.InverseTransformPoint(position)) + " " + $"toButton={Vector3.Distance(position, liveButton):F3}m " + $"children={child.childCount}.")); } LogApiPressContactFingerChain(hand, child, liveButton); } } } private void LogApiArmsRootStationPinUnavailable(string reason) { if (!string.Equals(_apiArmsRootStationPinUnavailableReason, reason, StringComparison.Ordinal)) { _apiArmsRootStationPinUnavailableReason = reason; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][ApiPose] pin_unavailable reason='" + reason + "'.")); } } } private void ReleaseInteractionsApiArmsRootStationPin(string reason) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (_apiArmsRootStationPinActive) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ApiPose] released reason='" + reason + "'.")); } } _apiArmsRootStationPinRoot = null; _apiArmsRootStationPinLeftTarget = null; _apiArmsRootStationPinLeftParent = null; _apiArmsRootStationPinRightTarget = null; _apiArmsRootStationPinActive = false; _apiArmsRootStationPinNextTelemetryAt = 0f; _apiArmsRootStationPinUnavailableReason = null; _apiLeverControlReachAssistSmoothed = 0f; _apiLeverControlReachAssistLastDirection = Vector3.zero; } private void FinishFirstPersonArmFrame() { if (Y4NGZPlayerAnimationBridge.UseManualFirstPersonArmIk) { ApplyManualFirstPersonArmIk(); ApplyRightArmPresentationHideAfterManualIk(); } else { EvaluateLegacyFirstPersonArmRig(); ApplyRightArmPresentationHideAfterManualIk(); } LogApiPressContactPostSolveSample(); LogApiLeverContactPostSolveSample(); Transform leftShoulder = (((Object)(object)_manualLeftArmIk?.Root != (Object)null) ? _manualLeftArmIk.Root.parent : null); Transform rightShoulder = (((Object)(object)_manualRightArmIk?.Root != (Object)null) ? _manualRightArmIk.Root.parent : _rightArmPresentationShoulder); MonitorFocus.LogPendingViewFraming(((Object)(object)Player != (Object)null) ? Player.gameplayCamera : null, leftShoulder, rightShoulder); } internal void TraceFirstPersonHandsPreCull(Camera camera) { if (!_interactionsApiMode && _handTraceEnabled && _handTraceFrame == Time.frameCount && !((Object)(object)Player == (Object)null) && !((Object)(object)camera == (Object)null) && !((Object)(object)camera != (Object)(object)Player.gameplayCamera)) { TraceHandSnapshot("D-gameplay-camera/pre-cull"); _handTraceFrame = -1; } } private void LogExitArmsFrame(string phase) { if (_exitArmsTelemetryEnabled && _exitArmsLastLoggedFrame != Time.frameCount) { _exitArmsLastLoggedFrame = Time.frameCount; WriteExitArmsLog(phase, Player, _firstPersonArmsRoot, (_manualLeftArmIk != null) ? _manualLeftArmIk.Tip : null, (_manualLeftArmIk != null) ? _manualLeftArmIk.Target : _firstPersonLeftHandTarget, _rightArmPresentationShoulder, (_manualRightArmIk != null) ? _manualRightArmIk.Target : _firstPersonRightHandTarget, _firstPersonArmsRenderer, _presentationRemapValid, _shoulderAnchorAppliedFrame == Time.frameCount, _firstPersonArmsHiddenForMissingAnchor); } } private void StartPostExitArmsTelemetry() { if (_isLocal && !((Object)(object)Player == (Object)null)) { _postExitArmsTelemetry = new ExitArmsPostExitTelemetry { Player = Player, ArmsRoot = _firstPersonArmsRoot, LeftHand = ((_manualLeftArmIk != null) ? _manualLeftArmIk.Tip : null), LeftTarget = ((_manualLeftArmIk != null) ? _manualLeftArmIk.Target : _firstPersonLeftHandTarget), RightShoulder = _rightArmPresentationShoulder, RightTarget = ((_manualRightArmIk != null) ? _manualRightArmIk.Target : _firstPersonRightHandTarget), ArmsRenderer = (Renderer)(((Object)(object)_firstPersonArmsRenderer != (Object)null) ? ((object)_firstPersonArmsRenderer) : ((object)Player.thisPlayerModelArms)) }; } } internal static void TickPostExitArmsTelemetry() { ExitArmsPostExitTelemetry postExitArmsTelemetry = _postExitArmsTelemetry; if (postExitArmsTelemetry != null && postExitArmsTelemetry.NextIndex <= 15 && postExitArmsTelemetry.LastLoggedFrame != Time.frameCount) { postExitArmsTelemetry.LastLoggedFrame = Time.frameCount; Transform root; Vector3 animPosition; Quaternion animRotation; Vector3 finalPosition; Quaternion finalRotation; bool presentationRemapValid = MonitorFocus.TryGetFirstPersonArmsPresentationThisFrame(out root, out animPosition, out animRotation, out finalPosition, out finalRotation); WriteExitArmsLog($"post-exit-{postExitArmsTelemetry.NextIndex}", postExitArmsTelemetry.Player, postExitArmsTelemetry.ArmsRoot, postExitArmsTelemetry.LeftHand, postExitArmsTelemetry.LeftTarget, postExitArmsTelemetry.RightShoulder, postExitArmsTelemetry.RightTarget, postExitArmsTelemetry.ArmsRenderer, presentationRemapValid, shoulderAnchorApplied: false, anchorFallbackHidden: false); postExitArmsTelemetry.NextIndex++; if (postExitArmsTelemetry.NextIndex > 15) { _postExitArmsTelemetry = null; } } } internal static void ClearPostExitArmsTelemetry() { _postExitArmsTelemetry = null; } private static void WriteExitArmsLog(string phase, PlayerControllerB player, Transform armsRoot, Transform leftHand, Transform leftTarget, Transform rightShoulder, Transform rightTarget, Renderer armsRenderer, bool presentationRemapValid, bool shoulderAnchorApplied, bool anchorFallbackHidden) { //IL_0042: 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_007c: 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_00b8: 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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: 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) try { Camera val = (((Object)(object)player != (Object)null) ? player.gameplayCamera : null); Transform val2 = (((Object)(object)player != (Object)null) ? player.localVisor : null); MonitorFocus.GetLocalRendererBookkeeping(armsRenderer, out var forcedVisible, out var obstructor); string text = (((Object)(object)armsRoot != (Object)null) ? FormatTraceVector(armsRoot.position) : ""); string text2 = (((Object)(object)armsRoot != (Object)null) ? FormatTraceVector(armsRoot.localPosition) : ""); string text3 = (((Object)(object)armsRoot != (Object)null) ? FormatTraceVector(armsRoot.localEulerAngles) : ""); string text4 = (((Object)(object)leftHand != (Object)null) ? FormatTraceVector(leftHand.position) : ""); string text5 = (((Object)(object)leftTarget != (Object)null) ? FormatTraceVector(leftTarget.position) : ""); string text6 = (((Object)(object)rightTarget != (Object)null) ? FormatTraceVector(rightTarget.position) : ""); string text7 = (((Object)(object)rightTarget != (Object)null) ? FormatTraceViewport(rightTarget.position, val) : ""); string text8 = (((Object)(object)rightShoulder != (Object)null) ? rightShoulder.lossyScale.x.ToString("0.000000") : ""); string text9 = (((Object)(object)leftHand != (Object)null && (Object)(object)val != (Object)null) ? FormatTraceVector(val.WorldToViewportPoint(leftHand.position)) : ""); string text10 = (((Object)(object)armsRenderer != (Object)null) ? armsRenderer.enabled.ToString() : ""); string arg = (((Object)(object)val2 != (Object)null) ? FormatTraceVector(val2.localPosition) : ""); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][ExitArms] Time.frameCount={Time.frameCount} phase={phase} " + $"_presentationRemapValid={presentationRemapValid} shoulderAnchorAppliedThisFrame={shoulderAnchorApplied} " + "ScavengerModelArmsOnly.worldPos=" + text + " ScavengerModelArmsOnly.localPosition=" + text2 + " ScavengerModelArmsOnly.localEulerAngles=" + text3 + " hand.L.worldPos=" + text4 + " target.L.worldPos=" + text5 + " target.R.worldPos=" + text6 + " target.R.viewport=" + text7 + " shoulder.R.lossyScale.x=" + text8 + " hand.L.viewport=" + text9 + " thisPlayerModelArms.enabled=" + text10 + " " + $"thisPlayerModelArms.forcedVisible={forcedVisible} thisPlayerModelArms.obstructor={obstructor} " + $"anchorFallbackHidden={anchorFallbackHidden} localVisor.localPosition={arg}.")); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)$"[LethalCCTV][ExitArms] Time.frameCount={Time.frameCount} phase={phase} telemetry-failed: {ex.Message}"); } } } private void LogFirstPersonTargetCalibrationOnce() { if (_fpCalibrationLogged || !_isLocal || !_controllerApplied) { return; } Camera val = (((Object)(object)Player != (Object)null) ? Player.gameplayCamera : null); Transform val2 = ResolveFirstPersonLeftHandTarget(); Transform val3 = ResolveFirstPersonRightHandTarget(); Transform cam; if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)val2.parent == (Object)null)) { _fpCalibrationLogged = true; cam = ((Component)val).transform; LogOne("L", val2); if ((Object)(object)val3 != (Object)null && (Object)(object)val3.parent != (Object)null) { LogOne("R", val3); } } void LogOne(string side, Transform target) { //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_0018: 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) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //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_0034: 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_003d: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: 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_011b: Unknown result type (might be due to invalid IL or missing references) Transform parent = target.parent; Vector3 val4 = cam.InverseTransformPoint(parent.position); Quaternion val5 = Quaternion.Inverse(cam.rotation) * parent.rotation; Vector3 eulerAngles = ((Quaternion)(ref val5)).eulerAngles; Vector3 localPosition = target.localPosition; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][FPCalib] {side} parentCamPos=({val4.x:F4}, {val4.y:F4}, {val4.z:F4}) " + $"parentCamEuler=({eulerAngles.x:F2}, {eulerAngles.y:F2}, {eulerAngles.z:F2}) parentLossy={parent.lossyScale.x:F4} " + $"camLossy={cam.lossyScale.x:F4} targetLocal=({localPosition.x:F4}, {localPosition.y:F4}, {localPosition.z:F4}).")); } } } internal static void CaptureInteractionBeginPresentation(PlayerControllerB player) { AbortInteractionBeginPresentation(null, "interaction-begin-replaced"); if ((Object)(object)player == (Object)null) { return; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val != (Object)null && val != player) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] Interaction-begin presentation capture rejected for a non-local player."); } } else { InteractionBeginPresentationState interactionBeginPresentationState = new InteractionBeginPresentationState { Player = player }; CaptureInteractionBeginRightArmPresentation(interactionBeginPresentationState); CaptureInteractionBeginHeadPresentation(interactionBeginPresentationState); _interactionBeginPresentation = ((interactionBeginPresentationState.RightShoulderCaptured || interactionBeginPresentationState.HeadCaptured) ? interactionBeginPresentationState : null); } } internal static void AbortInteractionBeginPresentation(PlayerControllerB player, string reason) { InteractionBeginPresentationState interactionBeginPresentation = _interactionBeginPresentation; if (interactionBeginPresentation != null && (!((Object)(object)player != (Object)null) || player == interactionBeginPresentation.Player)) { RestorePendingRightArmPresentation(interactionBeginPresentation, reason); RestorePendingHeadPresentation(interactionBeginPresentation, reason); _interactionBeginPresentation = null; } } private static void CaptureInteractionBeginRightArmPresentation(InteractionBeginPresentationState pending) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) Transform val = ResolveLocalFirstPersonRightShoulder(pending.Player); if ((Object)(object)val == (Object)null) { return; } pending.RightShoulder = val; pending.RightShoulderScale = val.localScale; pending.RightShoulderCaptured = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][RightArmHide] cached local arms-only shoulder scale: shoulder=" + GetTransformPath(val) + " verifiedUnderScavengerModelArmsOnly=True cachedLocalScale=" + FormatTraceVector(pending.RightShoulderScale) + ".")); } if (!Y4NGZPlayerAnimationBridge.HideRightFirstPersonArmDuringEnterAndExit) { return; } try { val.localScale = Vector3.one * 0.0001f; pending.RightShoulderHidden = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)($"[LethalCCTV][RightArmHide] frame={Time.frameCount} reason=interaction-begin " + "cachedLocalScale=" + FormatTraceVector(pending.RightShoulderScale) + " appliedLocalScale=" + FormatTraceVector(val.localScale) + ".")); } } catch (Exception ex) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV][RightArmHide] interaction-begin hide failed: " + ex.Message)); } } } private static void CaptureInteractionBeginHeadPresentation(InteractionBeginPresentationState pending) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) if (!Y4NGZPlayerAnimationBridge.UseInteractionsApiOperatorSession || !Y4NGZPlayerAnimationBridge.HideLocalPlayerHeadDuringApiSession) { return; } Transform val = ResolveLocalThirdPersonHeadBone(pending.Player); if ((Object)(object)val == (Object)null) { return; } Vector3 localScale = val.localScale; if (!TryResolveHeadPresentationBaseline(val, localScale, "interaction-begin", out var baselineLocalScale)) { return; } pending.HeadBone = val; pending.HeadScale = baselineLocalScale; pending.HeadCaptured = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][HeadHide] cached local third-person head scale: head=" + GetTransformPath(val) + " cachedLocalScale=" + FormatTraceVector(pending.HeadScale) + ".")); } try { val.localScale = Vector3.one * 0.0001f; pending.HeadHidden = true; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)($"[LethalCCTV][HeadHide] frame={Time.frameCount} reason=interaction-begin " + "cachedLocalScale=" + FormatTraceVector(pending.HeadScale) + " appliedLocalScale=" + FormatTraceVector(val.localScale) + ".")); } } catch (Exception ex) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV][HeadHide] interaction-begin hide failed: " + ex.Message)); } } } private static Transform ResolveLocalFirstPersonRightShoulder(PlayerControllerB player) { Transform val = (((Object)(object)player != (Object)null) ? player.localArmsTransform : null); if ((Object)(object)val == (Object)null && (Object)(object)player?.playerBodyAnimator != (Object)null) { val = ((Component)player.playerBodyAnimator).transform.Find("ScavengerModelArmsOnly"); } Transform val2 = (((Object)(object)val != (Object)null) ? (val.Find("metarig/spine.003/shoulder.R") ?? FindChildRecursive(val, "shoulder.R")) : null); bool flag = (Object)(object)val2 != (Object)null && HasAncestorOrSelfNamed(val2, "ScavengerModelArmsOnly"); bool flag2 = (Object)(object)val2 != (Object)null && string.Equals(((Object)val2).name, "shoulder.R", StringComparison.Ordinal); if (flag && flag2) { return val2; } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][RightArmHide] shoulder.R interaction-begin cache rejected: shoulder=" + GetTransformPath(val2) + " armsOnlyRoot=" + GetTransformPath(val) + " " + $"verifiedUnderScavengerModelArmsOnly={flag} " + $"verifiedName={flag2}.")); } return null; } private static Transform ResolveLocalThirdPersonHeadBone(PlayerControllerB player) { Transform transform = (((Object)(object)player?.playerBodyAnimator != (Object)null) ? ((Component)player.playerBodyAnimator).transform : null); Transform transform2 = (((Object)(object)player != (Object)null) ? player.localArmsTransform : null); Transform transform3 = (((Object)(object)player?.thisPlayerModel != (Object)null) ? ((Component)player.thisPlayerModel).transform : null); Transform val = FindAncestorOrSelfNamed(transform, "ScavengerModel") ?? FindAncestorOrSelfNamed(transform2, "ScavengerModel") ?? FindAncestorOrSelfNamed(transform3, "ScavengerModel") ?? FindDirectChild(((Object)(object)player != (Object)null) ? ((Component)player).transform : null, "ScavengerModel"); if ((Object)(object)val == (Object)null || HasAncestorOrSelfNamed(val, "ScavengerModelArmsOnly")) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV][HeadHide] local third-person ScavengerModel root was not found."); } return null; } Transform val2 = val; for (int i = 0; i < LocalThirdPersonHeadSpineChain.Length; i++) { string text = LocalThirdPersonHeadSpineChain[i]; val2 = FindDirectChild(val2, text); if ((Object)(object)val2 == (Object)null) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][HeadHide] local third-person spine walk failed: " + $"root={GetTransformPath(val)} missingNode={text} chainIndex={i}.")); } return null; } } if (!val2.IsChildOf(val) || HasAncestorOrSelfNamed(val2, "ScavengerModelArmsOnly")) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV][HeadHide] resolved head failed local third-person verification: head=" + GetTransformPath(val2) + " root=" + GetTransformPath(val) + ".")); } return null; } ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogInfo((object)("[LethalCCTV][HeadHide] resolved local third-person head bone: path=" + GetTransformPath(val2) + " " + $"matchesPlayerGlobalHead={val2 == player.playerGlobalHead}.")); } return val2; } private static Transform FindDirectChild(Transform parent, string name) { if ((Object)(object)parent == (Object)null) { return null; } for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if ((Object)(object)child != (Object)null && string.Equals(((Object)child).name, name, StringComparison.Ordinal)) { return child; } } return null; } private static Transform FindAncestorOrSelfNamed(Transform transform, string name) { Transform val = transform; while ((Object)(object)val != (Object)null) { if (string.Equals(((Object)val).name, name, StringComparison.OrdinalIgnoreCase)) { return val; } val = val.parent; } return null; } private static bool HasAncestorOrSelfNamed(Transform transform, string name) { Transform val = transform; while ((Object)(object)val != (Object)null) { if (string.Equals(((Object)val).name, name, StringComparison.Ordinal)) { return true; } val = val.parent; } return false; } private static void RestorePendingRightArmPresentation(InteractionBeginPresentationState pending, string reason) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) if (!pending.RightShoulderCaptured || (Object)(object)pending.RightShoulder == (Object)null) { return; } try { pending.RightShoulder.localScale = pending.RightShoulderScale; if (pending.RightShoulderHidden) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][RightArmHide] frame={Time.frameCount} reason={reason} " + "cachedLocalScale=" + FormatTraceVector(pending.RightShoulderScale) + " appliedLocalScale=" + FormatTraceVector(pending.RightShoulder.localScale) + ".")); } } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][RightArmHide] pending scale restore failed reason=" + reason + ": " + ex.Message)); } } } private static void RestorePendingHeadPresentation(InteractionBeginPresentationState pending, string reason) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) if (!pending.HeadCaptured || (Object)(object)pending.HeadBone == (Object)null) { return; } try { pending.HeadBone.localScale = pending.HeadScale; if (pending.HeadHidden) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][HeadHide] frame={Time.frameCount} reason={reason} " + "cachedLocalScale=" + FormatTraceVector(pending.HeadScale) + " appliedLocalScale=" + FormatTraceVector(pending.HeadBone.localScale) + ".")); } } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][HeadHide] pending scale restore failed reason=" + reason + ": " + ex.Message)); } } } private static void RestorePendingHeadPresentationForApiFallback(PlayerControllerB player) { RestorePendingHeadPresentationForPlayer(player, "api-fallback"); } private static void RestorePendingRightArmPresentationForApiFallback(PlayerControllerB player) { RestorePendingRightArmPresentationForPlayer(player, "api-fallback"); } private static void RestorePendingRightArmPresentationForPlayer(PlayerControllerB player, string reason) { InteractionBeginPresentationState interactionBeginPresentation = _interactionBeginPresentation; if (interactionBeginPresentation != null && interactionBeginPresentation.Player == player && interactionBeginPresentation.RightShoulderCaptured) { RestorePendingRightArmPresentation(interactionBeginPresentation, reason); ClearPendingRightArmPresentation(interactionBeginPresentation); } } private static void ClearPendingRightArmPresentation(InteractionBeginPresentationState pending) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) pending.RightShoulder = null; pending.RightShoulderScale = Vector3.one; pending.RightShoulderCaptured = false; pending.RightShoulderHidden = false; ClearConsumedInteractionBeginPresentation(pending); } private static void RestorePendingHeadPresentationForPlayer(PlayerControllerB player, string reason) { InteractionBeginPresentationState interactionBeginPresentation = _interactionBeginPresentation; if (interactionBeginPresentation != null && interactionBeginPresentation.Player == player && interactionBeginPresentation.HeadCaptured) { RestorePendingHeadPresentation(interactionBeginPresentation, reason); ClearPendingHeadPresentation(interactionBeginPresentation); } } private static void ClearPendingHeadPresentation(InteractionBeginPresentationState pending) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) pending.HeadBone = null; pending.HeadScale = Vector3.one; pending.HeadCaptured = false; pending.HeadHidden = false; ClearConsumedInteractionBeginPresentation(pending); } private bool TryAdoptInteractionBeginRightArmPresentation() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) InteractionBeginPresentationState interactionBeginPresentation = _interactionBeginPresentation; if (!_isLocal || interactionBeginPresentation == null || interactionBeginPresentation.Player != Player || !interactionBeginPresentation.RightShoulderCaptured || (Object)(object)interactionBeginPresentation.RightShoulder == (Object)null) { return false; } _rightArmPresentationShoulder = interactionBeginPresentation.RightShoulder; _rightArmPresentationCachedLocalScale = interactionBeginPresentation.RightShoulderScale; _rightArmPresentationScaleCaptured = true; _rightArmPresentationHidden = interactionBeginPresentation.RightShoulderHidden; interactionBeginPresentation.RightShoulder = null; interactionBeginPresentation.RightShoulderScale = Vector3.one; interactionBeginPresentation.RightShoulderCaptured = false; interactionBeginPresentation.RightShoulderHidden = false; ClearConsumedInteractionBeginPresentation(interactionBeginPresentation); return true; } private bool TryAdoptInteractionBeginHeadPresentation() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) InteractionBeginPresentationState interactionBeginPresentation = _interactionBeginPresentation; if (!_isLocal || interactionBeginPresentation == null || interactionBeginPresentation.Player != Player || !interactionBeginPresentation.HeadCaptured || (Object)(object)interactionBeginPresentation.HeadBone == (Object)null) { return false; } _headPresentationBone = interactionBeginPresentation.HeadBone; _headPresentationCachedLocalScale = interactionBeginPresentation.HeadScale; _headPresentationScaleCaptured = true; _headPresentationHidden = interactionBeginPresentation.HeadHidden; ClearPendingHeadPresentation(interactionBeginPresentation); return true; } private static bool TryResolveHeadPresentationBaseline(Transform head, Vector3 capturedLocalScale, string reason, out Vector3 baselineLocalScale) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_0015: 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_0032: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //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) baselineLocalScale = capturedLocalScale; if (!IsNearlyZeroPresentationScale(capturedLocalScale)) { _lastKnownHeadPresentationBone = head; _lastKnownHeadPresentationLocalScale = capturedLocalScale; _lastKnownHeadPresentationScaleValid = true; return true; } bool flag = _lastKnownHeadPresentationScaleValid && _lastKnownHeadPresentationBone == head && !IsNearlyZeroPresentationScale(_lastKnownHeadPresentationLocalScale); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV][HeadHide] capture-suspect reason=" + reason + " head=" + GetTransformPath(head) + " capturedLocalScale=" + FormatTraceVector(capturedLocalScale) + " " + $"previousNonZeroAvailable={flag} " + "previousLocalScale=" + FormatTraceVector(_lastKnownHeadPresentationLocalScale) + ".")); } if (!flag) { return false; } baselineLocalScale = _lastKnownHeadPresentationLocalScale; return true; } private static bool IsNearlyZeroPresentationScale(Vector3 scale) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (Mathf.Abs(scale.x) <= 0.001f && Mathf.Abs(scale.y) <= 0.001f) { return Mathf.Abs(scale.z) <= 0.001f; } return false; } private Transform LiftRightArmPresentationHideForApiBoundary(string reason) { //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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_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) Transform val = null; Vector3 val2 = Vector3.one; if (_rightArmPresentationHidden && (Object)(object)_rightArmPresentationShoulder != (Object)null) { val = _rightArmPresentationShoulder; val2 = _rightArmPresentationCachedLocalScale; } else { InteractionBeginPresentationState interactionBeginPresentation = _interactionBeginPresentation; if (interactionBeginPresentation != null && interactionBeginPresentation.RightShoulderHidden && (Object)(object)interactionBeginPresentation.RightShoulder != (Object)null && ((Object)(object)Player == (Object)null || interactionBeginPresentation.Player == Player)) { val = interactionBeginPresentation.RightShoulder; val2 = interactionBeginPresentation.RightShoulderScale; } } if ((Object)(object)val == (Object)null) { return null; } try { val.localScale = val2; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][RightArmHide] frame={Time.frameCount} reason={reason} " + "cachedLocalScale=" + FormatTraceVector(val2) + " appliedLocalScale=" + FormatTraceVector(val.localScale) + ".")); } return val; } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][RightArmHide] api boundary lift failed reason=" + reason + ": " + ex.Message)); } return null; } } private void ReapplyRightArmPresentationHideForApiBoundary(Transform shoulder, string reason) { //IL_000c: 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_0046: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)shoulder == (Object)null) { return; } try { shoulder.localScale = Vector3.one * 0.0001f; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][RightArmHide] frame={Time.frameCount} reason={reason} " + "appliedLocalScale=" + FormatTraceVector(shoulder.localScale) + ".")); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][RightArmHide] api boundary re-hide failed reason=" + reason + ": " + ex.Message)); } } } private static void ClearConsumedInteractionBeginPresentation(InteractionBeginPresentationState pending) { if (_interactionBeginPresentation == pending && !pending.RightShoulderCaptured && !pending.HeadCaptured) { _interactionBeginPresentation = null; } } private void EvaluateLegacyFirstPersonArmRig() { if (Y4NGZPlayerAnimationBridge.UseManualFirstPersonArmIk) { return; } Component[] array = ResolveFirstPersonRightHandRigBuilders(); int num = 0; while (array != null && num < array.Length) { Component val = array[num]; if (!((Object)(object)val == (Object)null)) { try { Type type = ((object)val).GetType(); type.GetMethod("SyncLayers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null)?.Invoke(val, null); MethodInfo method = type.GetMethod("Evaluate", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(float) }, null); if (method != null) { method.Invoke(val, new object[1] { 0f }); _handTraceRigEvaluateCount++; } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Legacy first-person arm rig evaluate failed: " + ex.Message)); } } } num++; } ReassertFirstPersonArmsPresentation(); } private void RebuildArmsRigAfterControllerSwap(string reason) { RebuildArmsRigComponents(ResolveFirstPersonRightHandRigBuilders(), reason); } private static void RebuildArmsRigComponents(Component[] rigBuilders, string reason) { if (rigBuilders == null || rigBuilders.Length == 0) { return; } foreach (Component val in rigBuilders) { if ((Object)(object)val == (Object)null) { continue; } try { MethodInfo method = ((object)val).GetType().GetMethod("Build", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); object obj = ((method != null) ? method.Invoke(val, null) : null); bool? graphPlaying; string text = DescribeRigGraph(val, out graphPlaying); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] Rig graph rebuilt after controller swap (" + reason + "): " + ((object)val).GetType().Name + "@" + GetTransformPath(val.transform) + " behaviourEnabled=" + DescribeBehaviourEnabled(val) + " build=" + ((method == null) ? "" : ((obj is bool flag) ? flag.ToString() : "void")) + " graph=" + text + ".")); } if (graphPlaying == false) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV][RIG GRAPH NOT PLAYING] Rebuild (" + reason + ") returned graph=" + text + " for " + ((object)val).GetType().Name + "@" + GetTransformPath(val.transform) + ". The graph cannot produce IK writes.")); } } } catch (Exception ex) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV] Rig graph rebuild failed after controller swap (" + reason + "): " + ex.Message)); } } } } private static string DescribeBehaviourEnabled(Component component) { Behaviour val = (Behaviour)(object)((component is Behaviour) ? component : null); if (val == null) { return ""; } return val.enabled.ToString(); } private static string DescribeRigGraph(Component rigBuilder) { bool? graphPlaying; return DescribeRigGraph(rigBuilder, out graphPlaying); } private static string DescribeRigGraph(Component rigBuilder, out bool? graphPlaying) { graphPlaying = null; try { object obj = ReadReflectedMemberNoByRef(rigBuilder, "graph"); if (obj == null) { return ""; } MethodInfo? method = obj.GetType().GetMethod("IsValid", Type.EmptyTypes); MethodInfo method2 = obj.GetType().GetMethod("IsPlaying", Type.EmptyTypes); object obj2 = method?.Invoke(obj, null); object obj3 = method2?.Invoke(obj, null); if (obj3 is bool value) { graphPlaying = value; } string obj4 = ((!(obj2 is bool)) ? "valid:" : (((bool)obj2) ? "valid" : "invalid")); string text = ((!(obj3 is bool)) ? "playing:" : (((bool)obj3) ? "playing" : "NOT-PLAYING")); return obj4 + "/" + text; } catch { return ""; } } private Component[] ResolveFirstPersonRightHandRigBuilders() { if (_firstPersonRightHandRigBuildersResolved) { return _firstPersonRightHandRigBuilders; } _firstPersonRightHandRigBuildersResolved = true; List list = new List(4); try { Transform val = (((Object)(object)_animator != (Object)null) ? ((Component)_animator).transform : null); Component[] array = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentsInChildren(true) : Array.Empty()); foreach (Component val2 in array) { if (!((Object)(object)val2 == (Object)null)) { Type type = ((object)val2).GetType(); string a = ((type != null) ? type.Name : string.Empty); string a2 = ((type != null) ? type.FullName : string.Empty); if (string.Equals(a, "RigBuilder", StringComparison.Ordinal) || string.Equals(a2, "UnityEngine.Animations.Rigging.RigBuilder", StringComparison.Ordinal)) { list.Add(val2); } } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] First-person right-hand rig builder search failed: " + ex.Message)); } } _firstPersonRightHandRigBuilders = list.ToArray(); if (_firstPersonRightHandRigBuilders.Length != 0) { string text = string.Empty; for (int j = 0; j < _firstPersonRightHandRigBuilders.Length; j++) { Component val3 = _firstPersonRightHandRigBuilders[j]; if (!((Object)(object)val3 == (Object)null)) { if (!string.IsNullOrEmpty(text)) { text += "; "; } text = text + ((object)val3).GetType().Name + "@" + GetTransformPath(val3.transform); } } ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] First-person right-hand rig builders resolved: " + text)); } } else if (!_firstPersonRightHandRigBuilderMissingLogged) { _firstPersonRightHandRigBuilderMissingLogged = true; ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)"[LethalCCTV] First-person right-hand rig builder not found; edit mode will move the target but may not visibly update the hand until the rig evaluates."); } } return _firstPersonRightHandRigBuilders; } private static Transform FindChildRecursive(Transform root, string name) { if ((Object)(object)root == (Object)null || string.IsNullOrWhiteSpace(name)) { return null; } if (string.Equals(((Object)root).name, name, StringComparison.Ordinal)) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindChildRecursive(root.GetChild(i), name); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static string GetTransformPath(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++ < 28) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private bool ShouldShowFirstPersonArmsLayer() { if (_isLocal && Y4NGZPlayerAnimationBridge.UseAuthoredLegacyOperatorPresentation) { return !MonitorFocus.IsStationThirdPersonDebugViewActive; } return false; } private bool ShouldSolveFirstPersonArms() { if (_isLocal && (_interactionsApiMode || Y4NGZPlayerAnimationBridge.UseAuthoredLegacyOperatorPresentation)) { return !MonitorFocus.IsStationThirdPersonDebugViewActive; } return false; } private void SetLayerWeight(int layerIndex, float weight) { if ((Object)(object)_animator == (Object)null || layerIndex < 0 || layerIndex >= _animator.layerCount) { return; } try { _animator.SetLayerWeight(layerIndex, Mathf.Clamp01(weight)); } catch { } } private void SaveAnimatorState(Animator animator) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)animator == (Object)null)) { AnimatorControllerParameter[] parameters = animator.parameters; _savedParameters = new SavedAnimatorParameter[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { AnimatorControllerParameter parameter = parameters[i]; _savedParameters[i] = new SavedAnimatorParameter(animator, parameter); } int num = Mathf.Max(0, animator.layerCount); _savedStates = new SavedAnimatorState[num]; for (int j = 0; j < num; j++) { AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(j); _savedStates[j] = new SavedAnimatorState(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash, ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime); } } } private void RestoreAnimatorState(Animator animator) { if ((Object)(object)animator == (Object)null) { return; } CacheParameters(animator); for (int i = 0; i < _savedParameters.Length; i++) { _savedParameters[i].Restore(animator, _parameterTypes); } int num = Mathf.Min(animator.layerCount, _savedStates.Length); for (int j = 0; j < num; j++) { SavedAnimatorState savedAnimatorState = _savedStates[j]; if (savedAnimatorState.StateHash != 0 && animator.HasState(j, savedAnimatorState.StateHash)) { animator.Play(savedAnimatorState.StateHash, j, savedAnimatorState.NormalizedTime); } } animator.Update(0f); } private static string FormatPlayerForLog(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return ""; } string text = (string.IsNullOrEmpty(player.playerUsername) ? "" : player.playerUsername); return "#" + player.playerClientId + " '" + text + "'"; } private void CacheParameters(Animator animator) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) _parameterTypes.Clear(); if (!((Object)(object)animator == (Object)null)) { AnimatorControllerParameter[] parameters = animator.parameters; foreach (AnimatorControllerParameter val in parameters) { _parameterTypes[val.nameHash] = val.type; } } } private void SetBool(int hash, bool value) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 if ((Object)(object)_animator != (Object)null && _parameterTypes.TryGetValue(hash, out var value2) && (int)value2 == 4) { _animator.SetBool(hash, value); } } private void SetInt(int hash, int value) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 if ((Object)(object)_animator != (Object)null && _parameterTypes.TryGetValue(hash, out var value2) && (int)value2 == 3) { _animator.SetInteger(hash, value); } } private void SetFloat(int hash, float value) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 if ((Object)(object)_animator != (Object)null && _parameterTypes.TryGetValue(hash, out var value2) && (int)value2 == 1) { _animator.SetFloat(hash, value); } } private void FireTrigger(int hash) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 if ((Object)(object)_animator != (Object)null && _parameterTypes.TryGetValue(hash, out var value) && (int)value == 9) { _animator.ResetTrigger(hash); _animator.SetTrigger(hash); } } } internal static class PaneHighlight { private static readonly Color ACTIVE_TINT = new Color(0.06f, 0.62f, 0.2f, 0.9f); private static readonly Color INACTIVE_OVERLAY_TINT = new Color(0.025f, 0.12f, 0.07f, 0.24f); private const string HDRP_UNLIT_COLOR_PROPERTY = "_UnlitColor"; internal static void SetActive(int activeSlot) { ApplyToOverlay(activeSlot); ApplyToWall(-1); MonitorFocus.UpdateActiveSlotLabel(activeSlot); } internal static void ClearAll() { ApplyToOverlay(-1); ApplyToWall(-1); MonitorFocus.UpdateActiveSlotLabel(-1); } private static void ApplyToOverlay(int activeSlot) { //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_0038: 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_0028: 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) Image[] overlayOutlines = MonitorFocus.OverlayOutlines; if (overlayOutlines == null) { return; } for (int i = 0; i < overlayOutlines.Length; i++) { if (!((Object)(object)overlayOutlines[i] == (Object)null)) { Color color = ((activeSlot < 0) ? Color.clear : ((i == activeSlot) ? ACTIVE_TINT : INACTIVE_OVERLAY_TINT)); ((Graphic)overlayOutlines[i]).color = Color.clear; MonitorFocus.SetOverlayFrameTint(i, color); } } } private static void ApplyToWall(int activeSlot) { //IL_002c: 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) Material[] quadOutlineMaterials = QuadMonitor.QuadOutlineMaterials; if (quadOutlineMaterials == null) { return; } for (int i = 0; i < quadOutlineMaterials.Length; i++) { if (!((Object)(object)quadOutlineMaterials[i] == (Object)null)) { quadOutlineMaterials[i].SetColor("_UnlitColor", (i == activeSlot) ? ACTIVE_TINT : Color.clear); } } } } internal static class QuadMonitor { private const float QUADRANT_WIDTH_M = 0.33f; private const float QUADRANT_HEIGHT_M = 0.25f; private const float MONITOR_ROOT_SCALE = 0.8f; private const float MONITOR_FORWARD_OFFSET_M = -0.14f; private const float LIVE_SCREEN_Z_M = -0.014f; private const float SCREEN_BACKING_Z_M = -0.01f; private const float FOCUS_SCREEN_Z_M = -0.024f; private const float QUADRANT_Z_OFFSET_STEP = 0.001f; private const float FOCUS_OVERLAY_Z_M = -0.0040000007f; private const float FOCUS_CHROME_Z_M = -4.656613E-10f; private const float FOCUS_CHROME_TEXT_Z_M = 0.0029999996f; private const float FOCUS_CHROME_LAYOUT_WIDTH_PX = 960f; private const float FOCUS_CHROME_LAYOUT_HEIGHT_PX = 720f; private const float FOCUS_VIEW_CAMERA_X_M = -0.31350002f; private const float FOCUS_VIEW_CAMERA_Y_M = 0.05f; private const float FOCUS_VIEW_CAMERA_Z_M = -0.78f; private const int DEFAULT_RT_WIDTH = 512; private const int MIN_RT_WIDTH = 64; private const int MAX_RT_WIDTH = 1024; private const int EMPTY_RT_SIZE = 256; private const float PAGE_INDICATOR_MARGIN_M = 0.035f; private const float PAGE_INDICATOR_FONT_SIZE = 0.034f; private const float LABEL_INSET_X_M = 0.018f; private const float LABEL_INSET_Y_M = 0.018f; private const float LABEL_FORWARD_Z_OFFSET_M = 0.005f; private const float LABEL_FONT_SIZE = 0.032f; private const float LABEL_BOX_WIDTH_M = 0.12f; private const float LABEL_BOX_HEIGHT_M = 0.035f; private static Texture[] _slotCurrentDisplayTex = (Texture[])(object)new Texture[4]; private const float OUTLINE_BORDER_M = 0.012f; private const float OUTLINE_Z_OFFSET_M = 0.0005f; private static readonly string[] DisplayTexturePropertyNames = new string[4] { "_UnlitColorMap", "_BaseColorMap", "_BaseMap", "_MainTex" }; private static readonly string[] ClearTexturePropertyNames = new string[1] { "_EmissiveColorMap" }; private static Mesh _cachedQuadMesh; private static RenderTexture _emptySlotBlackRT; private static TextMeshPro _pageIndicator; private static TextMesh _pageIndicatorLegacy; private static TextMeshPro[] _cameraLabels; private static GameObject _screenBacking; private static GameObject _focusScreen; private static GameObject _focusChromeRoot; private static Material _screenBackingMaterial; private static Material _focusScreenMaterial; private static readonly List _focusChromeMaterials = new List(8); private static bool _focusScreenLogged; private static bool _physicalMonitorVisualsHidden; private static Transform _runtimeFocusViewAnchor; internal static RenderTexture[] QuadRTs { get; private set; } internal static RenderTexture[] RawRTs { get; private set; } internal static GameObject MonitorRoot { get; private set; } internal static Material[] QuadMaterials { get; private set; } internal static Material[] QuadOutlineMaterials { get; private set; } internal static Transform FocusViewAnchor { get { if (!((Object)(object)CCTVOperatorStation.FocusViewAnchor != (Object)null)) { if (!((Object)(object)_runtimeFocusViewAnchor != (Object)null)) { return FindChildRecursive(((Object)(object)MonitorRoot != (Object)null) ? MonitorRoot.transform : null, "CCTVFocusViewAnchor"); } return _runtimeFocusViewAnchor; } return CCTVOperatorStation.FocusViewAnchor; } } private static void CreateRuntimeInteractionAnchors(Transform parent) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_005b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)parent == (Object)null)) { _runtimeFocusViewAnchor = CreateRuntimeAnchor(parent, "CCTVRuntimeFocusViewAnchor", new Vector3(-0.31350002f, 0.05f, -0.78f), Quaternion.identity); SurveillanceBootstrap.Log.LogInfo((object)($"[LethalCCTV] Runtime CCTV focus anchor created: focusLocal={_runtimeFocusViewAnchor.localPosition} " + $"focusEuler={_runtimeFocusViewAnchor.localEulerAngles}.")); } } private static Transform CreateRuntimeAnchor(Transform parent, string name, Vector3 localPosition, Quaternion localRotation) { //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_0013: 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_001f: 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_002b: 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) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localPosition = localPosition; val.transform.localRotation = localRotation; val.transform.localScale = Vector3.one; return val.transform; } private static Material CreateQuadrantOutline(Transform parent, int slotIndex, Mesh quadMesh) { //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) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00fb: Unknown result type (might be due to invalid IL or missing references) float num = ((slotIndex % 2 == 0) ? (-0.165f) : 0.165f); float num2 = ((slotIndex < 2) ? 0.125f : (-0.125f)); float num3 = -0.014f + (float)slotIndex * 0.001f - 0.0005f; GameObject val = new GameObject($"Quadrant_{slotIndex}_Outline"); val.transform.SetParent(parent, false); val.transform.localPosition = new Vector3(num, num2, num3); val.transform.localRotation = Quaternion.identity; val.transform.localScale = new Vector3(0.354f, 0.274f, 1f); val.AddComponent().sharedMesh = quadMesh; MeshRenderer obj = val.AddComponent(); ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).lightProbeUsage = (LightProbeUsage)0; ((Renderer)obj).reflectionProbeUsage = (ReflectionProbeUsage)0; Material val2 = Object.Instantiate(VanillaShaderInfo.SourceMaterial); ((Object)val2).name = $"LethalCCTV_QuadOutline_{slotIndex}"; BindDisplayTexture(val2, (Texture)(object)Texture2D.whiteTexture); val2.SetColor("_UnlitColor", Color.clear); val2.SetFloat("_DoubleSidedEnable", 0f); val2.SetFloat("_CullMode", 2f); val2.DisableKeyword("_DOUBLESIDED_ON"); HDMaterial.ValidateMaterial(val2); ((Renderer)obj).sharedMaterial = val2; return val2; } private static TextMeshPro CreateCameraLabel(Transform parent, int slotIndex, TMP_FontAsset fontAsset) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_008b: 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_009b: 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_00ab: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) float num = ((slotIndex % 2 == 0) ? (-0.165f) : 0.165f); float num2 = ((slotIndex < 2) ? 0.125f : (-0.125f)); float num3 = -0.014f + (float)slotIndex * 0.001f; float num4 = num - 0.165f + 0.018f; float num5 = num2 + 0.125f - 0.018f; float num6 = num3 + 0.005f; GameObject val = new GameObject($"CameraLabel_{slotIndex}"); val.transform.SetParent(parent, false); val.transform.localPosition = new Vector3(num4, num5, num6); val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; TextMeshPro val2 = val.AddComponent(); ((TMP_Text)val2).font = fontAsset; ((TMP_Text)val2).fontSize = 0.032f; ((TMP_Text)val2).fontStyle = (FontStyles)1; ((TMP_Text)val2).alignment = (TextAlignmentOptions)257; ((Graphic)val2).color = Color.white; ((TMP_Text)val2).text = "CAM_--"; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; RectTransform component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.sizeDelta = new Vector2(0.12f, 0.035f); component.pivot = new Vector2(0f, 1f); } if ((Object)(object)((TMP_Text)val2).fontMaterial != (Object)null) { ((TMP_Text)val2).fontMaterial.SetFloat("_CullMode", 0f); ((TMP_Text)val2).fontMaterial.EnableKeyword("_FACE_CULLING_OFF"); } ((TMP_Text)val2).ForceMeshUpdate(false, false); return val2; } private static void CreatePageIndicator(Transform parent) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0166: 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_00c4: Unknown result type (might be due to invalid IL or missing references) Vector3 localPosition = default(Vector3); ((Vector3)(ref localPosition))..ctor(0f, -0.285f, 0f); GameObject val = new GameObject("PageIndicator"); val.transform.SetParent(parent, false); val.transform.localPosition = localPosition; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; TMP_FontAsset val2 = ResolveTMPFontAsset(); if ((Object)(object)val2 != (Object)null) { TextMeshPro val3 = val.AddComponent(); ((TMP_Text)val3).font = val2; ((TMP_Text)val3).fontSize = 0.034f; ((TMP_Text)val3).alignment = (TextAlignmentOptions)514; ((Graphic)val3).color = Color.white; ((TMP_Text)val3).text = "Page 1 / 1"; RectTransform component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.sizeDelta = new Vector2(0.66f, 0.3f); } if ((Object)(object)((TMP_Text)val3).fontMaterial != (Object)null) { ((TMP_Text)val3).fontMaterial.SetFloat("_CullMode", 0f); } _pageIndicator = val3; SurveillanceBootstrap.Log.LogInfo((object)$"[LethalCCTV] Page indicator created (TextMeshPro 3D, font='{((Object)val2).name}', fontSize={0.034f})."); return; } SurveillanceBootstrap.Log.LogWarning((object)"[LethalCCTV] TMP_FontAsset chain exhausted — falling back to legacy TextMesh."); TextMesh val4 = val.AddComponent(); val4.text = "Page 1 / 1"; val4.anchor = (TextAnchor)4; val4.alignment = (TextAlignment)1; val4.characterSize = 0.034f; val4.fontSize = 32; val4.color = Color.white; Font builtinResource = Resources.GetBuiltinResource("Arial.ttf"); if ((Object)(object)builtinResource != (Object)null) { val4.font = builtinResource; MeshRenderer component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Renderer)component2).sharedMaterial = builtinResource.material; } } _pageIndicatorLegacy = val4; SurveillanceBootstrap.Log.LogInfo((object)"[LethalCCTV] Page indicator created (legacy TextMesh fallback)."); } private static void CreateFocusChromeOverlay(Transform parent, Mesh quadMesh) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_04c5: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) _focusChromeRoot = new GameObject("PhysicalFocusChrome"); _focusChromeRoot.transform.SetParent(parent, false); _focusChromeRoot.transform.localPosition = Vector3.zero; _focusChromeRoot.transform.localRotation = Quaternion.identity; _focusChromeRoot.transform.localScale = Vector3.one; Material material = CreateFocusChromeMaterial("LethalCCTV_FocusChromeRule", new Color(0.025f, 0.58f, 0.22f, 1f)); Material material2 = CreateFocusChromeMaterial("LethalCCTV_FocusChromeRuleDim", new Color(0.014f, 0.22f, 0.12f, 1f)); CreateFocusChromeRule(_focusChromeRoot.transform, "ChromeTopRule", new Vector2(0f, 345f), new Vector2(944f, 2f), material2, quadMesh); CreateFocusChromeRule(_focusChromeRoot.transform, "ChromeBottomRule", new Vector2(0f, -345f), new Vector2(944f, 2f), material2, quadMesh); CreateFocusChromeRule(_focusChromeRoot.transform, "ChromeLeftRule", new Vector2(-472f, 0f), new Vector2(2f, 690f), material2, quadMesh); CreateFocusChromeRule(_focusChromeRoot.transform, "ChromeRightRule", new Vector2(472f, 0f), new Vector2(2f, 690f), material2, quadMesh); float num = -120f; CreateFocusChromeRule(_focusChromeRoot.transform, "ChromeMainDivider", new Vector2(0f, num), new Vector2(944f, 3f), material, quadMesh); CreateFocusChromeRule(_focusChromeRoot.transform, "ChromeBottomColumnDivider", new Vector2(56f, -248f), new Vector2(3f, 210f), material, quadMesh); CreateFocusChromeRule(_focusChromeRoot.transform, "ChromeRightSectionDivider", new Vector2(267f, -226f), new Vector2(392f, 2f), material2, quadMesh); CreateFocusChromeRule(_focusChromeRoot.transform, "ChromeControlsDivider", new Vector2(267f, -166f), new Vector2(3f, 92f), material2, quadMesh); CreateFocusChromeCorner(_focusChromeRoot.transform, "ChromeCameraCornerTL", new Vector2(-456f, 254f), left: true, top: true, material, quadMesh); CreateFocusChromeCorner(_focusChromeRoot.transform, "ChromeCameraCornerTR", new Vector2(456f, 254f), left: false, top: true, material, quadMesh); CreateFocusChromeCorner(_focusChromeRoot.transform, "ChromeCameraCornerBL", new Vector2(-456f, -104f), left: true, top: false, material, quadMesh); CreateFocusChromeCorner(_focusChromeRoot.transform, "ChromeCameraCornerBR", new Vector2(456f, -104f), left: false, top: false, material, quadMesh); TMP_FontAsset val = ResolveTMPFontAsset(); if ((Object)(object)val != (Object)null) { CreateFocusChromeText(_focusChromeRoot.transform, "ChromeTitle", "LETHALCCTV SECURITY FEED", new Vector2(-438f, 326f), new Vector2(360f, 26f), 0.0095f, new Color(0.16f, 1f, 0.32f, 1f), (TextAlignmentOptions)257, val); CreateFocusChromeText(_focusChromeRoot.transform, "ChromePage", "PAGE", new Vector2(382f, 326f), new Vector2(70f, 22f), 0.0066f, new Color(0.72f, 0.75f, 0.72f, 1f), (TextAlignmentOptions)260, val); CreateFocusChromeText(_focusChromeRoot.transform, "ChromeRadar", "RADAR MAP", new Vector2(-438f, -112f), new Vector2(130f, 22f), 0.0069f, new Color(1f, 0.6f, 0.1f, 1f), (TextAlignmentOptions)257, val); CreateFocusChromeText(_focusChromeRoot.transform, "ChromeInterior", "INTERIOR", new Vector2(92f, -112f), new Vector2(100f, 22f), 0.0062f, Color.white, (TextAlignmentOptions)257, val); CreateFocusChromeText(_focusChromeRoot.transform, "ChromeControls", "CONTROLS", new Vector2(274f, -112f), new Vector2(110f, 22f), 0.0062f, new Color(0.57f, 0.82f, 0.64f, 1f), (TextAlignmentOptions)257, val); CreateFocusChromeText(_focusChromeRoot.transform, "ChromeSignal", "SIGNAL LOG", new Vector2(92f, -226f), new Vector2(140f, 22f), 0.0064f, new Color(1f, 0.6f, 0.1f, 1f), (TextAlignmentOptions)257, val); } else { SurveillanceBootstrap.Log.LogWarning((object)"[LethalCCTV] Focus chrome labels skipped: TMP font unavailable."); } _focusChromeRoot.SetActive(false); SurveillanceBootstrap.Log.LogInfo((object)"[LethalCCTV] Physical focus chrome overlay created."); } private static void CreateFocusChromeCorner(Transform parent, string name, Vector2 cornerPx, bool left, bool top, Material material, Mesh quadMesh) { //IL_002d: 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_0041: 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_006a: 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_007e: 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) float num = (left ? 1f : (-1f)); float num2 = (top ? (-1f) : 1f); CreateFocusChromeRule(parent, name + "_H", new Vector2(cornerPx.x + num * 22f, cornerPx.y), new Vector2(44f, 2.4f), material, quadMesh); CreateFocusChromeRule(parent, name + "_V", new Vector2(cornerPx.x, cornerPx.y + num2 * 22f), new Vector2(2.4f, 44f), material, quadMesh); } private static void CreateFocusChromeRule(Transform parent, string name, Vector2 centerPx, Vector2 sizePx, Material material, Mesh quadMesh) { //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_0028: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_0059: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null) && !((Object)(object)quadMesh == (Object)null)) { GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localPosition = FocusChromePixelToLocal(centerPx, -4.656613E-10f); val.transform.localRotation = Quaternion.identity; val.transform.localScale = new Vector3(Mathf.Max(0.0006f, sizePx.x / 960f * 0.33f * 2f), Mathf.Max(0.0006f, sizePx.y / 720f * 0.25f * 2f), 1f); val.AddComponent().sharedMesh = quadMesh; MeshRenderer obj = val.AddComponent(); ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).lightProbeUsage = (LightProbeUsage)0; ((Renderer)obj).reflectionProbeUsage = (ReflectionProbeUsage)0; ((Renderer)obj).sharedMaterial = material; } } private static void CreateFocusChromeText(Transform parent, string name, string text, Vector2 topLeftPx, Vector2 sizePx, float fontSize, Color color, TextAlignmentOptions alignment, TMP_FontAsset fontAsset) { //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_0013: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localPosition = FocusChromePixelToLocal(topLeftPx, 0.0029999996f); val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; TextMeshPro val2 = val.AddComponent(); ((TMP_Text)val2).font = fontAsset; ((TMP_Text)val2).fontSize = fontSize; ((TMP_Text)val2).fontStyle = (FontStyles)1; ((TMP_Text)val2).alignment = alignment; ((Graphic)val2).color = color; ((TMP_Text)val2).text = text; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; RectTransform component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.pivot = new Vector2(0f, 1f); component.sizeDelta = new Vector2(sizePx.x / 960f * 0.33f * 2f, sizePx.y / 720f * 0.25f * 2f); } if ((Object)(object)((TMP_Text)val2).fontMaterial != (Object)null) { ((TMP_Text)val2).fontMaterial.SetFloat("_CullMode", 0f); ((TMP_Text)val2).fontMaterial.EnableKeyword("_FACE_CULLING_OFF"); } ((TMP_Text)val2).ForceMeshUpdate(false, false); } private static Vector3 FocusChromePixelToLocal(Vector2 centeredPx, float z) { //IL_0000: 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_0033: Unknown result type (might be due to invalid IL or missing references) float num = centeredPx.x / 960f * 0.33f * 2f; float num2 = centeredPx.y / 720f * 0.25f * 2f; return new Vector3(num, num2, z); } private static Material CreateFocusChromeMaterial(string name, Color color) { //IL_0058: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) Material val = (Material)(((Object)(object)VanillaShaderInfo.SourceMaterial != (Object)null) ? ((object)Object.Instantiate(VanillaShaderInfo.SourceMaterial)) : ((object)new Material(Shader.Find("HDRP/Unlit") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Standard")))); ((Object)val).name = name; BindDisplayTexture(val, (Texture)(object)Texture2D.whiteTexture); SetRuntimeMaterialColor(val, color); if (val.HasProperty("_EmissiveColor")) { val.SetColor("_EmissiveColor", Color.black); } if (val.HasProperty("_EmissiveColorLDR")) { val.SetColor("_EmissiveColorLDR", Color.black); } if (val.HasProperty("_DoubleSidedEnable")) { val.SetFloat("_DoubleSidedEnable", 1f); } if (val.HasProperty("_CullMode")) { val.SetFloat("_CullMode", 0f); } val.EnableKeyword("_DOUBLESIDED_ON"); ValidateMaterial(val); _focusChromeMaterials.Add(val); return val; } private static void SetFocusChromeVisible(bool visible) { if ((Object)(object)_focusChromeRoot != (Object)null && _focusChromeRoot.activeSelf != visible) { _focusChromeRoot.SetActive(visible); } if (_physicalMonitorVisualsHidden) { SetRendererTreeEnabled(_focusChromeRoot, visible); } } private static void SetRendererTreeEnabled(GameObject root, bool enabled) { if ((Object)(object)root == (Object)null) { return; } Renderer[] componentsInChildren = root.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { componentsInChildren[i].enabled = enabled; } } } internal static void Spawn() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: 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_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)MonitorRoot != (Object)null) { return; } if (!CCTVTerminalUnlockable.IsPurchased()) { SurveillanceBootstrap.Log.LogInfo((object)"[LethalCCTV] QuadMonitor.Spawn skipped; CCTV terminal is not purchased."); return; } GameObject val = GameObject.Find("Environment/HangarShip"); if ((Object)(object)val == (Object)null) { SurveillanceBootstrap.Log.LogWarning((object)"[LethalCCTV] QuadMonitor.Spawn: HangarShip not found — skipping spawn."); return; } VanillaShaderInfo.EnsureProbed(); if (!VanillaShaderInfo.ProbeSucceeded) { return; } GameObject val2 = null; RenderTexture[] array = null; RenderTexture[] array2 = null; Material[] array3 = null; try { Quaternion monitorRotation = SurveillanceBootstrap.Config.MonitorRotation; Vector3 val3 = SurveillanceBootstrap.Config.MonitorPosition + monitorRotation * Vector3.forward * -0.14f; val2 = new GameObject("LethalCCTV_QuadMonitor"); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = val.transform.InverseTransformPoint(val3); val2.transform.localRotation = monitorRotation; val2.transform.localScale = Vector3.one * 0.8f; Mesh quadMesh = GetQuadMesh(); if ((Object)(object)quadMesh == (Object)null) { SurveillanceBootstrap.Log.LogError((object)"[LethalCCTV] QuadMonitor.Spawn: failed to obtain Quad mesh from Resources or primitive fallback. Aborting."); CleanupPartialConstruction(val2, array, array2, array3); return; } EnsureEmptySlotBlackRT(); bool flag = NightVisionBaker.TryStart(); int num = ResolveRenderTextureWidth(); int num2 = ResolveRenderTextureHeight(num); array = (RenderTexture[])(object)new RenderTexture[4]; if (flag) { array2 = (RenderTexture[])(object)new RenderTexture[4]; } array3 = (Material[])(object)new Material[4]; Material[] array4 = (Material[])(object)new Material[4]; for (int i = 0; i < 4; i++) { RenderTexture val4 = new RenderTexture(num, num2, 16, (RenderTextureFormat)0) { name = $"LethalCCTV_Quad{i}_RT", useDynamicScale = false, autoGenerateMips = false, filterMode = (FilterMode)1 }; val4.Create(); array[i] = val4; if (flag) { RenderTexture val5 = new RenderTexture(num, num2, 16, (RenderTextureFormat)0) { name = $"LethalCCTV_Quad{i}_RawRT", useDynamicScale = false, autoGenerateMips = false, filterMode = (FilterMode)1 }; val5.Create(); array2[i] = val5; } array3[i] = CreateQuadrant(val2.transform, i, quadMesh, val4); array4[i] = CreateQuadrantOutline(val2.transform, i, quadMesh); } CreateScreenBacking(val2.transform, quadMesh); CreateFocusScreen(val2.transform, quadMesh); CreateRuntimeInteractionAnchors(val2.transform); _cameraLabels = (TextMeshPro[])(object)new TextMeshPro[4]; TMP_FontAsset val6 = ResolveTMPFontAsset(); if ((Object)(object)val6 != (Object)null) { for (int j = 0; j < 4; j++) { _cameraLabels[j] = CreateCameraLabel(val2.transform, j, val6); } } else { SurveillanceBootstrap.Log.LogWarning((object)"[LethalCCTV] CAM labels: TMP_FontAsset unavailable — camera labels skipped this load."); } CreatePageIndicator(val2.transform); ApplyNightVisionParams(); HidePhysicalMonitorVisuals(val2); MonitorRoot = val2; QuadRTs = array; RawRTs = array2; QuadMaterials = array3; QuadOutlineMaterials = array4; for (int k = 0; k < 4; k++) { _slotCurrentDisplayTex[k] = (Texture)(object)array[k]; } SurveillanceBootstrap.Log.LogInfo((object)($"[LethalCCTV] QuadMonitor spawned at {val3} rot={((Quaternion)(ref monitorRotation)).eulerAngles} " + $"with 4 Quad meshes ({0.33f}m × {0.25f}m each) " + "using cloned shader '" + VanillaShaderInfo.ShaderName + "' and texture property '" + VanillaShaderInfo.MainTexturePropertyName + "'.")); UpdatePageIndicator(QuadCameraAssignment.CurrentPage, QuadCameraAssignment.TotalPages); } catch (Exception arg) { SurveillanceBootstrap.Log.LogError((object)$"[LethalCCTV] QuadMonitor.Spawn failed: {arg}"); CleanupPartialConstruction(val2, array, array2, array3); _cameraLabels = null; _screenBacking = null; _focusScreen = null; _focusChromeRoot = null; DestroyMaterial(ref _screenBackingMaterial); DestroyMaterial(ref _focusScreenMaterial); DestroyFocusChromeMaterials(); } } private static int ResolveRenderTextureWidth() { return Mathf.Clamp(SurveillanceBootstrap.Config?.RenderRTWidth?.Value ?? 512, 64, 1024); } private static int ResolveRenderTextureHeight(int width) { return Mathf.Max(16, Mathf.RoundToInt((float)width * 0.75f)); } internal static void Despawn() { if (MonitorFocus.IsFocused) { MonitorFocus.ExitFocus(); } try { QuadCameraAssignment.Unassign(); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] QuadMonitor.Despawn: camera unassign failed: " + ex.Message)); } } NightVisionBaker.Shutdown(); if (QuadMaterials != null) { for (int i = 0; i < QuadMaterials.Length; i++) { if ((Object)(object)QuadMaterials[i] != (Object)null) { Object.Destroy((Object)(object)QuadMaterials[i]); } } QuadMaterials = null; } if (QuadOutlineMaterials != null) { for (int j = 0; j < QuadOutlineMaterials.Length; j++) { if ((Object)(object)QuadOutlineMaterials[j] != (Object)null) { Object.Destroy((Object)(object)QuadOutlineMaterials[j]); } } QuadOutlineMaterials = null; } DestroyMaterial(ref _screenBackingMaterial); DestroyMaterial(ref _focusScreenMaterial); _screenBacking = null; _focusScreen = null; _focusChromeRoot = null; DestroyFocusChromeMaterials(); _focusScreenLogged = false; if (QuadRTs != null) { for (int k = 0; k < QuadRTs.Length; k++) { if ((Object)(object)QuadRTs[k] != (Object)null) { QuadRTs[k].Release(); Object.Destroy((Object)(object)QuadRTs[k]); } } QuadRTs = null; } if (RawRTs != null) { for (int l = 0; l < RawRTs.Length; l++) { if ((Object)(object)RawRTs[l] != (Object)null) { RawRTs[l].Release(); Object.Destroy((Object)(object)RawRTs[l]); } } RawRTs = null; } if (_slotCurrentDisplayTex != null) { for (int m = 0; m < _slotCurrentDisplayTex.Length; m++) { _slotCurrentDisplayTex[m] = null; } } if ((Object)(object)_emptySlotBlackRT != (Object)null) { _emptySlotBlackRT.Release(); Object.Destroy((Object)(object)_emptySlotBlackRT); _emptySlotBlackRT = null; } if ((Object)(object)MonitorRoot != (Object)null) { Object.Destroy((Object)(object)MonitorRoot); } _runtimeFocusViewAnchor = null; _physicalMonitorVisualsHidden = false; MonitorRoot = null; _pageIndicator = null; _pageIndicatorLegacy = null; _cameraLabels = null; } private static void HidePhysicalMonitorVisuals(GameObject root) { if ((Object)(object)root == (Object)null) { return; } Renderer[] componentsInChildren = root.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { componentsInChildren[i].enabled = false; } } Collider[] componentsInChildren2 = root.GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren2.Length; j++) { if ((Object)(object)componentsInChildren2[j] != (Object)null) { componentsInChildren2[j].enabled = false; } } root.SetActive(false); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] QuadMonitor physical visuals hidden and root deactivated; render textures remain active for the vanilla monitor station."); } _physicalMonitorVisualsHidden = true; } private static void CleanupPartialConstruction(GameObject localRoot, RenderTexture[] localRTs, RenderTexture[] localRawRTs, Material[] localMaterials) { NightVisionBaker.Shutdown(); if (localMaterials != null) { for (int i = 0; i < localMaterials.Length; i++) { if ((Object)(object)localMaterials[i] != (Object)null) { Object.Destroy((Object)(object)localMaterials[i]); } } } if (localRTs != null) { for (int j = 0; j < localRTs.Length; j++) { if ((Object)(object)localRTs[j] != (Object)null) { localRTs[j].Release(); Object.Destroy((Object)(object)localRTs[j]); } } } if (localRawRTs != null) { for (int k = 0; k < localRawRTs.Length; k++) { if ((Object)(object)localRawRTs[k] != (Object)null) { localRawRTs[k].Release(); Object.Destroy((Object)(object)localRawRTs[k]); } } } if ((Object)(object)localRoot != (Object)null) { Object.Destroy((Object)(object)localRoot); } _focusChromeRoot = null; DestroyFocusChromeMaterials(); } private static Material CreateQuadrant(Transform parent, int slotIndex, Mesh quadMesh, RenderTexture rt) { //IL_0042: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) float num = ((slotIndex % 2 == 0) ? (-0.165f) : 0.165f); float num2 = ((slotIndex < 2) ? 0.125f : (-0.125f)); float num3 = -0.014f + (float)slotIndex * 0.001f; GameObject val = new GameObject($"Quadrant_{slotIndex}"); val.transform.SetParent(parent, false); val.transform.localPosition = new Vector3(num, num2, num3); val.transform.localRotation = Quaternion.identity; val.transform.localScale = new Vector3(0.33f, 0.25f, 1f); val.AddComponent().sharedMesh = quadMesh; MeshRenderer obj = val.AddComponent(); ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).lightProbeUsage = (LightProbeUsage)0; ((Renderer)obj).reflectionProbeUsage = (ReflectionProbeUsage)0; Material val2 = Object.Instantiate(VanillaShaderInfo.SourceMaterial); ((Object)val2).name = $"LethalCCTV_QuadMat_{slotIndex}"; BindDisplayTexture(val2, (Texture)(object)rt); if (val2.HasProperty("_UnlitColor")) { val2.SetColor("_UnlitColor", Color.white); } val2.SetFloat("_DoubleSidedEnable", 1f); val2.SetFloat("_CullMode", 0f); val2.EnableKeyword("_DOUBLESIDED_ON"); HDMaterial.ValidateMaterial(val2); ((Renderer)obj).sharedMaterial = val2; return val2; } private static void CreateScreenBacking(Transform parent, Mesh quadMesh) { //IL_000a: 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_0028: Expected O, but got Unknown //IL_0052: 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_0089: Unknown result type (might be due to invalid IL or missing references) _screenBackingMaterial = CreateScreenSurfaceMaterial("LethalCCTV_BlackScreenBacking", (Texture)(object)Texture2D.blackTexture, Color.black); _screenBacking = new GameObject("ScreenBlackBacking"); _screenBacking.transform.SetParent(parent, false); _screenBacking.transform.localPosition = new Vector3(0f, 0f, -0.01f); _screenBacking.transform.localRotation = Quaternion.identity; _screenBacking.transform.localScale = new Vector3(0.66f, 0.5f, 1f); _screenBacking.AddComponent().sharedMesh = quadMesh; MeshRenderer obj = _screenBacking.AddComponent(); ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).lightProbeUsage = (LightProbeUsage)0; ((Renderer)obj).reflectionProbeUsage = (ReflectionProbeUsage)0; ((Renderer)obj).sharedMaterial = _screenBackingMaterial; } private static void CreateFocusScreen(Transform parent, Mesh quadMesh) { //IL_000a: 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_0028: Expected O, but got Unknown //IL_0052: 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_0089: Unknown result type (might be due to invalid IL or missing references) _focusScreenMaterial = CreateScreenSurfaceMaterial("LethalCCTV_PhysicalFocusScreen", (Texture)(object)Texture2D.blackTexture, Color.white); _focusScreen = new GameObject("PhysicalFocusScreen"); _focusScreen.transform.SetParent(parent, false); _focusScreen.transform.localPosition = new Vector3(0f, 0f, -0.024f); _focusScreen.transform.localRotation = Quaternion.identity; _focusScreen.transform.localScale = new Vector3(0.66f, 0.5f, 1f); _focusScreen.AddComponent().sharedMesh = quadMesh; MeshRenderer obj = _focusScreen.AddComponent(); ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).lightProbeUsage = (LightProbeUsage)0; ((Renderer)obj).reflectionProbeUsage = (ReflectionProbeUsage)0; ((Renderer)obj).sharedMaterial = _focusScreenMaterial; _focusScreen.SetActive(false); CreateFocusChromeOverlay(parent, quadMesh); } private static Material CreateScreenSurfaceMaterial(string name, Texture texture, Color color) { //IL_002f: 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_006f: 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_00a1: 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) Shader val = Shader.Find("HDRP/Unlit") ?? Shader.Find("Unlit/Texture"); Material val2 = (Material)((!((Object)(object)val != (Object)null)) ? ((object)Object.Instantiate(VanillaShaderInfo.SourceMaterial)) : ((object)new Material(val))); ((Object)val2).name = name; BindDisplayTexture(val2, texture); if (val2.HasProperty("_UnlitColor")) { val2.SetColor("_UnlitColor", color); } if (val2.HasProperty("_BaseColor")) { val2.SetColor("_BaseColor", color); } if (val2.HasProperty("_Color")) { val2.SetColor("_Color", color); } if (val2.HasProperty("_EmissiveColor")) { val2.SetColor("_EmissiveColor", Color.black); } if (val2.HasProperty("_EmissiveColorLDR")) { val2.SetColor("_EmissiveColorLDR", Color.black); } if (val2.HasProperty("_SurfaceType")) { val2.SetFloat("_SurfaceType", 0f); } if (val2.HasProperty("_BlendMode")) { val2.SetFloat("_BlendMode", 0f); } if (val2.HasProperty("_ZWrite")) { val2.SetFloat("_ZWrite", 1f); } if (val2.HasProperty("_TransparentZWrite")) { val2.SetFloat("_TransparentZWrite", 0f); } if (val2.HasProperty("_AlphaCutoffEnable")) { val2.SetFloat("_AlphaCutoffEnable", 0f); } if (val2.HasProperty("_DoubleSidedEnable")) { val2.SetFloat("_DoubleSidedEnable", 1f); } if (val2.HasProperty("_CullMode")) { val2.SetFloat("_CullMode", 0f); } val2.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); val2.DisableKeyword("_BLENDMODE_ALPHA"); val2.DisableKeyword("_EMISSION"); val2.DisableKeyword("_EMISSIVE_COLOR_MAP"); val2.EnableKeyword("_DOUBLESIDED_ON"); val2.renderQueue = 2000; ValidateMaterial(val2); return val2; } private static void BindDisplayTexture(Material material, Texture texture) { if (!((Object)(object)material == (Object)null)) { Texture texture2 = (Texture)(((Object)(object)texture != (Object)null) ? ((object)texture) : ((object)Texture2D.blackTexture)); if (!string.IsNullOrEmpty(VanillaShaderInfo.MainTexturePropertyName)) { SetTextureIfExists(material, VanillaShaderInfo.MainTexturePropertyName, texture2); } for (int i = 0; i < DisplayTexturePropertyNames.Length; i++) { SetTextureIfExists(material, DisplayTexturePropertyNames[i], texture2); } for (int j = 0; j < ClearTexturePropertyNames.Length; j++) { SetTextureIfExists(material, ClearTexturePropertyNames[j], null); } } } private static bool SetTextureIfExists(Material material, string propertyName, Texture texture) { if ((Object)(object)material == (Object)null || string.IsNullOrEmpty(propertyName) || !material.HasProperty(propertyName)) { return false; } material.SetTexture(propertyName, texture); return true; } private static void ValidateMaterial(Material material) { if ((Object)(object)material == (Object)null) { return; } try { HDMaterial.ValidateMaterial(material); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Material validation skipped for '" + ((Object)material).name + "': " + ex.Message)); } } } internal static void BindRTToSlot(int slotIndex) { if (QuadMaterials != null && slotIndex >= 0 && slotIndex < QuadMaterials.Length && QuadRTs != null && slotIndex < QuadRTs.Length) { Material val = QuadMaterials[slotIndex]; RenderTexture val2 = QuadRTs[slotIndex]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null)) { BindDisplayTexture(val, (Texture)(object)val2); _slotCurrentDisplayTex[slotIndex] = (Texture)(object)val2; MonitorFocus.NotifySlotDisplayTextureChanged(slotIndex, (Texture)(object)val2); CCTVVanillaMonitorDisplay.NotifySlotTextureChanged(slotIndex, (Texture)(object)val2); } } } internal static void BindEmptyToSlot(int slotIndex) { if (QuadMaterials != null && slotIndex >= 0 && slotIndex < QuadMaterials.Length) { EnsureEmptySlotBlackRT(); Material val = QuadMaterials[slotIndex]; if (!((Object)(object)val == (Object)null) && !((Object)(object)_emptySlotBlackRT == (Object)null)) { BindDisplayTexture(val, (Texture)(object)_emptySlotBlackRT); _slotCurrentDisplayTex[slotIndex] = (Texture)(object)_emptySlotBlackRT; MonitorFocus.NotifySlotDisplayTextureChanged(slotIndex, (Texture)(object)_emptySlotBlackRT); CCTVVanillaMonitorDisplay.NotifySlotTextureChanged(slotIndex, (Texture)(object)_emptySlotBlackRT); SurveillanceBootstrap.Log.LogInfo((object)$"[LethalCCTV] SelectCameras: slot {slotIndex} bound to empty-fallback black RT."); } } } internal static void SetPhysicalDisplayBlanked(bool blanked) { if (QuadMaterials == null) { return; } if (blanked) { EnsureEmptySlotBlackRT(); } for (int i = 0; i < QuadMaterials.Length; i++) { Material val = QuadMaterials[i]; if (!((Object)(object)val == (Object)null)) { Texture val2 = (Texture)(blanked ? ((object)_emptySlotBlackRT) : ((object)GetCurrentDisplayTexture(i))); if (!((Object)(object)val2 == (Object)null)) { BindDisplayTexture(val, val2); } } } } internal static void SetFocusScreenTexture(Texture texture, bool active) { //IL_00c3: 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) if ((Object)(object)_focusScreen == (Object)null || (Object)(object)_focusScreenMaterial == (Object)null) { if (active) { SurveillanceBootstrap.Log.LogWarning((object)"[LethalCCTV] Physical focus screen requested but focus screen quad/material is unavailable."); } } else if (active && (Object)(object)texture != (Object)null) { BindDisplayTexture(_focusScreenMaterial, texture); _focusScreen.SetActive(true); if (_physicalMonitorVisualsHidden) { SetRendererTreeEnabled(_focusScreen, enabled: true); } SetFocusChromeVisible(visible: true); if (!_focusScreenLogged) { _focusScreenLogged = true; SurveillanceBootstrap.Log.LogInfo((object)("[LethalCCTV] Physical focus screen active: texture='" + ((Object)texture).name + "' size=" + DescribeTextureSize(texture) + " " + $"quadScale={_focusScreen.transform.localScale} localPos={_focusScreen.transform.localPosition} property='{VanillaShaderInfo.MainTexturePropertyName}'.")); } } else { _focusScreen.SetActive(false); SetFocusChromeVisible(visible: false); if (_physicalMonitorVisualsHidden) { SetRendererTreeEnabled(_focusScreen, enabled: false); } BindDisplayTexture(_focusScreenMaterial, (Texture)(object)Texture2D.blackTexture); } } internal static Texture GetCurrentDisplayTexture(int slot) { if (_slotCurrentDisplayTex == null) { return null; } if (slot < 0 || slot >= _slotCurrentDisplayTex.Length) { return null; } return _slotCurrentDisplayTex[slot]; } internal static void UpdateCameraLabel(int slot, CCTVCamera camera) { if (slot < 0) { return; } string text = QuadCameraAssignment.BuildCameraLabel(camera); MonitorFocus.UpdateCameraLabel(slot, text); if (_cameraLabels == null || slot < 0 || slot >= _cameraLabels.Length) { return; } TextMeshPro val = _cameraLabels[slot]; if ((Object)(object)val == (Object)null) { return; } if (!string.IsNullOrEmpty(text)) { ((TMP_Text)val).text = text; if (!((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } } else if (((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(false); } } internal static void ApplyNightVisionParams() { Material bakeMaterial = NightVisionBaker.BakeMaterial; if (!((Object)(object)bakeMaterial == (Object)null)) { LethalCCTVConfig config = SurveillanceBootstrap.Config; float value = config?.NightVisionGain.Value ?? 2f; float value2 = ((config != null && config.NightVisionEnabled.Value) ? 1f : 0f); float value3 = ((config == null || config.NightVisionFlipY.Value) ? 1f : 0f); Push(bakeMaterial, NightVisionShader.GainPropertyId, value); Push(bakeMaterial, NightVisionShader.GrayscaleEnabledPropertyId, value2); Push(bakeMaterial, NightVisionShader.FlipYPropertyId, value3); Push(bakeMaterial, NightVisionShader.ColorRetentionPropertyId, config?.FeedColorRetention.Value ?? 0.35f); Push(bakeMaterial, NightVisionShader.ScanlineStrengthPropertyId, config?.FeedScanlineStrength.Value ?? 0.055f); Push(bakeMaterial, NightVisionShader.NoiseStrengthPropertyId, config?.FeedNoiseStrength.Value ?? 0.018f); Push(bakeMaterial, NightVisionShader.VignetteStrengthPropertyId, config?.FeedVignetteStrength.Value ?? 0.12f); Push(bakeMaterial, NightVisionShader.ChromaAberrationPropertyId, config?.FeedChromaAberration.Value ?? 0.25f); Push(bakeMaterial, NightVisionShader.RollBarStrengthPropertyId, config?.FeedRollBarStrength.Value ?? 0.1f); Push(bakeMaterial, NightVisionShader.RollBarSpeedPropertyId, config?.FeedRollBarSpeed.Value ?? 0.12f); Push(bakeMaterial, NightVisionShader.CurvatureStrengthPropertyId, config?.FeedCurvatureStrength.Value ?? 0.12f); Push(bakeMaterial, NightVisionShader.InterlaceStrengthPropertyId, config?.FeedInterlaceStrength.Value ?? 0.06f); Push(bakeMaterial, NightVisionShader.DropoutStrengthPropertyId, config?.FeedDropoutStrength.Value ?? 0.04f); } static void Push(Material mat, int propertyId, float num) { if (mat.HasProperty(propertyId)) { mat.SetFloat(propertyId, num); } } } internal static void UpdatePageIndicator(int currentPageZeroIndexed, int totalPages) { string text = ((totalPages > 0) ? $"Page {currentPageZeroIndexed + 1} / {totalPages}" : "No Cameras"); if ((Object)(object)_pageIndicator != (Object)null) { ((TMP_Text)_pageIndicator).text = text; } else if ((Object)(object)_pageIndicatorLegacy != (Object)null) { _pageIndicatorLegacy.text = text; } MonitorFocus.UpdatePageIndicator(currentPageZeroIndexed, totalPages); } private static string DescribeTextureSize(Texture texture) { if (!((Object)(object)texture != (Object)null)) { return ""; } return $"{texture.width}x{texture.height}"; } private static void DestroyMaterial(ref Material material) { if (!((Object)(object)material == (Object)null)) { Object.Destroy((Object)(object)material); material = null; } } private static void DestroyFocusChromeMaterials() { if (_focusChromeMaterials.Count == 0) { return; } for (int i = 0; i < _focusChromeMaterials.Count; i++) { if ((Object)(object)_focusChromeMaterials[i] != (Object)null) { Object.Destroy((Object)(object)_focusChromeMaterials[i]); } } _focusChromeMaterials.Clear(); } private static void SetRuntimeMaterialColor(Material mat, Color color) { //IL_001d: 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_0056: 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) if (!((Object)(object)mat == (Object)null)) { if (mat.HasProperty("_UnlitColor")) { mat.SetColor("_UnlitColor", color); } if (mat.HasProperty("_BaseColor")) { mat.SetColor("_BaseColor", color); } if (mat.HasProperty("_Color")) { mat.SetColor("_Color", color); } mat.color = color; } } private static Transform FindChildRecursive(Transform parent, string name) { if ((Object)(object)parent == (Object)null) { return null; } if (((Object)parent).name == name) { return parent; } for (int i = 0; i < parent.childCount; i++) { Transform val = FindChildRecursive(parent.GetChild(i), name); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static TMP_FontAsset ResolveTMPFontAsset() { try { if ((Object)(object)TMP_Settings.defaultFontAsset != (Object)null) { return TMP_Settings.defaultFontAsset; } } catch (Exception ex) { SurveillanceBootstrap.Log.LogWarning((object)("[LethalCCTV] TMP_Settings.defaultFontAsset read threw: " + ex.Message)); } try { HUDManager instance = HUDManager.Instance; if ((Object)(object)instance != (Object)null && instance.controlTipLines != null && instance.controlTipLines.Length != 0) { TextMeshProUGUI val = instance.controlTipLines[0]; if ((Object)(object)val != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)null) { return ((TMP_Text)val).font; } } } catch (Exception ex2) { SurveillanceBootstrap.Log.LogWarning((object)("[LethalCCTV] HUDManager.controlTipLines[0].font read threw: " + ex2.Message)); } return null; } private static void EnsureEmptySlotBlackRT() { //IL_001a: 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) //IL_002a: 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) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown if (!((Object)(object)_emptySlotBlackRT != (Object)null)) { _emptySlotBlackRT = new RenderTexture(256, 256, 0, (RenderTextureFormat)0) { name = "LethalCCTV_EmptySlot_BlackRT", useDynamicScale = false, autoGenerateMips = false, filterMode = (FilterMode)0 }; _emptySlotBlackRT.Create(); Texture2D obj = BuildEmptySlotBlackTexture(); Graphics.Blit((Texture)(object)obj, _emptySlotBlackRT); Object.Destroy((Object)(object)obj); SurveillanceBootstrap.Log.LogInfo((object)$"[LethalCCTV] Empty-slot black RT allocated ({256}x{256} ARGB32)."); } } private static Texture2D BuildEmptySlotBlackTexture() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_004b: 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) Texture2D val = new Texture2D(256, 256, (TextureFormat)4, false) { name = "LethalCCTV_EmptyBlack", filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; Color32[] array = (Color32[])(object)new Color32[65536]; Color32 val2 = default(Color32); ((Color32)(ref val2))..ctor((byte)0, (byte)0, (byte)0, byte.MaxValue); for (int i = 0; i < array.Length; i++) { array[i] = val2; } val.SetPixels32(array); val.Apply(false, true); return val; } private static Mesh GetQuadMesh() { if ((Object)(object)_cachedQuadMesh != (Object)null) { return _cachedQuadMesh; } Mesh val = Resources.GetBuiltinResource("Quad.fbx"); if ((Object)(object)val == (Object)null) { SurveillanceBootstrap.Log.LogWarning((object)"[LethalCCTV] Resources.GetBuiltinResource('Quad.fbx') returned null. Falling back to CreatePrimitive."); GameObject obj = GameObject.CreatePrimitive((PrimitiveType)5); MeshFilter component = obj.GetComponent(); val = (((Object)(object)component != (Object)null) ? component.sharedMesh : null); Object.Destroy((Object)(object)obj); } _cachedQuadMesh = val; return _cachedQuadMesh; } } [HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")] internal static class QuickMenuPatch { [HarmonyPrefix] private static bool Prefix() { bool flag = MainframeInteractionSession.IsAnyLocalSessionActive || MainframeInteractionSession.WasActiveThisFrame; bool flag2 = MonitorFocus.IsFocused || MonitorFocus.WasActiveThisFrame || flag; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] QuickMenu prefix fired, IsFocused={MonitorFocus.IsFocused} WasActiveThisFrame={MonitorFocus.WasActiveThisFrame} MainframeActive={MainframeInteractionSession.IsAnyLocalSessionActive} MainframeWasActiveThisFrame={MainframeInteractionSession.WasActiveThisFrame} suppress={flag2}"); } return !flag2; } } [HarmonyPatch(typeof(PlayerControllerB), "OpenMenu_performed")] internal static class CameraOperatorOpenMenuPerformedPatch { [HarmonyPrefix] private static bool Prefix() { bool flag = MainframeInteractionSession.IsAnyLocalSessionActive || MainframeInteractionSession.WasActiveThisFrame; bool flag2 = MonitorFocus.IsFocused || MonitorFocus.WasActiveThisFrame || flag; if (flag2) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] PlayerControllerB.OpenMenu_performed suppressed during CCTV focus/mainframe session, IsFocused={MonitorFocus.IsFocused} WasActiveThisFrame={MonitorFocus.WasActiveThisFrame} MainframeActive={MainframeInteractionSession.IsAnyLocalSessionActive} MainframeWasActiveThisFrame={MainframeInteractionSession.WasActiveThisFrame}."); } } return !flag2; } } internal static class RadarOverlay { private readonly struct TileFootprint { public readonly Tile Tile; public readonly Vector3[] Corners; public readonly Vector3 Center; public readonly float FloorY; public readonly float Area; public readonly bool Primary; public readonly int FloorIndex; public readonly DoorwayMarker[] Doorways; public TileFootprint(Tile tile, Vector3[] corners, Vector3 center, float floorY, float area, bool primary, int floorIndex, DoorwayMarker[] doorways) { //IL_000f: 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) Tile = tile; Corners = corners; Center = center; FloorY = floorY; Area = area; Primary = primary; FloorIndex = floorIndex; Doorways = doorways; } public TileFootprint WithFloorIndex(int floorIndex) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) return new TileFootprint(Tile, Corners, Center, FloorY, Area, Primary, floorIndex, Doorways); } } private sealed class FloorBand { private float _weightedY; private float _weight; private int _tileCount; public int Rank; public float CenterY => _weightedY / Mathf.Max(0.01f, _weight); public float Weight => _weight; public int TileCount => _tileCount; public FloorBand(float y, float weight) { _weight = Mathf.Max(0.01f, weight); _weightedY = y * _weight; _tileCount = 1; } public void Add(float y, float weight) { Add(y, weight, 1); } public void Add(float y, float weight, int tileCount) { float num = Mathf.Max(0.01f, weight); _weightedY += y * num; _weight += num; _tileCount += Mathf.Max(1, tileCount); } } private readonly struct DoorwayMarker { public readonly Vector3 Position; public readonly Tile ConnectedTile; public readonly Vector3 ConnectedPosition; public DoorwayMarker(Vector3 position, Tile connectedTile, Vector3 connectedPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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_0010: Unknown result type (might be due to invalid IL or missing references) Position = position; ConnectedTile = connectedTile; ConnectedPosition = connectedPosition; } } private readonly struct DoorwayPixel { public readonly Vector2Int Pixel; public readonly DoorwayMarker Marker; public DoorwayPixel(Vector2Int pixel, DoorwayMarker marker) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) Pixel = pixel; Marker = marker; } } private readonly struct MapBounds { public readonly float MinX; public readonly float MaxX; public readonly float MinZ; public readonly float MaxZ; public MapBounds(float minX, float maxX, float minZ, float maxZ) { MinX = minX; MaxX = maxX; MinZ = minZ; MaxZ = maxZ; } } internal readonly struct StatsSnapshot { public readonly int FacilityScrapValue; public readonly int LiveInteriorPlayers; public readonly int LiveInteriorEnemies; public StatsSnapshot(int facilityScrapValue, int liveInteriorPlayers, int liveInteriorEnemies) { FacilityScrapValue = facilityScrapValue; LiveInteriorPlayers = liveInteriorPlayers; LiveInteriorEnemies = liveInteriorEnemies; } } private const int MAP_TEXTURE_WIDTH = 2048; private const int MAP_TEXTURE_HEIGHT = 864; private const int GRID_SPACING_PX = 96; private const float MAP_PADDING_M = 2f; private const float MAP_PADDING_RATIO = 0.02f; private const float MIN_MAP_SPAN_M = 34f; private const float PAGE_REGION_RADIUS_M = 44f; private const float RADAR_VIEW_FILL_HEADROOM = 0.96f; private const float STATS_REFRESH_INTERVAL = 0.75f; private const float FLOOR_BAND_MERGE_M = 7.5f; private const float INTERMEDIATE_FLOOR_NOISE_MAX_AREA_RATIO = 0.22f; private const int INTERMEDIATE_FLOOR_NOISE_MAX_TILES = 2; private static readonly Color32 COLOR_BG = new Color32((byte)5, (byte)13, (byte)9, byte.MaxValue); private static readonly Color32 COLOR_GRID = new Color32((byte)10, (byte)34, (byte)26, byte.MaxValue); private static readonly Color32 COLOR_TILE_FILL = new Color32((byte)0, (byte)50, (byte)29, byte.MaxValue); private static readonly Color32 COLOR_TILE_FILL_PRIMARY = new Color32((byte)0, (byte)70, (byte)38, byte.MaxValue); private static readonly Color32 COLOR_BRIDGE = new Color32((byte)0, (byte)128, (byte)78, byte.MaxValue); private static readonly Color32 COLOR_TILE = new Color32((byte)0, (byte)238, (byte)105, byte.MaxValue); private static readonly Color32 COLOR_TILE_SECONDARY = new Color32((byte)0, (byte)170, (byte)88, byte.MaxValue); private static readonly Color32 COLOR_OPENING = new Color32((byte)0, (byte)212, (byte)91, byte.MaxValue); private static readonly Color32 COLOR_LABEL = new Color32(byte.MaxValue, (byte)184, (byte)46, byte.MaxValue); private static readonly Color32 COLOR_ALL = new Color32((byte)56, (byte)148, (byte)214, byte.MaxValue); private static readonly Color32 COLOR_PAGE = new Color32(byte.MaxValue, (byte)184, (byte)46, byte.MaxValue); private static readonly Color32 COLOR_ACTIVE = new Color32((byte)64, (byte)236, (byte)96, byte.MaxValue); private static readonly Color32 COLOR_FORWARD = new Color32((byte)106, (byte)224, (byte)126, byte.MaxValue); private static readonly Color32 COLOR_PLAYER = new Color32((byte)190, (byte)240, byte.MaxValue, byte.MaxValue); private static readonly Color32 COLOR_ENEMY = new Color32(byte.MaxValue, (byte)68, (byte)68, byte.MaxValue); private static readonly Color32 COLOR_CONTRACT = new Color32(byte.MaxValue, (byte)226, (byte)52, byte.MaxValue); private static readonly Color32 COLOR_CONTRACT_DANGER = new Color32(byte.MaxValue, (byte)76, (byte)62, byte.MaxValue); private static readonly Color32 COLOR_SUPPORT = new Color32((byte)55, byte.MaxValue, (byte)105, byte.MaxValue); private static readonly Color32 COLOR_SUPPORT_CORE = new Color32((byte)190, byte.MaxValue, (byte)205, byte.MaxValue); private static IReadOnlyList _cameras; private static readonly List _tileFootprints = new List(64); private static readonly List _mapPoints = new List(128); private static readonly List _floorBands = new List(8); private static readonly HashSet _seenTiles = new HashSet(); private static Texture2D _mapTexture; private static Color32[] _pixels; private static Color32[] _staticPixels; private static MapBounds _cachedBounds; private static bool _dirty = true; private static bool _staticDirty = true; private static int _cachedFloorIndex = -1; private static float _nextStatsRefreshTime; private static bool _hasCachedStats; private static StatsSnapshot _cachedStats; internal static Texture ResolveMapTexture() { EnsureTexture(); if (_dirty) { Redraw(); } return (Texture)(object)_mapTexture; } internal static void Prewarm() { if (_cameras == null || _cameras.Count == 0) { return; } try { ResolveMapTexture(); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Radar map prewarm skipped: " + ex.Message)); } } } internal static string GetActiveInteriorFloorLabel() { CCTVCamera boundCamera = QuadCameraAssignment.GetBoundCamera(MonitorFocus.ActiveSlot); if ((Object)(object)boundCamera != (Object)null) { return "RADAR MAP " + boundCamera.ResolvedLabel; } if (!TryResolveActiveFloorRank(out var floorRank)) { return "RADAR MAP"; } return "RADAR MAP " + FormatFloorLabel(floorRank); } internal static void SetCameras(IReadOnlyList cameras) { _cameras = cameras; RebuildTileFootprints(); _staticDirty = true; _dirty = true; _nextStatsRefreshTime = 0f; _hasCachedStats = false; } internal static void ClearCameras() { _cameras = null; _tileFootprints.Clear(); _mapPoints.Clear(); _floorBands.Clear(); _staticDirty = true; _dirty = true; } internal static void UpdateHighlights() { _dirty = true; } internal static void Shutdown() { _cameras = null; _tileFootprints.Clear(); _mapPoints.Clear(); _floorBands.Clear(); _seenTiles.Clear(); if ((Object)(object)_mapTexture != (Object)null) { Object.Destroy((Object)(object)_mapTexture); _mapTexture = null; } _pixels = null; _staticPixels = null; _dirty = true; _staticDirty = true; _cachedFloorIndex = -1; _nextStatsRefreshTime = 0f; _hasCachedStats = false; VanillaRadarFeed.Shutdown(); } internal static StatsSnapshot CollectStats() { if (_hasCachedStats && Time.unscaledTime < _nextStatsRefreshTime) { return _cachedStats; } int num = 0; GrabbableObject[] array = Object.FindObjectsOfType(); foreach (GrabbableObject val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.itemProperties == (Object)null) && val.itemProperties.isScrap && !val.isInShipRoom && !val.isInElevator && val.isInFactory) { num += Mathf.Max(0, val.scrapValue); } } int num2 = 0; StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && instance.allPlayerScripts != null) { for (int j = 0; j < instance.allPlayerScripts.Length; j++) { PlayerControllerB val2 = instance.allPlayerScripts[j]; if (!((Object)(object)val2 == (Object)null) && val2.isPlayerControlled && !val2.isPlayerDead && val2.isInsideFactory) { num2++; } } } int num3 = 0; RoundManager instance2 = RoundManager.Instance; if ((Object)(object)instance2 != (Object)null && instance2.SpawnedEnemies != null) { for (int k = 0; k < instance2.SpawnedEnemies.Count; k++) { EnemyAI val3 = instance2.SpawnedEnemies[k]; if (!((Object)(object)val3 == (Object)null) && !val3.isEnemyDead && !val3.isInsidePlayerShip && !val3.isOutside) { num3++; } } } _cachedStats = new StatsSnapshot(num, num2, num3); _hasCachedStats = true; _nextStatsRefreshTime = Time.unscaledTime + 0.75f; return _cachedStats; } private static void EnsureTexture() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown if (!((Object)(object)_mapTexture != (Object)null) || _pixels == null || _staticPixels == null) { _mapTexture = new Texture2D(2048, 864, (TextureFormat)4, false) { name = "LethalCCTV_RadarSchematic", filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; _pixels = (Color32[])(object)new Color32[1769472]; _staticPixels = (Color32[])(object)new Color32[1769472]; _dirty = true; _staticDirty = true; } } private static void RebuildTileFootprints() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) _tileFootprints.Clear(); _mapPoints.Clear(); _seenTiles.Clear(); if (_cameras == null) { return; } HashSet hashSet = new HashSet(); for (int i = 0; i < _cameras.Count; i++) { CCTVCamera cCTVCamera = _cameras[i]; if (!((Object)(object)cCTVCamera == (Object)null)) { _mapPoints.Add(((Component)cCTVCamera).transform.position); if ((Object)(object)cCTVCamera.OwningTile != (Object)null) { hashSet.Add(cCTVCamera.OwningTile); } } } Dungeon val = ResolveDungeonOrNull(); IReadOnlyList readOnlyList = (((Object)(object)val != (Object)null) ? val.AllTiles : null); if (readOnlyList != null && readOnlyList.Count > 0) { for (int j = 0; j < readOnlyList.Count; j++) { Tile val2 = readOnlyList[j]; AddTileFootprint(val2, hashSet.Contains(val2)); } AssignFloorIndices(); return; } foreach (Tile item in hashSet) { AddTileFootprint(item, primary: true); } AssignFloorIndices(); } private static void AddTileFootprint(Tile tile, bool primary) { //IL_002c: 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) //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_0057: 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_0054: 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) //IL_007b: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_009f: 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_00b1: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_00f8: 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_0105: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tile == (Object)null || _seenTiles.Contains(tile) || tile.Placement == null) { return; } _seenTiles.Add(tile); Bounds local = DungeonCameraSpawner.ComputeWorldAabbLocal(tile); Vector3 size = ((Bounds)(ref local)).size; if (((Vector3)(ref size)).sqrMagnitude < 1E-06f) { local = tile.Placement.LocalBounds; } size = ((Bounds)(ref local)).size; if (!(((Vector3)(ref size)).sqrMagnitude < 1E-06f)) { Vector3[] array = (Vector3[])(object)new Vector3[4]; Vector3 min = ((Bounds)(ref local)).min; Vector3 max = ((Bounds)(ref local)).max; array[0] = ToWorld(tile, new Vector3(min.x, ((Bounds)(ref local)).center.y, min.z)); array[1] = ToWorld(tile, new Vector3(max.x, ((Bounds)(ref local)).center.y, min.z)); array[2] = ToWorld(tile, new Vector3(max.x, ((Bounds)(ref local)).center.y, max.z)); array[3] = ToWorld(tile, new Vector3(min.x, ((Bounds)(ref local)).center.y, max.z)); for (int i = 0; i < array.Length; i++) { _mapPoints.Add(array[i]); } DoorwayMarker[] doorways = CollectDoorwayMarkers(tile); Vector3 center = ToWorld(tile, ((Bounds)(ref local)).center); float floorY = ResolveTileFloorY(tile, local); float area = Mathf.Max(1f, Mathf.Abs(((Bounds)(ref local)).size.x * ((Bounds)(ref local)).size.z)); _tileFootprints.Add(new TileFootprint(tile, array, center, floorY, area, primary, 0, doorways)); } } private static void AssignFloorIndices() { _floorBands.Clear(); if (_tileFootprints.Count == 0) { return; } List list = new List(_tileFootprints); list.Sort((TileFootprint a, TileFootprint b) => a.FloorY.CompareTo(b.FloorY)); for (int num = 0; num < list.Count; num++) { TileFootprint tileFootprint = list[num]; int num2 = FindNearestFloorBandIndex(tileFootprint.FloorY); if (num2 < 0 || Mathf.Abs(_floorBands[num2].CenterY - tileFootprint.FloorY) > 7.5f) { _floorBands.Add(new FloorBand(tileFootprint.FloorY, tileFootprint.Area)); _floorBands.Sort((FloorBand a, FloorBand b) => a.CenterY.CompareTo(b.CenterY)); } else { _floorBands[num2].Add(tileFootprint.FloorY, tileFootprint.Area); } } CollapseIntermediateFloorNoiseBands(); int num3 = ResolveMainEntranceFloorBandIndex(); for (int num4 = 0; num4 < _floorBands.Count; num4++) { _floorBands[num4].Rank = num4 - num3; } for (int num5 = 0; num5 < _tileFootprints.Count; num5++) { TileFootprint tileFootprint2 = _tileFootprints[num5]; int num6 = FindNearestFloorBandIndex(tileFootprint2.FloorY); int floorIndex = ((num6 >= 0) ? _floorBands[num6].Rank : 0); _tileFootprints[num5] = tileFootprint2.WithFloorIndex(floorIndex); } } private static Dungeon ResolveDungeonOrNull() { RoundManager instance = RoundManager.Instance; RuntimeDungeon val = (((Object)(object)instance != (Object)null) ? instance.dungeonGenerator : null); DungeonGenerator val2 = (((Object)(object)val != (Object)null) ? val.Generator : null); if (val2 == null) { return null; } return val2.CurrentDungeon; } private static Vector3 ToWorld(Tile tile, Vector3 local) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_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) return tile.Placement.Position + tile.Placement.Rotation * local; } private static float ResolveTileFloorY(Tile tile, Bounds local) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0043: 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) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tile == (Object)null || tile.Placement == null) { return 0f; } Vector3 local2 = default(Vector3); ((Vector3)(ref local2))..ctor(((Bounds)(ref local)).center.x, ((Bounds)(ref local)).min.y, ((Bounds)(ref local)).center.z); float num = ToWorld(tile, local2).y; if (tile.UsedDoorways != null) { for (int i = 0; i < tile.UsedDoorways.Count; i++) { Doorway val = tile.UsedDoorways[i]; if (!((Object)(object)val == (Object)null)) { float y = ((Component)val).transform.position.y; if (Mathf.Abs(y - num) <= 7.5f) { num = Mathf.Min(num, y); } } } } return num; } private static int ResolveMainEntranceFloorBandIndex() { //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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_005a: 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) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (_floorBands.Count == 0) { return 0; } if (!TryResolveInteriorMainEntrancePosition(out var position)) { return FindNearestFloorBandIndex(0f); } int num = -1; float num2 = float.PositiveInfinity; for (int i = 0; i < _tileFootprints.Count; i++) { TileFootprint tileFootprint = _tileFootprints[i]; Vector3 val = tileFootprint.Center - position; float num3 = Mathf.Abs(tileFootprint.FloorY - position.y); float num4 = val.x * val.x + val.z * val.z + num3 * num3 * 16f; if (!(num4 >= num2)) { num = i; num2 = num4; } } if (num >= 0) { return FindNearestFloorBandIndex(_tileFootprints[num].FloorY); } return FindNearestFloorBandIndex(position.y); } private static bool TryResolveInteriorMainEntrancePosition(out Vector3 position) { //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_0073: 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_0078: Unknown result type (might be due to invalid IL or missing references) EntranceTeleport[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); EntranceTeleport val = null; foreach (EntranceTeleport val2 in array) { if (!((Object)(object)val2 == (Object)null) && !val2.isEntranceToBuilding && ((Object)(object)val == (Object)null || val2.entranceId == 0)) { val = val2; if (val2.entranceId == 0) { break; } } } if ((Object)(object)val != (Object)null) { position = (((Object)(object)val.entrancePoint != (Object)null) ? val.entrancePoint.position : ((Component)val).transform.position); return true; } position = Vector3.zero; return false; } private static string FormatFloorLabel(int floorRank) { if (floorRank == 0) { return "FLOOR 1"; } if (floorRank > 0) { return "FLOOR " + (floorRank + 1); } return floorRank switch { -1 => "BASEMENT", -2 => "SUB-BASEMENT", _ => "SUB-BASEMENT " + (-floorRank - 1), }; } private static void Redraw() { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00bb: 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_00e1: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) EnsureTexture(); bool hasActiveFloor = false; int activeFloorRank = 0; int num = int.MinValue; if (_staticDirty || _cachedFloorIndex != num) { RebuildStaticMap(hasActiveFloor, activeFloorRank, num); } Array.Copy(_staticPixels, _pixels, _pixels.Length); MapBounds cachedBounds = _cachedBounds; if (_cameras != null) { for (int i = 0; i < _cameras.Count; i++) { CCTVCamera cCTVCamera = _cameras[i]; if ((Object)(object)cCTVCamera == (Object)null) { continue; } bool flag = IsCameraBound(cCTVCamera); bool flag2 = cCTVCamera == QuadCameraAssignment.GetBoundCamera(MonitorFocus.ActiveSlot); if (flag || flag2 || IsWorldInsideBounds(((Component)cCTVCamera).transform.position, cachedBounds, 4f)) { Color32 color = (flag2 ? COLOR_ACTIVE : (flag ? COLOR_PAGE : COLOR_ALL)); int num2 = (flag2 ? 8 : (flag ? 4 : 3)); Vector2Int origin = WorldToPixel(((Component)cCTVCamera).transform.position, cachedBounds); DrawFilledCircle(((Vector2Int)(ref origin)).x, ((Vector2Int)(ref origin)).y, num2, color); DrawCircle(((Vector2Int)(ref origin)).x, ((Vector2Int)(ref origin)).y, num2 + 1, color); if (flag2) { DrawActiveCameraMarker(cCTVCamera, cachedBounds, origin); } } } } IReadOnlyList markers = ContractObjectiveProvider.GetMarkers(); DrawDynamicEntities(cachedBounds, hasActiveFloor, activeFloorRank); DrawSupportFixtures(cachedBounds, hasActiveFloor, activeFloorRank); DrawContractObjectiveRoom(markers, cachedBounds, hasActiveFloor, activeFloorRank); _mapTexture.SetPixels32(_pixels); _mapTexture.Apply(false, false); _dirty = false; } private static void RebuildStaticMap(bool hasActiveFloor, int activeFloorRank, int activeFloorIndex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) Fill(COLOR_BG); DrawGrid(); IReadOnlyList markers = ContractObjectiveProvider.GetMarkers(); List supportPositions = CollectSupportFixturePositions(); _cachedBounds = ComputeMapBounds(hasActiveFloor, activeFloorRank, markers, supportPositions); for (int i = 0; i < _tileFootprints.Count; i++) { TileFootprint footprint = _tileFootprints[i]; if (ShouldDrawFootprint(footprint, _cachedBounds, hasActiveFloor, activeFloorRank)) { DrawFootprintFill(footprint, _cachedBounds); } } DrawConnectionBridges(_cachedBounds, hasActiveFloor, activeFloorRank); for (int j = 0; j < _tileFootprints.Count; j++) { TileFootprint footprint2 = _tileFootprints[j]; if (ShouldDrawFootprint(footprint2, _cachedBounds, hasActiveFloor, activeFloorRank)) { DrawFootprintOutline(footprint2, _cachedBounds); } } DrawFloorLabel(_cachedBounds, hasActiveFloor, activeFloorRank); Array.Copy(_pixels, _staticPixels, _pixels.Length); _cachedFloorIndex = activeFloorIndex; _staticDirty = false; } private static void DrawDynamicEntities(MapBounds bounds, bool hasActiveFloor, int activeFloorRank) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && instance.allPlayerScripts != null) { for (int i = 0; i < instance.allPlayerScripts.Length; i++) { PlayerControllerB val = instance.allPlayerScripts[i]; if (!((Object)(object)val == (Object)null) && val.isPlayerControlled && !val.isPlayerDead && val.isInsideFactory && IsWorldOnActiveFloor(((Component)val).transform.position.y, hasActiveFloor, activeFloorRank) && IsWorldInsideBounds(((Component)val).transform.position, bounds, 2f)) { Vector2Int val2 = WorldToPixel(((Component)val).transform.position, bounds); DrawFilledCircle(((Vector2Int)(ref val2)).x, ((Vector2Int)(ref val2)).y, 4, COLOR_PLAYER); DrawCircle(((Vector2Int)(ref val2)).x, ((Vector2Int)(ref val2)).y, 5, COLOR_PLAYER); } } } RoundManager instance2 = RoundManager.Instance; if ((Object)(object)instance2 == (Object)null || instance2.SpawnedEnemies == null) { return; } for (int j = 0; j < instance2.SpawnedEnemies.Count; j++) { EnemyAI val3 = instance2.SpawnedEnemies[j]; if (!((Object)(object)val3 == (Object)null) && !val3.isEnemyDead && !val3.isOutside && !val3.isInsidePlayerShip && IsWorldOnActiveFloor(((Component)val3).transform.position.y, hasActiveFloor, activeFloorRank) && IsWorldInsideBounds(((Component)val3).transform.position, bounds, 2f)) { Vector2Int val4 = WorldToPixel(((Component)val3).transform.position, bounds); DrawDiamond(((Vector2Int)(ref val4)).x, ((Vector2Int)(ref val4)).y, 5, COLOR_ENEMY); } } } private static void DrawContractObjectiveRoom(IReadOnlyList markers, MapBounds bounds, bool hasActiveFloor, int activeFloorRank) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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) if (markers == null || markers.Count == 0) { return; } for (int i = 0; i < markers.Count; i++) { ContractObjectiveProvider.MarkerSnapshot markerSnapshot = markers[i]; if (!markerSnapshot.IsComplete && IsWorldOnActiveFloor(markerSnapshot.Position.y, hasActiveFloor, activeFloorRank) && IsWorldInsideBounds(markerSnapshot.Position, bounds, 2f)) { Color32 color = ((markerSnapshot.ColorKind == 1) ? COLOR_CONTRACT_DANGER : COLOR_CONTRACT); Vector2Int val = WorldToPixel(markerSnapshot.Position, bounds); DrawLine(((Vector2Int)(ref val)).x - 5, ((Vector2Int)(ref val)).y - 5, ((Vector2Int)(ref val)).x + 5, ((Vector2Int)(ref val)).y + 5, color); DrawLine(((Vector2Int)(ref val)).x - 5, ((Vector2Int)(ref val)).y + 5, ((Vector2Int)(ref val)).x + 5, ((Vector2Int)(ref val)).y - 5, color); break; } } } private static void DrawActiveCameraMarker(CCTVCamera camera, MapBounds bounds, Vector2Int origin) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) DrawCircle(((Vector2Int)(ref origin)).x, ((Vector2Int)(ref origin)).y, 13, COLOR_ACTIVE); DrawCircle(((Vector2Int)(ref origin)).x, ((Vector2Int)(ref origin)).y, 17, COLOR_FORWARD); DrawLine(((Vector2Int)(ref origin)).x - 22, ((Vector2Int)(ref origin)).y, ((Vector2Int)(ref origin)).x - 13, ((Vector2Int)(ref origin)).y, COLOR_ACTIVE); DrawLine(((Vector2Int)(ref origin)).x + 13, ((Vector2Int)(ref origin)).y, ((Vector2Int)(ref origin)).x + 22, ((Vector2Int)(ref origin)).y, COLOR_ACTIVE); DrawLine(((Vector2Int)(ref origin)).x, ((Vector2Int)(ref origin)).y - 22, ((Vector2Int)(ref origin)).x, ((Vector2Int)(ref origin)).y - 13, COLOR_ACTIVE); DrawLine(((Vector2Int)(ref origin)).x, ((Vector2Int)(ref origin)).y + 13, ((Vector2Int)(ref origin)).x, ((Vector2Int)(ref origin)).y + 22, COLOR_ACTIVE); DrawCameraCone(camera, bounds, origin); } private static void DrawCameraCone(CCTVCamera camera, MapBounds bounds, Vector2Int origin) { //IL_0006: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_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_008e: 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_0099: 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) //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_00af: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) Vector3 forward = ((Component)camera).transform.forward; forward.y = 0f; if (!(((Vector3)(ref forward)).sqrMagnitude < 1E-06f)) { ((Vector3)(ref forward)).Normalize(); Vector3 val = Vector3.Cross(Vector3.up, forward); Vector3 normalized = ((Vector3)(ref val)).normalized; Vector3 position = ((Component)camera).transform.position; Vector2Int val2 = WorldToPixel(position + forward * 11f, bounds); Vector2Int val3 = WorldToPixel(position + forward * 10f - normalized * 4.8f, bounds); Vector2Int val4 = WorldToPixel(position + forward * 10f + normalized * 4.8f, bounds); DrawThickLine(((Vector2Int)(ref origin)).x, ((Vector2Int)(ref origin)).y, ((Vector2Int)(ref val2)).x, ((Vector2Int)(ref val2)).y, COLOR_FORWARD, 2); DrawThickLine(((Vector2Int)(ref origin)).x, ((Vector2Int)(ref origin)).y, ((Vector2Int)(ref val3)).x, ((Vector2Int)(ref val3)).y, COLOR_FORWARD); DrawThickLine(((Vector2Int)(ref origin)).x, ((Vector2Int)(ref origin)).y, ((Vector2Int)(ref val4)).x, ((Vector2Int)(ref val4)).y, COLOR_FORWARD); DrawThickLine(((Vector2Int)(ref val3)).x, ((Vector2Int)(ref val3)).y, ((Vector2Int)(ref val4)).x, ((Vector2Int)(ref val4)).y, COLOR_BRIDGE); } } private static void Fill(Color32 color) { //IL_000a: 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) for (int i = 0; i < _pixels.Length; i++) { _pixels[i] = color; } } private static void DrawGrid() { //IL_000c: 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) for (int i = 0; i < 2048; i += 96) { DrawLine(i, 0, i, 863, COLOR_GRID); } for (int j = 0; j < 864; j += 96) { DrawLine(0, j, 2047, j, COLOR_GRID); } } private static void DrawFootprintFill(TileFootprint footprint, MapBounds bounds) { //IL_001b: 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_002d: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_006a: Unknown result type (might be due to invalid IL or missing references) if (footprint.Corners != null && footprint.Corners.Length == 4) { Vector2Int a = WorldToPixel(footprint.Corners[0], bounds); Vector2Int b = WorldToPixel(footprint.Corners[1], bounds); Vector2Int c = WorldToPixel(footprint.Corners[2], bounds); Vector2Int d = WorldToPixel(footprint.Corners[3], bounds); FillQuad(a, b, c, d, footprint.Primary ? COLOR_TILE_FILL_PRIMARY : COLOR_TILE_FILL); } } private static void DrawFootprintOutline(TileFootprint footprint, MapBounds bounds) { //IL_0023: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_005c: 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) //IL_006f: 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_00e3: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0104: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) if (footprint.Corners == null || footprint.Corners.Length != 4) { return; } Color32 color = (footprint.Primary ? COLOR_TILE : COLOR_TILE_SECONDARY); Vector2Int val = WorldToPixel(footprint.Corners[0], bounds); Vector2Int val2 = WorldToPixel(footprint.Corners[1], bounds); Vector2Int val3 = WorldToPixel(footprint.Corners[2], bounds); Vector2Int val4 = WorldToPixel(footprint.Corners[3], bounds); DoorwayPixel[] array = null; if (footprint.Doorways != null && footprint.Doorways.Length != 0) { array = new DoorwayPixel[footprint.Doorways.Length]; for (int i = 0; i < footprint.Doorways.Length; i++) { array[i] = new DoorwayPixel(WorldToPixel(footprint.Doorways[i].Position, bounds), footprint.Doorways[i]); } } DrawWallEdge(val, val2, array, color); DrawWallEdge(val2, val3, array, color); DrawWallEdge(val3, val4, array, color); DrawWallEdge(val4, val, array, color); } private static void DrawConnectionBridges(MapBounds bounds, bool hasActiveFloor, int activeFloorRank) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _tileFootprints.Count; i++) { TileFootprint footprint = _tileFootprints[i]; if (!IsFootprintOnActiveFloor(footprint, hasActiveFloor, activeFloorRank) || !FootprintIntersectsBounds(footprint, bounds, 2f) || footprint.Doorways == null) { continue; } for (int j = 0; j < footprint.Doorways.Length; j++) { DoorwayMarker doorwayMarker = footprint.Doorways[j]; if (!((Object)(object)doorwayMarker.ConnectedTile == (Object)null) && IsTileOnActiveFloor(doorwayMarker.ConnectedTile, hasActiveFloor, activeFloorRank) && ShouldDrawConnectionFrom(footprint.Tile, doorwayMarker.ConnectedTile) && SegmentIntersectsBounds(doorwayMarker.Position, doorwayMarker.ConnectedPosition, bounds, 2f)) { Vector2Int val = WorldToPixel(doorwayMarker.Position, bounds); Vector2Int val2 = WorldToPixel(doorwayMarker.ConnectedPosition, bounds); DrawThickLine(((Vector2Int)(ref val)).x, ((Vector2Int)(ref val)).y, ((Vector2Int)(ref val2)).x, ((Vector2Int)(ref val2)).y, COLOR_BRIDGE); } } } } private static void DrawWallEdge(Vector2Int from, Vector2Int to, DoorwayPixel[] doorPx, Color32 color) { //IL_0090: 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_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_0198: 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_01b5: Unknown result type (might be due to invalid IL or missing references) float num = ((Vector2Int)(ref to)).x - ((Vector2Int)(ref from)).x; float num2 = ((Vector2Int)(ref to)).y - ((Vector2Int)(ref from)).y; float num3 = Mathf.Sqrt(num * num + num2 * num2); if (num3 < 0.5f || (num3 < 9f && (doorPx == null || doorPx.Length == 0))) { return; } float num4 = num / num3; float num5 = num2 / num3; int num6 = Mathf.RoundToInt(0f - num5); int num7 = Mathf.RoundToInt(num4); int num8 = 0; float[] array = null; if (doorPx != null && doorPx.Length != 0) { array = new float[doorPx.Length]; for (int i = 0; i < doorPx.Length; i++) { Vector2Int pixel = doorPx[i].Pixel; float num9 = ((Vector2Int)(ref pixel)).x - ((Vector2Int)(ref from)).x; pixel = doorPx[i].Pixel; float num10 = ((Vector2Int)(ref pixel)).y - ((Vector2Int)(ref from)).y; float num11 = num9 * num4 + num10 * num5; if (!(num11 < -5f) && !(num11 > num3 + 5f) && !(Mathf.Abs(num9 * (0f - num5) + num10 * num4) > 12f)) { array[num8] = num11; num8++; } } } int num12 = Mathf.CeilToInt(num3); for (int j = 0; j <= num12; j++) { float num13 = j; bool flag = false; for (int k = 0; k < num8; k++) { if (num13 >= array[k] - 5f && num13 <= array[k] + 5f) { flag = true; break; } } if (!flag) { int num14 = Mathf.RoundToInt((float)((Vector2Int)(ref from)).x + num13 * num4); int num15 = Mathf.RoundToInt((float)((Vector2Int)(ref from)).y + num13 * num5); SetPixel(num14, num15, color); SetPixel(num14 + num6, num15 + num7, color); SetPixel(num14 - num6, num15 - num7, color); } } } private static DoorwayMarker[] CollectDoorwayMarkers(Tile tile) { //IL_0088: 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_008d: 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_009d: Unknown result type (might be due to invalid IL or missing references) if (tile?.UsedDoorways == null || tile.UsedDoorways.Count == 0) { return Array.Empty(); } List list = new List(tile.UsedDoorways.Count); foreach (Doorway usedDoorway in tile.UsedDoorways) { if (!((Object)(object)usedDoorway == (Object)null)) { Doorway connectedDoorway = usedDoorway.ConnectedDoorway; Tile connectedTile = (((Object)(object)connectedDoorway != (Object)null) ? connectedDoorway.Tile : null); Vector3 connectedPosition = (((Object)(object)connectedDoorway != (Object)null) ? ((Component)connectedDoorway).transform.position : ((Component)usedDoorway).transform.position); list.Add(new DoorwayMarker(((Component)usedDoorway).transform.position, connectedTile, connectedPosition)); } } return list.ToArray(); } private static bool IsCameraBound(CCTVCamera camera) { if ((Object)(object)camera == (Object)null) { return false; } for (int i = 0; i < 4; i++) { if (QuadCameraAssignment.GetBoundCamera(i) == camera) { return true; } } return false; } private static bool TryResolveActiveFloorRank(out int floorRank) { CCTVCamera boundCamera = QuadCameraAssignment.GetBoundCamera(MonitorFocus.ActiveSlot); if ((Object)(object)boundCamera != (Object)null) { floorRank = ResolveCameraFloorRank(boundCamera); return true; } floorRank = 0; return false; } private static int ResolveCameraFloorRank(CCTVCamera camera) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)camera == (Object)null) { return 0; } Tile owningTile = camera.OwningTile; if ((Object)(object)owningTile != (Object)null) { for (int i = 0; i < _tileFootprints.Count; i++) { if (_tileFootprints[i].Tile == owningTile) { return _tileFootprints[i].FloorIndex; } } } return ResolveFloorRank(((Component)camera).transform.position.y); } private static int ResolveFloorRank(float worldY) { int num = FindNearestFloorBandIndex(worldY); if (num < 0) { return 0; } return _floorBands[num].Rank; } private static bool IsWorldOnActiveFloor(float worldY, bool hasActiveFloor, int activeFloorRank) { if (hasActiveFloor) { return ResolveFloorRank(worldY) == activeFloorRank; } return true; } private static bool IsFootprintOnActiveFloor(TileFootprint footprint, bool hasActiveFloor, int activeFloorRank) { if (hasActiveFloor) { return footprint.FloorIndex == activeFloorRank; } return true; } private static bool IsTileOnActiveFloor(Tile tile, bool hasActiveFloor, int activeFloorRank) { if ((Object)(object)tile == (Object)null) { return false; } for (int i = 0; i < _tileFootprints.Count; i++) { TileFootprint footprint = _tileFootprints[i]; if (footprint.Tile == tile) { return IsFootprintOnActiveFloor(footprint, hasActiveFloor, activeFloorRank); } } return false; } private static bool ShouldDrawConnectionFrom(Tile a, Tile b) { if ((Object)(object)a == (Object)null || (Object)(object)b == (Object)null) { return false; } return true; } private static int FindNearestFloorBandIndex(float worldY) { if (_floorBands.Count == 0) { return -1; } int result = 0; float num = Mathf.Abs(worldY - _floorBands[0].CenterY); for (int i = 1; i < _floorBands.Count; i++) { float num2 = Mathf.Abs(worldY - _floorBands[i].CenterY); if (!(num2 >= num)) { result = i; num = num2; } } return result; } private static void CollapseIntermediateFloorNoiseBands() { if (_floorBands.Count < 3) { return; } float num = 0f; for (int i = 0; i < _floorBands.Count; i++) { num = Mathf.Max(num, _floorBands[i].Weight); } if (num <= 0f) { return; } for (int j = 1; j < _floorBands.Count - 1; j++) { FloorBand floorBand = _floorBands[j]; if (floorBand.TileCount <= 2 && !(floorBand.Weight > num * 0.22f)) { FloorBand floorBand2 = _floorBands[j - 1]; FloorBand floorBand3 = _floorBands[j + 1]; float num2 = Mathf.Abs(floorBand.CenterY - floorBand2.CenterY); float num3 = Mathf.Abs(floorBand3.CenterY - floorBand.CenterY); int index = ((num2 <= num3) ? (j - 1) : (j + 1)); _floorBands[index].Add(floorBand.CenterY, floorBand.Weight, floorBand.TileCount); _floorBands.RemoveAt(j); j--; } } } private static void DrawSupportFixtures(MapBounds bounds, bool hasActiveFloor, int activeFloorRank) { //IL_003e: 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) HashSet hashSet = new HashSet(); List activeTargets = CctvCommandTargetBridge.GetActiveTargets(); for (int i = 0; i < activeTargets.Count; i++) { CctvCommandTargetBridge.TargetInfo targetInfo = activeTargets[i]; if (targetInfo != null && !((Object)(object)targetInfo.Component == (Object)null) && IsWorldOnActiveFloor(targetInfo.Position.y, hasActiveFloor, activeFloorRank) && IsWorldInsideBounds(targetInfo.Position, bounds, 2f) && TryClassifySupportTarget(targetInfo.DisplayName, targetInfo.CommandHint, targetInfo.Component, out var isMainframe)) { hashSet.Add(((Object)targetInfo.Component).GetInstanceID()); DrawSupportIcon(targetInfo.Position, bounds, isMainframe); } } DrawSupportByType("MainframeSupport", bounds, hasActiveFloor, activeFloorRank, isMainframe: true, hashSet); } private static void DrawSupportByType(string typeName, MapBounds bounds, bool hasActiveFloor, int activeFloorRank, bool isMainframe, HashSet drawn) { //IL_0044: 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_008c: Unknown result type (might be due to invalid IL or missing references) Type type = Type.GetType("Y4NGZCompany.Facility.Mainframe." + typeName + ", LethalCCTV", throwOnError: false); if (type == null) { return; } Object[] array = Object.FindObjectsOfType(type); foreach (Object obj in array) { Component val = (Component)(object)((obj is Component) ? obj : null); if (!((Object)(object)val == (Object)null) && IsWorldOnActiveFloor(val.transform.position.y, hasActiveFloor, activeFloorRank) && IsWorldInsideBounds(val.transform.position, bounds, 2f)) { int instanceID = ((Object)val).GetInstanceID(); if (drawn == null || !drawn.Contains(instanceID)) { DrawSupportIcon(val.transform.position, bounds, isMainframe); } } } } private static List CollectSupportFixturePositions() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) List list = new List(8); List activeTargets = CctvCommandTargetBridge.GetActiveTargets(); for (int i = 0; i < activeTargets.Count; i++) { CctvCommandTargetBridge.TargetInfo targetInfo = activeTargets[i]; if (targetInfo != null && !((Object)(object)targetInfo.Component == (Object)null) && TryClassifySupportTarget(targetInfo.DisplayName, targetInfo.CommandHint, targetInfo.Component, out var _)) { list.Add(targetInfo.Position); } } CollectSupportTypePositions("MainframeSupport", list); return list; } private static bool TryClassifySupportTarget(string displayName, string commandHint, Component component, out bool isMainframe) { isMainframe = false; string text = displayName ?? ((object)component)?.GetType().Name ?? string.Empty; string text2 = commandHint ?? string.Empty; if (text.IndexOf("MAINFRAME", StringComparison.OrdinalIgnoreCase) >= 0 || (component != null && ((object)component).GetType().Name.IndexOf("Mainframe", StringComparison.OrdinalIgnoreCase) >= 0) || text2.IndexOf("hack", StringComparison.OrdinalIgnoreCase) >= 0) { isMainframe = true; return true; } if (text.IndexOf("ALARM", StringComparison.OrdinalIgnoreCase) >= 0 || (component != null && ((object)component).GetType().Name.IndexOf("Alarm", StringComparison.OrdinalIgnoreCase) >= 0)) { isMainframe = false; return true; } return false; } private static void DrawSupportIcon(Vector3 worldPosition, MapBounds bounds, bool isMainframe) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_00c7: Unknown result type (might be due to invalid IL or missing references) Vector2Int val = WorldToPixel(worldPosition, bounds); if (isMainframe) { DrawSquare(((Vector2Int)(ref val)).x, ((Vector2Int)(ref val)).y, 10, COLOR_SUPPORT); DrawSquare(((Vector2Int)(ref val)).x, ((Vector2Int)(ref val)).y, 9, COLOR_SUPPORT); DrawLine(((Vector2Int)(ref val)).x - 6, ((Vector2Int)(ref val)).y, ((Vector2Int)(ref val)).x + 6, ((Vector2Int)(ref val)).y, COLOR_SUPPORT_CORE); DrawLine(((Vector2Int)(ref val)).x, ((Vector2Int)(ref val)).y - 6, ((Vector2Int)(ref val)).x, ((Vector2Int)(ref val)).y + 6, COLOR_SUPPORT_CORE); DrawFilledCircle(((Vector2Int)(ref val)).x, ((Vector2Int)(ref val)).y, 2, COLOR_SUPPORT_CORE); DrawTinyText(((Vector2Int)(ref val)).x + 13, ((Vector2Int)(ref val)).y - 3, "MF", COLOR_SUPPORT); } else { DrawDiamond(((Vector2Int)(ref val)).x, ((Vector2Int)(ref val)).y, 9, COLOR_SUPPORT); DrawDiamond(((Vector2Int)(ref val)).x, ((Vector2Int)(ref val)).y, 6, COLOR_BG); DrawDiamond(((Vector2Int)(ref val)).x, ((Vector2Int)(ref val)).y, 4, COLOR_SUPPORT_CORE); DrawTinyText(((Vector2Int)(ref val)).x + 12, ((Vector2Int)(ref val)).y - 3, "AL", COLOR_SUPPORT); } } private static void CollectSupportTypePositions(string typeName, List positions) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) Type type = Type.GetType("Y4NGZCompany.Facility.Mainframe." + typeName + ", LethalCCTV", throwOnError: false); if (type == null) { return; } Object[] array = Object.FindObjectsOfType(type); foreach (Object obj in array) { Component val = (Component)(object)((obj is Component) ? obj : null); if ((Object)(object)val != (Object)null) { positions.Add(val.transform.position); } } } private static MapBounds ComputeMapBounds(bool hasActiveFloor, int activeFloorRank, IReadOnlyList contractMarkers = null, List supportPositions = null) { //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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0075: 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_0089: 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_009b: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0174: 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_0184: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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_01a0: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) List list = CollectInteriorPageRegionBoundsPoints(); bool flag = list.Count > 0; if (!flag && !HasVisibleMarkers(contractMarkers, hasActiveFloor, activeFloorRank) && !HasVisiblePositions(supportPositions, hasActiveFloor, activeFloorRank)) { return new MapBounds(-34f, 34f, -34f, 34f); } Vector3 val = ResolveFirstBoundsPoint(list, contractMarkers, supportPositions, hasActiveFloor, activeFloorRank); float x = val.x; float x2 = val.x; float z = val.z; float z2 = val.z; for (int i = 0; i < list.Count; i++) { Vector3 val2 = list[i]; if (val2.x < x) { x = val2.x; } if (val2.x > x2) { x2 = val2.x; } if (val2.z < z) { z = val2.z; } if (val2.z > z2) { z2 = val2.z; } } if (!flag && contractMarkers != null) { for (int j = 0; j < contractMarkers.Count; j++) { Vector3 position = contractMarkers[j].Position; if (IsWorldOnActiveFloor(position.y, hasActiveFloor, activeFloorRank)) { if (position.x < x) { x = position.x; } if (position.x > x2) { x2 = position.x; } if (position.z < z) { z = position.z; } if (position.z > z2) { z2 = position.z; } } } } if (!flag && supportPositions != null) { for (int k = 0; k < supportPositions.Count; k++) { Vector3 val3 = supportPositions[k]; if (IsWorldOnActiveFloor(val3.y, hasActiveFloor, activeFloorRank)) { if (val3.x < x) { x = val3.x; } if (val3.x > x2) { x2 = val3.x; } if (val3.z < z) { z = val3.z; } if (val3.z > z2) { z2 = val3.z; } } } } float num = Mathf.Max(x2 - x, 34f); float num2 = Mathf.Max(z2 - z, 34f); float num3 = (x + x2) * 0.5f; float num4 = (z + z2) * 0.5f; float num5 = 2.3703704f; if (num / num2 > num5) { num2 = num / num5; } else { num = num2 * num5; } float num6 = Mathf.Max(2f, Mathf.Max(num, num2) * 0.02f); num += num6 * 2f; num2 += num6 * 2f; num *= 0.96f; num2 *= 0.96f; return new MapBounds(num3 - num * 0.5f, num3 + num * 0.5f, num4 - num2 * 0.5f, num4 + num2 * 0.5f); } private static List CollectInteriorBoundsPoints(bool hasActiveFloor, int activeFloorRank) { //IL_003e: 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_00e1: Unknown result type (might be due to invalid IL or missing references) List list = new List(_mapPoints.Count); for (int i = 0; i < _tileFootprints.Count; i++) { TileFootprint footprint = _tileFootprints[i]; if (IsFootprintOnActiveFloor(footprint, hasActiveFloor, activeFloorRank) && footprint.Corners != null) { for (int j = 0; j < footprint.Corners.Length; j++) { list.Add(footprint.Corners[j]); } } } if (list.Count == 0 && _mapPoints.Count > 0) { for (int k = 0; k < _mapPoints.Count; k++) { list.Add(_mapPoints[k]); } } if (_cameras != null) { for (int l = 0; l < _cameras.Count; l++) { CCTVCamera cCTVCamera = _cameras[l]; if (!((Object)(object)cCTVCamera == (Object)null) && (!hasActiveFloor || ResolveCameraFloorRank(cCTVCamera) == activeFloorRank)) { list.Add(((Component)cCTVCamera).transform.position); } } } return list; } private static List CollectInteriorPageRegionBoundsPoints() { //IL_0061: 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) List list = new List(4); for (int i = 0; i < 4; i++) { CCTVCamera boundCamera = QuadCameraAssignment.GetBoundCamera(i); if (!((Object)(object)boundCamera == (Object)null)) { list.Add(boundCamera); } } if (list.Count == 0) { return CollectInteriorBoundsPoints(hasActiveFloor: false, 0); } float radiusSq = 1936f; List list2 = new List(128); for (int j = 0; j < list.Count; j++) { list2.Add(((Component)list[j]).transform.position); } for (int k = 0; k < _tileFootprints.Count; k++) { TileFootprint footprint = _tileFootprints[k]; if (footprint.Corners != null && IsFootprintNearAnyAnchor(footprint, list, radiusSq)) { for (int l = 0; l < footprint.Corners.Length; l++) { list2.Add(footprint.Corners[l]); } } } if (list2.Count < list.Count + 4) { return CollectInteriorBoundsPoints(hasActiveFloor: false, 0); } return list2; } private static bool IsFootprintNearAnyAnchor(TileFootprint footprint, List anchors, float radiusSq) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) //IL_0054: 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 (anchors == null || footprint.Corners == null) { return false; } for (int i = 0; i < anchors.Count; i++) { CCTVCamera cCTVCamera = anchors[i]; if (!((Object)(object)cCTVCamera == (Object)null) && ResolveCameraFloorRank(cCTVCamera) == footprint.FloorIndex) { Vector3 val = footprint.Center - ((Component)cCTVCamera).transform.position; if (val.x * val.x + val.z * val.z <= radiusSq) { return true; } } } return false; } private static bool ShouldDrawFootprint(TileFootprint footprint, MapBounds bounds, bool hasActiveFloor, int activeFloorRank) { if (IsFootprintOnActiveFloor(footprint, hasActiveFloor, activeFloorRank)) { return FootprintIntersectsBounds(footprint, bounds, 2f); } return false; } private static bool FootprintIntersectsBounds(TileFootprint footprint, MapBounds bounds, float margin) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0079: 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_008b: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) if (footprint.Corners == null || footprint.Corners.Length == 0) { return false; } float x = footprint.Corners[0].x; float x2 = footprint.Corners[0].x; float z = footprint.Corners[0].z; float z2 = footprint.Corners[0].z; for (int i = 1; i < footprint.Corners.Length; i++) { Vector3 val = footprint.Corners[i]; if (val.x < x) { x = val.x; } if (val.x > x2) { x2 = val.x; } if (val.z < z) { z = val.z; } if (val.z > z2) { z2 = val.z; } } if (x2 >= bounds.MinX - margin && x <= bounds.MaxX + margin && z2 >= bounds.MinZ - margin) { return z <= bounds.MaxZ + margin; } return false; } private static bool SegmentIntersectsBounds(Vector3 a, Vector3 b, MapBounds bounds, float margin) { //IL_0000: 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_0012: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_003b: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Min(a.x, b.x); float num2 = Mathf.Max(a.x, b.x); float num3 = Mathf.Min(a.z, b.z); float num4 = Mathf.Max(a.z, b.z); if (num2 >= bounds.MinX - margin && num <= bounds.MaxX + margin && num4 >= bounds.MinZ - margin) { return num3 <= bounds.MaxZ + margin; } return false; } private static bool IsWorldInsideBounds(Vector3 world, MapBounds bounds, float margin) { //IL_0000: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (world.x >= bounds.MinX - margin && world.x <= bounds.MaxX + margin && world.z >= bounds.MinZ - margin) { return world.z <= bounds.MaxZ + margin; } return false; } private static bool HasVisibleMarkers(IReadOnlyList markers, bool hasActiveFloor, int activeFloorRank) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (markers == null) { return false; } for (int i = 0; i < markers.Count; i++) { if (IsWorldOnActiveFloor(markers[i].Position.y, hasActiveFloor, activeFloorRank)) { return true; } } return false; } private static bool HasVisiblePositions(List positions, bool hasActiveFloor, int activeFloorRank) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (positions == null) { return false; } for (int i = 0; i < positions.Count; i++) { if (IsWorldOnActiveFloor(positions[i].y, hasActiveFloor, activeFloorRank)) { return true; } } return false; } private static Vector3 ResolveFirstBoundsPoint(List points, IReadOnlyList contractMarkers, List supportPositions, bool hasActiveFloor, int activeFloorRank) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (points != null && points.Count > 0) { return points[0]; } if (contractMarkers != null) { for (int i = 0; i < contractMarkers.Count; i++) { if (IsWorldOnActiveFloor(contractMarkers[i].Position.y, hasActiveFloor, activeFloorRank)) { return contractMarkers[i].Position; } } } if (supportPositions != null) { for (int j = 0; j < supportPositions.Count; j++) { if (IsWorldOnActiveFloor(supportPositions[j].y, hasActiveFloor, activeFloorRank)) { return supportPositions[j]; } } } return Vector3.zero; } private static Vector2Int WorldToPixel(Vector3 world, MapBounds bounds) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.InverseLerp(bounds.MinX, bounds.MaxX, world.x); float num2 = Mathf.InverseLerp(bounds.MinZ, bounds.MaxZ, world.z); int num3 = Mathf.Clamp(Mathf.RoundToInt(num * 2047f), 0, 2047); int num4 = Mathf.Clamp(Mathf.RoundToInt((1f - num2) * 863f), 0, 863); return new Vector2Int(num3, num4); } private static void DrawFilledCircle(int cx, int cy, int radius, Color32 color) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) int num = radius * radius; for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { if (j * j + i * i <= num) { SetPixel(cx + j, cy + i, color); } } } } private static void DrawCircle(int cx, int cy, int radius, Color32 color) { //IL_0011: 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_0029: 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_0041: 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) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) int num = radius; int num2 = 0; int num3 = 0; while (num >= num2) { SetPixel(cx + num, cy + num2, color); SetPixel(cx + num2, cy + num, color); SetPixel(cx - num2, cy + num, color); SetPixel(cx - num, cy + num2, color); SetPixel(cx - num, cy - num2, color); SetPixel(cx - num2, cy - num, color); SetPixel(cx + num2, cy - num, color); SetPixel(cx + num, cy - num2, color); num2++; if (num3 <= 0) { num3 += 2 * num2 + 1; } if (num3 > 0) { num--; num3 -= 2 * num + 1; } } } private static void DrawDiamond(int cx, int cy, int radius, Color32 color) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) for (int i = -radius; i <= radius; i++) { int num = radius - Mathf.Abs(i); for (int j = -num; j <= num; j++) { SetPixel(cx + j, cy + i, color); } } } private static void DrawSquare(int cx, int cy, int radius, Color32 color) { //IL_000c: 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_0030: 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) DrawLine(cx - radius, cy - radius, cx + radius, cy - radius, color); DrawLine(cx + radius, cy - radius, cx + radius, cy + radius, color); DrawLine(cx + radius, cy + radius, cx - radius, cy + radius, color); DrawLine(cx - radius, cy + radius, cx - radius, cy - radius, color); } private static void FillQuad(Vector2Int a, Vector2Int b, Vector2Int c, Vector2Int d, Color32 color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) FillTriangle(a, b, c, color); FillTriangle(a, c, d, color); } private static void FillTriangle(Vector2Int a, Vector2Int b, Vector2Int c, Color32 color) { //IL_00a0: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00d8: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_0128: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(0, Mathf.Min(((Vector2Int)(ref a)).x, Mathf.Min(((Vector2Int)(ref b)).x, ((Vector2Int)(ref c)).x))); int num2 = Mathf.Min(2047, Mathf.Max(((Vector2Int)(ref a)).x, Mathf.Max(((Vector2Int)(ref b)).x, ((Vector2Int)(ref c)).x))); int num3 = Mathf.Max(0, Mathf.Min(((Vector2Int)(ref a)).y, Mathf.Min(((Vector2Int)(ref b)).y, ((Vector2Int)(ref c)).y))); int num4 = Mathf.Min(863, Mathf.Max(((Vector2Int)(ref a)).y, Mathf.Max(((Vector2Int)(ref b)).y, ((Vector2Int)(ref c)).y))); if (Mathf.Abs(Edge(a, b, c)) < 0.5f) { return; } Vector2Int c2 = default(Vector2Int); for (int i = num3; i <= num4; i++) { for (int j = num; j <= num2; j++) { ((Vector2Int)(ref c2))..ctor(j, i); float num5 = Edge(b, c, c2); float num6 = Edge(c, a, c2); float num7 = Edge(a, b, c2); if ((num5 >= 0f && num6 >= 0f && num7 >= 0f) || (num5 <= 0f && num6 <= 0f && num7 <= 0f)) { SetPixel(j, i, color); } } } } private static float Edge(Vector2Int a, Vector2Int b, Vector2Int c) { return (((Vector2Int)(ref c)).x - ((Vector2Int)(ref a)).x) * (((Vector2Int)(ref b)).y - ((Vector2Int)(ref a)).y) - (((Vector2Int)(ref c)).y - ((Vector2Int)(ref a)).y) * (((Vector2Int)(ref b)).x - ((Vector2Int)(ref a)).x); } private static void DrawFloorLabel(MapBounds bounds, bool hasActiveFloor, int activeFloorRank) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (hasActiveFloor) { DrawTinyText(20, 18, FormatFloorLabel(activeFloorRank), COLOR_LABEL); } } private static void DrawTinyText(int x, int y, string text, Color32 color) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(text)) { int num = x; for (int i = 0; i < text.Length; i++) { DrawTinyChar(num, y, text[i], color); num += 6; } } } private static void DrawTinyChar(int x, int y, char ch, Color32 color) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) string[] array = TinyGlyph(ch); if (array == null) { return; } for (int i = 0; i < array.Length; i++) { string text = array[i]; for (int j = 0; j < text.Length; j++) { if (text[j] != ' ') { SetPixel(x + j, y + i, color); } } } } private static string[] TinyGlyph(char ch) { return char.ToUpperInvariant(ch) switch { 'A' => new string[5] { " ## ", "# #", "####", "# #", "# #" }, 'B' => new string[5] { "### ", "# #", "### ", "# #", "### " }, 'E' => new string[5] { "####", "# ", "### ", "# ", "####" }, 'F' => new string[5] { "####", "# ", "### ", "# ", "# " }, 'H' => new string[5] { "# #", "# #", "####", "# #", "# #" }, 'L' => new string[5] { "# ", "# ", "# ", "# ", "####" }, 'M' => new string[5] { "# #", "####", "####", "# #", "# #" }, 'N' => new string[5] { "# #", "## #", "# ##", "# #", "# #" }, 'O' => new string[5] { " ## ", "# #", "# #", "# #", " ## " }, 'R' => new string[5] { "### ", "# #", "### ", "# # ", "# #" }, 'S' => new string[5] { " ###", "# ", " ## ", " #", "### " }, 'T' => new string[5] { "####", " ## ", " ## ", " ## ", " ## " }, 'U' => new string[5] { "# #", "# #", "# #", "# #", " ## " }, '-' => new string[5] { " ", " ", "### ", " ", " " }, ' ' => new string[5] { " ", " ", " ", " ", " " }, '1' => new string[5] { " # ", "## ", " # ", " # ", "### " }, '2' => new string[5] { "### ", " #", " ## ", "# ", "####" }, '3' => new string[5] { "### ", " #", " ## ", " #", "### " }, '4' => new string[5] { "# #", "# #", "####", " #", " #" }, '5' => new string[5] { "####", "# ", "### ", " #", "### " }, '6' => new string[5] { " ## ", "# ", "### ", "# #", " ## " }, '7' => new string[5] { "####", " #", " # ", " # ", " # " }, '8' => new string[5] { " ## ", "# #", " ## ", "# #", " ## " }, '9' => new string[5] { " ## ", "# #", " ###", " #", " ## " }, '0' => new string[5] { " ## ", "# #", "# #", "# #", " ## " }, _ => null, }; } private static void DrawThickLine(int x0, int y0, int x1, int y1, Color32 color, int radius = 1) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { if (j * j + i * i <= radius * radius) { DrawLine(x0 + j, y0 + i, x1 + j, y1 + i, color); } } } } private static void DrawLine(int x0, int y0, int x1, int y1, Color32 color) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Abs(x1 - x0); int num2 = ((x0 < x1) ? 1 : (-1)); int num3 = -Mathf.Abs(y1 - y0); int num4 = ((y0 < y1) ? 1 : (-1)); int num5 = num + num3; while (true) { SetPixel(x0, y0, color); if (x0 != x1 || y0 != y1) { int num6 = 2 * num5; if (num6 >= num3) { num5 += num3; x0 += num2; } if (num6 <= num) { num5 += num; y0 += num4; } continue; } break; } } private static void SetPixel(int x, int y, Color32 color) { //IL_0027: 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) if (x >= 0 && x < 2048 && y >= 0 && y < 864) { _pixels[y * 2048 + x] = color; } } } internal static class ShipTurretController { private sealed class RaycastHitDistanceComparer : IComparer { internal static readonly RaycastHitDistanceComparer Instance = new RaycastHitDistanceComparer(); public int Compare(RaycastHit a, RaycastHit b) { return ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance); } } [Serializable] private sealed class TurretPlacementProfile { public List placements = new List(); } [Serializable] private sealed class TurretPlacementRecord { public string layout; public Vector3 localPosition; public Vector3 localEuler; } [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnReceiveShotRequest; public static HandleNamedMessageDelegate <1>__OnReceiveShotResult; } private const string BundleFileName = "shipturret.turretbundle"; private const string MsgShotRequest = "LethalCCTV.TurretShotRequest"; private const string MsgShotResult = "LethalCCTV.TurretShotResult"; private const float ShotCooldownSeconds = 3f; private const float ShotDistance = 260f; private const int ShotDamage = 10; private const int TurretHitId = 4107; private const int PlayerCameraMask = 591075327; private const int UiLayer = 5; private const int HelmetVisorLayer = 7; private const int ScanNodeLayer = 22; private const int TurretCameraMask = 591075167; private const float VisualTargetMaxDimensionMeters = 4.35f; private const float RotateCueMaxSeconds = 0.38f; private const float ZoomCueMaxSeconds = 0.46f; private const float AudioDirectionResetSeconds = 0.55f; private const float RecoilDurationSeconds = 0.34f; private const float RecoilDistance = 0.82f; private const float RecoilPitchKick = -4.6f; private const float CameraRecoilDistance = 0.16f; private const float CameraRecoilPitch = -3.4f; private const float EnemyShotRadius = 0.72f; private const float EnemyPriorityLeeway = 1.15f; private static readonly Dictionary ServerNextShotAt = new Dictionary(); private static readonly RaycastHit[] ShotHits = (RaycastHit[])(object)new RaycastHit[48]; private static readonly RaycastHit[] ShotSphereHits = (RaycastHit[])(object)new RaycastHit[96]; private static readonly string[] LayoutPresets = new string[4] { "Vanilla", "Wider", "TwoStory", "WiderAndTwoStory" }; private static readonly Vector3 PitchPivotLocalPosition = new Vector3(0f, 0.55f, 0f); private static GameObject _root; private static Transform _yawPivot; private static Transform _pitchPivot; private static Transform _fixtureVisualRoot; private static Transform _gunVisualRoot; private static Transform _muzzle; private static Camera _camera; private static RenderTexture _renderTexture; private static AudioSource _fireSource; private static AudioSource _rotateSource; private static AudioSource _zoomSource; private static AudioClip[] _fireClips; private static AudioClip _rotateClip; private static AudioClip _zoomClip; private static GameObject _visualPrefab; private static GameObject _dustExplosionPrefab; private static Material _impactDustMaterial; private static Material _muzzleFlashMaterial; private static Material _muzzleSmokeMaterial; private static Texture2D _softParticleTexture; private static AssetBundle _bundle; private static bool _bundleLoadAttempted; private static bool _networkHandlersRegistered; private static NetworkManager _registeredNetworkManager; private static float _yawDeg; private static float _pitchDeg = 8f; private static float _zoom; private static float _nextLocalShotAt; private static float _lastRotateAt; private static float _lastZoomAt; private static float _lastRotateCueAt; private static float _lastZoomCueAt; private static float _rotateCueStopAt; private static float _zoomCueStopAt; private static int _lastRotateDirection; private static int _lastZoomDirection; private static float _recoilStartedAt = -100f; private static string _lastAppliedLayout; private static string _lastStatus = "READY"; private static float _statusVisibleUntil; private static TurretPlacementProfile _profile; private static bool _profileLoaded; private static bool _placementActive; private static string _placementLayout = "Vanilla"; private static Vector3 _placementStartLocalPosition; private static Quaternion _placementStartLocalRotation; private static PlayerControllerB _placementPlayer; private static Camera _placementCamera; private static bool _placementCapturedInputState; private static CursorLockMode _placementSavedLock; private static bool _placementSavedCursorVisible; private static bool _placementSavedDisableLookInput; private static bool _placementSavedDisableMoveInput; private static bool _placementCapturedCameraTransform; private static Vector3 _placementSavedCameraLocalPosition; private static Quaternion _placementSavedCameraLocalRotation; private const float LayoutRecheckIntervalSeconds = 1f; private static float _nextLayoutRecheckAt; internal static bool IsUnlocked => CCTVShipSystemsBridge.HasTurretUpgrade(); internal static bool PlacementActive => _placementActive; internal static Texture ViewTexture => (Texture)(object)_renderTexture; internal static float Zoom => _zoom; private static string PlacementProfilePath => Y4NGZCompanyPaths.LocalDataFile("ship-turret-placements.local.json"); internal static void Initialize() { EnsurePlacementProfileLoaded(); } internal static void Shutdown() { UnregisterNetworkHandlers(); RestorePlacementInputCapture(); if ((Object)(object)_camera != (Object)null) { _camera.targetTexture = null; } DestroyTurret(); if ((Object)(object)_renderTexture != (Object)null) { _renderTexture.Release(); Object.Destroy((Object)(object)_renderTexture); _renderTexture = null; } if ((Object)(object)_bundle != (Object)null) { _bundle.Unload(false); _bundle = null; } if ((Object)(object)_impactDustMaterial != (Object)null) { Object.Destroy((Object)(object)_impactDustMaterial); _impactDustMaterial = null; } if ((Object)(object)_muzzleFlashMaterial != (Object)null) { Object.Destroy((Object)(object)_muzzleFlashMaterial); _muzzleFlashMaterial = null; } if ((Object)(object)_muzzleSmokeMaterial != (Object)null) { Object.Destroy((Object)(object)_muzzleSmokeMaterial); _muzzleSmokeMaterial = null; } if ((Object)(object)_softParticleTexture != (Object)null) { Object.Destroy((Object)(object)_softParticleTexture); _softParticleTexture = null; } _bundleLoadAttempted = false; _profileLoaded = false; _profile = null; ServerNextShotAt.Clear(); } internal static void Tick() { EnsureNetworkHandlers(); if (!IsUnlocked && !_placementActive) { DestroyTurret(); return; } EnsureTurretPresent(); ApplyLayoutPlacementIfNeeded(); TickPlacementEditor(); TickAudioCues(); TickRecoil(); if (MonitorFocus.IsFocused && MonitorFocus.IsTurretPageActive) { RenderView(); } } internal static void ApplyLookDelta(Vector2 rawLook) { //IL_0041: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_00c9: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null || ((Vector2)(ref rawLook)).sqrMagnitude < 1E-08f) { return; } float num = (float)IngamePlayerSettings.Instance.settings.lookSensitivity * 0.008f; if (IngamePlayerSettings.Instance.flipCamera) { rawLook.x = 0f - rawLook.x; } if (IngamePlayerSettings.Instance.settings.invertYAxis) { rawLook.y *= -1f; } Vector2 val = rawLook * num * 0.7f; float num2 = 82f * Mathf.Max(Time.unscaledDeltaTime, 1f / 120f); if (((Vector2)(ref val)).magnitude > num2) { val = ((Vector2)(ref val)).normalized * num2; } _yawDeg = WrapAngle(_yawDeg + val.x); _pitchDeg = Mathf.Clamp(_pitchDeg - val.y, -28f, 54f); ApplyAim(); if (((Vector2)(ref val)).sqrMagnitude > 0.0001f) { float unscaledTime = Time.unscaledTime; int num3 = ResolveDominantDirection(val); _lastRotateAt = unscaledTime; EnsureAudioSources(); if (num3 != 0 && num3 != _lastRotateDirection) { _lastRotateDirection = num3; _lastRotateCueAt = unscaledTime; _rotateCueStopAt = unscaledTime + 0.38f; PlayShortCue(_rotateSource, _rotateClip, 0.34f); } } } internal static void HandleZoomScroll(float scroll) { if (!(Mathf.Abs(scroll) < 0.01f)) { _zoom = Mathf.Clamp01(_zoom + Mathf.Sign(scroll) * 0.08f); if ((Object)(object)_camera != (Object)null) { _camera.fieldOfView = Mathf.Lerp(72f, 28f, _zoom); } float unscaledTime = Time.unscaledTime; int num = ((scroll > 0f) ? 1 : (-1)); _lastZoomAt = unscaledTime; EnsureAudioSources(); if (num != _lastZoomDirection) { _lastZoomDirection = num; _lastZoomCueAt = unscaledTime; _zoomCueStopAt = unscaledTime + 0.46f; PlayShortCue(_zoomSource, _zoomClip, 0.3f); } } } internal static void TryFire() { //IL_006c: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_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_00a8: 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_00ee: 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_0109: Unknown result type (might be due to invalid IL or missing references) if (!MonitorFocus.IsTurretPageActive || !IsUnlocked) { return; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup < _nextLocalShotAt) { SetStatus($"COOLDOWN {Mathf.CeilToInt(_nextLocalShotAt - realtimeSinceStartup)}S", 0.6f); return; } EnsureTurretPresent(); if ((Object)(object)_camera == (Object)null) { return; } _nextLocalShotAt = realtimeSinceStartup + 3f; Vector3 position = ((Component)_camera).transform.position; Vector3 forward = ((Component)_camera).transform.forward; Vector3 normalized = ((Vector3)(ref forward)).normalized; NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && singleton.IsServer) { ProcessShotRequest(singleton.LocalClientId, position, normalized); return; } if ((Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null || !singleton.IsClient || !singleton.IsListening) { SetStatus("NETWORK OFFLINE", 1.2f); return; } FastBufferWriter writer = default(FastBufferWriter); ((FastBufferWriter)(ref writer))..ctor(96, (Allocator)2, -1); try { WriteVector(ref writer, position); WriteVector(ref writer, normalized); singleton.CustomMessagingManager.SendNamedMessage("LethalCCTV.TurretShotRequest", 0uL, writer, (NetworkDelivery)3); } finally { ((FastBufferWriter)(ref writer)).Dispose(); } } internal static string BuildStatsBlock(string walkie) { float num = Mathf.Clamp01(CCTVShipSystemsBridge.GetPowerFraction()); float num2 = Mathf.Max(0f, _nextLocalShotAt - Time.realtimeSinceStartup); string text = ((Time.unscaledTime <= _statusVisibleUntil) ? _lastStatus : ((num2 > 0f) ? "CHARGING" : "READY")); return "TURRET\nSHIP PWR " + Mathf.RoundToInt(num * 100f) + "%\nSHOT 10%\nSTATUS " + text + "\nCOOLDOWN " + num2.ToString("0.0") + "S\nZOOM " + FormatZoom() + "\nWALKIE " + walkie; } internal static string GetDebugStatus() { string text = ResolveLayoutName(); TurretPlacementRecord placement; bool flag = TryGetPlacement(text, out placement); return string.Format("layout={0} bought={1} current={2} editing={3} presets={4}", text, IsUnlocked, flag ? "saved" : "default", _placementActive, BuildPresetStatus()); } public static void StartDebugPlacement() { StartDebugPlacement(null); } public static void StartDebugPlacement(string layoutName) { //IL_003c: 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_0050: 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) EnsurePlacementProfileLoaded(); _placementLayout = NormalizeLayoutName(layoutName); _placementActive = true; EnsureTurretPresent(); ApplyPlacementForLayout(_placementLayout); if ((Object)(object)_root != (Object)null) { _placementStartLocalPosition = _root.transform.localPosition; _placementStartLocalRotation = _root.transform.localRotation; } BeginPlacementInputCapture(); EnsurePlacementCamera(); UpdatePlacementCameraPose(); SetStatus("PLACEMENT ACTIVE", 2f); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV.Turret] Placement editor started for layout " + _placementLayout + ".")); } } public static void ShowDebugPreview() { EnsurePlacementProfileLoaded(); EnsureTurretPresent(); ApplyLayoutPlacementIfNeeded(force: true); SetStatus("PREVIEW SHOWN", 1.5f); } public static void ClearDebugPreview() { _placementActive = false; RestorePlacementInputCapture(); if (!IsUnlocked) { DestroyTurret(); } SetStatus("PREVIEW CLEARED", 1.5f); } private static void EnsureTurretPresent() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015c: 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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018b: 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_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: 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) if (!((Object)(object)_root != (Object)null)) { EnsureAssetsLoaded(); EnsureRenderTexture(); Transform val = ResolveShipRoot(); _root = new GameObject("LethalCCTV_ShipTurret"); if ((Object)(object)val != (Object)null) { _root.transform.SetParent(val, false); } _yawPivot = new GameObject("YawPivot").transform; _yawPivot.SetParent(_root.transform, false); _fixtureVisualRoot = new GameObject("FixtureVisualRoot").transform; _fixtureVisualRoot.SetParent(_root.transform, false); _pitchPivot = new GameObject("PitchPivot").transform; _pitchPivot.SetParent(_yawPivot, false); _pitchPivot.localPosition = PitchPivotLocalPosition; _gunVisualRoot = new GameObject("GunVisualRoot").transform; _gunVisualRoot.SetParent(_pitchPivot, false); BuildVisual(_fixtureVisualRoot, _gunVisualRoot); _muzzle = new GameObject("Muzzle").transform; _muzzle.SetParent(_pitchPivot, false); _muzzle.localPosition = new Vector3(0f, 0.22f, 3.05f); GameObject val2 = new GameObject("TurretCamera"); val2.transform.SetParent(_pitchPivot, false); val2.transform.localPosition = new Vector3(0f, 1.12f, 2.35f); val2.transform.localRotation = Quaternion.identity; _camera = val2.AddComponent(); ((Behaviour)_camera).enabled = false; _camera.targetTexture = _renderTexture; _camera.clearFlags = (CameraClearFlags)2; _camera.backgroundColor = Color.black; _camera.cullingMask = 591075167; _camera.nearClipPlane = 0.03f; _camera.farClipPlane = 260f; _camera.fieldOfView = 72f; HDAdditionalCameraData obj = val2.AddComponent(); obj.clearColorMode = (ClearColorMode)1; obj.backgroundColorHDR = Color.black; EnsureAudioSources(); ApplyLayoutPlacementIfNeeded(force: true); ApplyAim(); } } private static void DestroyTurret() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _yawPivot = null; _pitchPivot = null; _fixtureVisualRoot = null; _gunVisualRoot = null; _muzzle = null; _camera = null; _fireSource = null; _rotateSource = null; _zoomSource = null; _lastAppliedLayout = null; _lastRotateDirection = 0; _lastZoomDirection = 0; _recoilStartedAt = -100f; } private static void ApplyAim() { //IL_0027: 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_0087: 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_00e4: Unknown result type (might be due to invalid IL or missing references) float currentRecoil = GetCurrentRecoil01(); if ((Object)(object)_yawPivot != (Object)null) { _yawPivot.localRotation = Quaternion.Euler(0f, _yawDeg, 0f); } if ((Object)(object)_pitchPivot != (Object)null) { _pitchPivot.localRotation = Quaternion.Euler(_pitchDeg + -4.6f * currentRecoil, 0f, 0f); } if ((Object)(object)_gunVisualRoot != (Object)null) { _gunVisualRoot.localPosition = new Vector3(0f, 0f, -0.82f * currentRecoil); } if ((Object)(object)_camera != (Object)null) { ((Component)_camera).transform.localPosition = new Vector3(0f, 1.12f, 2.35f - 0.16f * currentRecoil); ((Component)_camera).transform.localRotation = Quaternion.Euler(-3.4f * currentRecoil, 0f, 0f); } } private static void RenderView() { if (!((Object)(object)_camera == (Object)null) && !((Object)(object)_renderTexture == (Object)null)) { _camera.targetTexture = _renderTexture; _camera.Render(); } } private static void SetStatus(string status, float seconds) { _lastStatus = status ?? "READY"; _statusVisibleUntil = Time.unscaledTime + Mathf.Max(0.1f, seconds); } private static string BuildPresetStatus() { string text = string.Empty; for (int i = 0; i < LayoutPresets.Length; i++) { string text2 = LayoutPresets[i]; TurretPlacementRecord placement; bool flag = TryGetPlacement(text2, out placement); if (i > 0) { text += ","; } text = text + text2 + ":" + (flag ? "saved" : "default"); } return text; } private static string FormatVector(Vector3 value) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"{value.x:0.0},{value.y:0.0},{value.z:0.0}"; } private static string FormatZoom() { float num = Mathf.Lerp(72f, 28f, _zoom); return (72f / Mathf.Max(1f, num)).ToString("0.0") + "X"; } private static float WrapAngle(float angle) { while (angle > 180f) { angle -= 360f; } while (angle < -180f) { angle += 360f; } return angle; } private static void EnsureNetworkHandlers() { //IL_0058: 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_0063: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null || !singleton.IsListening || (_networkHandlersRegistered && _registeredNetworkManager == singleton)) { return; } if (_networkHandlersRegistered) { UnregisterNetworkHandlers(); } try { CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager; object obj = <>O.<0>__OnReceiveShotRequest; if (obj == null) { HandleNamedMessageDelegate val = OnReceiveShotRequest; <>O.<0>__OnReceiveShotRequest = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler("LethalCCTV.TurretShotRequest", (HandleNamedMessageDelegate)obj); CustomMessagingManager customMessagingManager2 = singleton.CustomMessagingManager; object obj2 = <>O.<1>__OnReceiveShotResult; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnReceiveShotResult; <>O.<1>__OnReceiveShotResult = val2; obj2 = (object)val2; } customMessagingManager2.RegisterNamedMessageHandler("LethalCCTV.TurretShotResult", (HandleNamedMessageDelegate)obj2); _networkHandlersRegistered = true; _registeredNetworkManager = singleton; } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV.Turret] Network handler registration failed: " + ex.Message)); } } } private static void UnregisterNetworkHandlers() { if (!_networkHandlersRegistered || (Object)(object)_registeredNetworkManager == (Object)null || _registeredNetworkManager.CustomMessagingManager == null) { _networkHandlersRegistered = false; _registeredNetworkManager = null; return; } try { _registeredNetworkManager.CustomMessagingManager.UnregisterNamedMessageHandler("LethalCCTV.TurretShotRequest"); } catch { } try { _registeredNetworkManager.CustomMessagingManager.UnregisterNamedMessageHandler("LethalCCTV.TurretShotResult"); } catch { } _networkHandlersRegistered = false; _registeredNetworkManager = null; } private static void OnReceiveShotRequest(ulong senderClientId, FastBufferReader reader) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0033: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsServer) { return; } try { Vector3 origin = ReadVector(ref reader); Vector3 val = ReadVector(ref reader); Vector3 normalized = ((Vector3)(ref val)).normalized; ProcessShotRequest(senderClientId, origin, normalized); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV.Turret] Malformed shot request: " + ex.Message)); } } } private static void ProcessShotRequest(ulong senderClientId, Vector3 origin, Vector3 direction) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_0031: 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_0033: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0055: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_00b3: 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_010f: 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_0111: 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_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_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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) bool flag = false; bool hit = false; bool enemyHit = false; Vector3 hitPoint = origin + direction * 260f; Vector3 hitNormal = Vector3.up; float realtimeSinceStartup = Time.realtimeSinceStartup; if (!IsUnlocked) { BroadcastShotResult(senderClientId, accepted: false, hit: false, enemyHit: false, origin, direction, hitPoint, hitNormal); return; } if (ServerNextShotAt.TryGetValue(senderClientId, out var value) && realtimeSinceStartup < value) { BroadcastShotResult(senderClientId, accepted: false, hit: false, enemyHit: false, origin, direction, hitPoint, hitNormal); return; } if (!CCTVShipSystemsBridge.TrySpendTurretShotPower()) { BroadcastShotResult(senderClientId, accepted: false, hit: false, enemyHit: false, origin, direction, hitPoint, hitNormal); return; } flag = true; ServerNextShotAt[senderClientId] = realtimeSinceStartup + 3f; PlayerControllerB val = FindPlayerByClientId(senderClientId); if ((Object)(object)val != (Object)null) { BundyWorldNoiseBridge.Report(((Component)val).transform.position, 9, val); } if (TryResolveShotHit(origin, direction, out var bestHit, out var enemy)) { hit = true; hitPoint = ((RaycastHit)(ref bestHit)).point; Vector3 normal = ((RaycastHit)(ref bestHit)).normal; hitNormal = ((((Vector3)(ref normal)).sqrMagnitude > 0.001f) ? ((RaycastHit)(ref bestHit)).normal : (-direction)); if ((Object)(object)enemy != (Object)null) { enemyHit = TryDamageEnemy(((RaycastHit)(ref bestHit)).collider, enemy, direction); } } BroadcastShotResult(senderClientId, flag, hit, enemyHit, origin, direction, hitPoint, hitNormal); } private static PlayerControllerB FindPlayerByClientId(ulong clientId) { PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null) { return null; } foreach (PlayerControllerB val in array) { if ((Object)(object)val != (Object)null && (val.actualClientId == clientId || val.playerClientId == clientId)) { return val; } } return null; } private static bool TryResolveShotHit(Vector3 origin, Vector3 direction, out RaycastHit bestHit, out EnemyAI enemy) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_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_001f: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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) bestHit = default(RaycastHit); enemy = null; RaycastHit firstWorldHit = default(RaycastHit); bool hasWorldHit = false; RaycastHit firstEnemyHit = default(RaycastHit); EnemyAI firstEnemy = null; int count = Physics.RaycastNonAlloc(origin, direction, ShotHits, 260f, -1, (QueryTriggerInteraction)2); ConsiderShotHits(ShotHits, count, ref hasWorldHit, ref firstWorldHit, ref firstEnemyHit, ref firstEnemy); int count2 = Physics.SphereCastNonAlloc(origin, 0.72f, direction, ShotSphereHits, 260f, -1, (QueryTriggerInteraction)2); ConsiderShotHits(ShotSphereHits, count2, ref hasWorldHit, ref firstWorldHit, ref firstEnemyHit, ref firstEnemy); if ((Object)(object)firstEnemy != (Object)null && (!hasWorldHit || ((RaycastHit)(ref firstEnemyHit)).distance <= ((RaycastHit)(ref firstWorldHit)).distance + 1.15f)) { bestHit = firstEnemyHit; enemy = firstEnemy; return true; } if (hasWorldHit) { bestHit = firstWorldHit; return true; } return false; } private static void ConsiderShotHits(RaycastHit[] hits, int count, ref bool hasWorldHit, ref RaycastHit firstWorldHit, ref RaycastHit firstEnemyHit, ref EnemyAI firstEnemy) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_00cf: 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_00b0: 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) if (hits == null || count <= 0) { return; } Array.Sort(hits, 0, count, RaycastHitDistanceComparer.Instance); for (int i = 0; i < count; i++) { RaycastHit val = hits[i]; hits[i] = default(RaycastHit); Collider collider = ((RaycastHit)(ref val)).collider; if ((Object)(object)collider == (Object)null || ((Object)(object)_root != (Object)null && ((Component)collider).transform.IsChildOf(_root.transform)) || (Object)(object)((Component)collider).GetComponentInParent() != (Object)null) { continue; } EnemyAI val2 = ResolveEnemyFromCollider(collider); if ((Object)(object)val2 != (Object)null && !val2.isEnemyDead) { if ((Object)(object)firstEnemy == (Object)null || ((RaycastHit)(ref val)).distance < ((RaycastHit)(ref firstEnemyHit)).distance) { firstEnemy = val2; firstEnemyHit = val; } } else if (!hasWorldHit || ((RaycastHit)(ref val)).distance < ((RaycastHit)(ref firstWorldHit)).distance) { hasWorldHit = true; firstWorldHit = val; } } } private static EnemyAI ResolveEnemyFromCollider(Collider collider) { if ((Object)(object)collider == (Object)null) { return null; } EnemyAICollisionDetect val = ((Component)collider).GetComponent() ?? ((Component)collider).GetComponentInParent(); if ((Object)(object)val != (Object)null && (Object)(object)val.mainScript != (Object)null) { return val.mainScript; } return ((Component)collider).GetComponentInParent(); } private static bool TryDamageEnemy(Collider collider, EnemyAI enemy, Vector3 direction) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)enemy == (Object)null || enemy.isEnemyDead) { return false; } try { bool flag = false; EnemyAICollisionDetect val = (((Object)(object)collider != (Object)null) ? (((Component)collider).GetComponent() ?? ((Component)collider).GetComponentInParent()) : null); if ((Object)(object)val != (Object)null) { flag = ((IHittable)val).Hit(10, direction, (PlayerControllerB)null, true, 4107); } if (!flag) { enemy.HitEnemy(10, (PlayerControllerB)null, true, 4107); } return true; } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV.Turret] Enemy damage failed: " + ex.Message)); } return false; } } private static void BroadcastShotResult(ulong requester, bool accepted, bool hit, bool enemyHit, Vector3 origin, Vector3 direction, Vector3 hitPoint, Vector3 hitNormal) { //IL_0034: 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_0046: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0078: 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_008a: 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_00a5: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null || !singleton.IsServer) { return; } FastBufferWriter writer = default(FastBufferWriter); ((FastBufferWriter)(ref writer))..ctor(160, (Allocator)2, -1); try { ((FastBufferWriter)(ref writer)).WriteValueSafe(ref requester, default(ForPrimitives)); ((FastBufferWriter)(ref writer)).WriteValueSafe(ref accepted, default(ForPrimitives)); ((FastBufferWriter)(ref writer)).WriteValueSafe(ref hit, default(ForPrimitives)); ((FastBufferWriter)(ref writer)).WriteValueSafe(ref enemyHit, default(ForPrimitives)); WriteVector(ref writer, origin); WriteVector(ref writer, direction); WriteVector(ref writer, hitPoint); WriteVector(ref writer, hitNormal); singleton.CustomMessagingManager.SendNamedMessageToAll("LethalCCTV.TurretShotResult", writer, (NetworkDelivery)3); } finally { ((FastBufferWriter)(ref writer)).Dispose(); } } private static void OnReceiveShotResult(ulong senderClientId, FastBufferReader reader) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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) //IL_002c: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0057: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00db: 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_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) //IL_00fa: 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) try { ulong num = default(ulong); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num, default(ForPrimitives)); bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag, default(ForPrimitives)); bool flag2 = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag2, default(ForPrimitives)); bool flag3 = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag3, default(ForPrimitives)); Vector3 val = ReadVector(ref reader); Vector3 val2 = ReadVector(ref reader); Vector3 val3 = ReadVector(ref reader); Vector3 normal = ReadVector(ref reader); NetworkManager singleton = NetworkManager.Singleton; bool flag4 = (Object)(object)singleton != (Object)null && num == singleton.LocalClientId; if (!flag) { if (flag4) { _nextLocalShotAt = Mathf.Min(_nextLocalShotAt, Time.realtimeSinceStartup + 0.4f); SetStatus("NO POWER / LOCKED", 1.2f); } return; } PlayFireAudio(); CCTVShipSystemsBridge.NoteTurretShotAccepted(); TriggerRecoil(); SpawnMuzzleEffects(val, val2, flag2 ? val3 : (val + val2 * 260f)); if (flag2) { SpawnImpact(val3, normal); if (flag4) { MonitorFocus.ShowTurretHitmarker(flag3); } } if (flag4) { SetStatus((!flag2) ? "FIRED" : (flag3 ? "TARGET HIT" : "IMPACT"), 1f); } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV.Turret] Malformed shot result: " + ex.Message)); } } } private static void WriteVector(ref FastBufferWriter writer, Vector3 value) { //IL_000a: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) ((FastBufferWriter)(ref writer)).WriteValueSafe(ref value.x, default(ForPrimitives)); ((FastBufferWriter)(ref writer)).WriteValueSafe(ref value.y, default(ForPrimitives)); ((FastBufferWriter)(ref writer)).WriteValueSafe(ref value.z, default(ForPrimitives)); } private static Vector3 ReadVector(ref FastBufferReader reader) { //IL_0005: 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_0016: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) float num = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num, default(ForPrimitives)); float num2 = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num2, default(ForPrimitives)); float num3 = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num3, default(ForPrimitives)); return new Vector3(num, num2, num3); } private static void TickPlacementEditor() { //IL_00e2: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022c: 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_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0243: 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_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) if (!_placementActive) { return; } EnsureTurretPresent(); Transform val = ResolveShipRoot(); if ((Object)(object)val == (Object)null || (Object)(object)_root == (Object)null || Keyboard.current == null) { return; } Keyboard current = Keyboard.current; if (((ButtonControl)current.enterKey).wasPressedThisFrame || ((ButtonControl)current.numpadEnterKey).wasPressedThisFrame) { SavePlacementFromCurrentTransform(val); return; } if (((ButtonControl)current.escapeKey).wasPressedThisFrame || ((ButtonControl)current.backspaceKey).wasPressedThisFrame || ((ButtonControl)current.deleteKey).wasPressedThisFrame) { CancelPlacement(); return; } float num = Mathf.Max(Time.unscaledDeltaTime, 0.001f); int num2; float num3; if (!((ButtonControl)current.leftShiftKey).isPressed) { num2 = (((ButtonControl)current.rightShiftKey).isPressed ? 1 : 0); if (num2 == 0) { num3 = 1.8f; goto IL_00c0; } } else { num2 = 1; } num3 = 8f; goto IL_00c0; IL_00c0: float num4 = num3; float num5 = ((num2 != 0) ? 2f : 0.55f); float num6 = ((num2 != 0) ? 120f : 42f); Vector3 val2 = Vector3.zero; if (((ButtonControl)current.wKey).isPressed || ((ButtonControl)current.upArrowKey).isPressed) { val2 += GetPlacementEditForward(); } if (((ButtonControl)current.sKey).isPressed || ((ButtonControl)current.downArrowKey).isPressed) { val2 -= GetPlacementEditForward(); } if (((ButtonControl)current.dKey).isPressed || ((ButtonControl)current.rightArrowKey).isPressed) { val2 += GetPlacementEditRight(); } if (((ButtonControl)current.aKey).isPressed || ((ButtonControl)current.leftArrowKey).isPressed) { val2 -= GetPlacementEditRight(); } float num7 = 0f; if (((ButtonControl)current.eKey).isPressed || ((ButtonControl)current.pageUpKey).isPressed) { num7 += num5 * num; } if (((ButtonControl)current.qKey).isPressed || ((ButtonControl)current.pageDownKey).isPressed) { num7 -= num5 * num; } float num8 = 0f; if (((ButtonControl)current.rKey).isPressed) { num8 -= num6 * num; } if (((ButtonControl)current.tKey).isPressed) { num8 += num6 * num; } Vector3 val3 = ((((Vector3)(ref val2)).sqrMagnitude > 0.0001f) ? (((Vector3)(ref val2)).normalized * num4 * num) : Vector3.zero); if (Mathf.Abs(num7) > 0.0001f) { val3 += Vector3.up * num7; } if (((Vector3)(ref val3)).sqrMagnitude > 0f || Mathf.Abs(num8) > 0.001f) { NudgePlacementPreview(val3, num8); } } private static void NudgePlacementPreview(Vector3 worldDelta, float yawDegrees) { //IL_0050: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null)) { Transform val = ResolveShipRoot(); if ((Object)(object)val != (Object)null && (Object)(object)_root.transform.parent != (Object)(object)val) { _root.transform.SetParent(val, true); } Transform transform = _root.transform; transform.position += worldDelta; if (Mathf.Abs(yawDegrees) > 0.001f) { _root.transform.rotation = Quaternion.Euler(0f, _root.transform.eulerAngles.y + yawDegrees, 0f); } SetStatus("EDIT " + _placementLayout + " " + FormatVector(_root.transform.localPosition), 0.25f); UpdatePlacementCameraPose(); } } private static Vector3 GetPlacementEditForward() { //IL_0017: 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_001c: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) Transform placementControlBasis = GetPlacementControlBasis(); Vector3 val = (((Object)(object)placementControlBasis != (Object)null) ? placementControlBasis.forward : Vector3.forward); val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.forward; } return ((Vector3)(ref val)).normalized; } private static Vector3 GetPlacementEditRight() { //IL_0017: 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_001c: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) Transform placementControlBasis = GetPlacementControlBasis(); Vector3 val = (((Object)(object)placementControlBasis != (Object)null) ? placementControlBasis.right : Vector3.right); val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.right; } return ((Vector3)(ref val)).normalized; } private static Transform GetPlacementControlBasis() { if (!((Object)(object)_placementCamera != (Object)null)) { if (!((Object)(object)_root != (Object)null)) { return null; } return _root.transform; } return ((Component)_placementCamera).transform; } private static void BeginPlacementInputCapture() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = ResolvePlacementPlayer(); if (!((Object)(object)val == (Object)null)) { if (_placementCapturedInputState) { RestorePlacementInputCapture(); } _placementPlayer = val; _placementSavedLock = Cursor.lockState; _placementSavedCursorVisible = Cursor.visible; _placementSavedDisableLookInput = val.disableLookInput; _placementSavedDisableMoveInput = val.disableMoveInput; Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; val.disableLookInput = true; val.disableMoveInput = true; _placementCapturedInputState = true; } } private static void RestorePlacementInputCapture() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) RestorePlacementCameraTransform(); if (_placementCapturedInputState) { if ((Object)(object)_placementPlayer != (Object)null) { _placementPlayer.disableLookInput = _placementSavedDisableLookInput; _placementPlayer.disableMoveInput = _placementSavedDisableMoveInput; } Cursor.lockState = _placementSavedLock; Cursor.visible = _placementSavedCursorVisible; } _placementCapturedInputState = false; _placementPlayer = null; _placementCamera = null; } private static void EnsurePlacementCamera() { //IL_001d: 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_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) Camera val = ResolvePlacementSourceCamera(); if (!((Object)(object)val == (Object)null)) { if (!_placementCapturedCameraTransform) { _placementSavedCameraLocalPosition = ((Component)val).transform.localPosition; _placementSavedCameraLocalRotation = ((Component)val).transform.localRotation; _placementCapturedCameraTransform = true; } _placementCamera = val; Camera placementCamera = _placementCamera; placementCamera.cullingMask |= 1; ((Behaviour)_placementCamera).enabled = true; } } private static Camera ResolvePlacementSourceCamera() { PlayerControllerB val = _placementPlayer ?? ResolvePlacementPlayer(); if ((Object)(object)val?.gameplayCamera != (Object)null) { return val.gameplayCamera; } Camera main = Camera.main; if ((Object)(object)main != (Object)null) { return main; } Camera[] array = Object.FindObjectsOfType(); foreach (Camera val2 in array) { if ((Object)(object)val2 != (Object)null && ((Behaviour)val2).enabled) { return val2; } } return null; } private static PlayerControllerB ResolvePlacementPlayer() { if ((Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null) { return GameNetworkManager.Instance.localPlayerController; } if (!((Object)(object)StartOfRound.Instance != (Object)null)) { return null; } return StartOfRound.Instance.localPlayerController; } private static void UpdatePlacementCameraPose() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_003a: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_0162: 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) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_placementCamera == (Object)null) && !((Object)(object)_root == (Object)null)) { if (!TryGetRendererBounds(_root, out var bounds)) { ((Bounds)(ref bounds))..ctor(_root.transform.position + Vector3.up * 1.4f, new Vector3(4.35f, 2.4f, 4.35f)); } Vector3 center = ((Bounds)(ref bounds)).center; Vector3 forward = _root.transform.forward; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 0.0001f) { forward = Vector3.forward; } ((Vector3)(ref forward)).Normalize(); float num = Mathf.Max(((Bounds)(ref bounds)).size.x, ((Bounds)(ref bounds)).size.z); float num2 = Mathf.Clamp(num * 0.95f + 3f, 6f, 22f); float num3 = Mathf.Clamp(((Bounds)(ref bounds)).size.y * 0.75f + num * 0.14f, 2.6f, 8f); Vector3 val = center + forward * num2 + Vector3.up * num3; Vector3 val2 = center + Vector3.up * Mathf.Clamp(((Bounds)(ref bounds)).size.y * 0.05f, 0.15f, 0.65f) - val; if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = -forward; } ((Component)_placementCamera).transform.SetPositionAndRotation(val, Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up)); } } private static void RestorePlacementCameraTransform() { //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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (_placementCapturedCameraTransform) { if ((Object)(object)_placementCamera != (Object)null) { Transform transform = ((Component)_placementCamera).transform; transform.localPosition = _placementSavedCameraLocalPosition; transform.localRotation = _placementSavedCameraLocalRotation; } _placementCapturedCameraTransform = false; _placementSavedCameraLocalPosition = Vector3.zero; _placementSavedCameraLocalRotation = Quaternion.identity; } } private static bool TryGetRendererBounds(GameObject root, out Bounds bounds) { //IL_0001: 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_003c: 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) bounds = default(Bounds); Renderer[] array = (((Object)(object)root != (Object)null) ? root.GetComponentsInChildren(true) : null); if (array == null || array.Length == 0) { return false; } bool flag = false; foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null)) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } return flag; } private static void SavePlacementFromCurrentTransform(Transform shipRoot) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null) && !((Object)(object)shipRoot == (Object)null)) { TurretPlacementRecord turretPlacementRecord = new TurretPlacementRecord { layout = (string.IsNullOrWhiteSpace(_placementLayout) ? ResolveLayoutName() : _placementLayout), localPosition = _root.transform.localPosition, localEuler = _root.transform.localEulerAngles }; UpsertPlacement(turretPlacementRecord); SavePlacementProfile(); _placementActive = false; _lastAppliedLayout = null; ApplyLayoutPlacementIfNeeded(force: true); RestorePlacementInputCapture(); SetStatus("PLACEMENT SAVED", 2f); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV.Turret] Saved placement layout={turretPlacementRecord.layout} pos={turretPlacementRecord.localPosition} euler={turretPlacementRecord.localEuler}."); } } } private static void CancelPlacement() { //IL_0017: 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) if ((Object)(object)_root != (Object)null) { _root.transform.localPosition = _placementStartLocalPosition; _root.transform.localRotation = _placementStartLocalRotation; } _placementActive = false; RestorePlacementInputCapture(); if (!IsUnlocked) { DestroyTurret(); } SetStatus("PLACEMENT CANCELLED", 1.5f); } private static void ApplyLayoutPlacementIfNeeded(bool force = false) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) if (_placementActive || (Object)(object)_root == (Object)null || (!force && Time.unscaledTime < _nextLayoutRecheckAt)) { return; } _nextLayoutRecheckAt = Time.unscaledTime + 1f; Transform val = ResolveShipRoot(); if ((Object)(object)val != (Object)null && (Object)(object)_root.transform.parent != (Object)(object)val) { _root.transform.SetParent(val, false); } string text = ResolveLayoutName(); if (force || !string.Equals(_lastAppliedLayout, text, StringComparison.Ordinal)) { if (!TryGetPlacement(text, out var placement)) { placement = GetDefaultPlacement(text); } _root.transform.localPosition = placement.localPosition; _root.transform.localRotation = Quaternion.Euler(placement.localEuler); _lastAppliedLayout = text; } } private static void ApplyPlacementForLayout(string layout) { //IL_0069: 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_0083: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null)) { Transform val = ResolveShipRoot(); if ((Object)(object)val != (Object)null && (Object)(object)_root.transform.parent != (Object)(object)val) { _root.transform.SetParent(val, false); } layout = NormalizeLayoutName(layout); if (!TryGetPlacement(layout, out var placement)) { placement = GetDefaultPlacement(layout); } _root.transform.localPosition = placement.localPosition; _root.transform.localRotation = Quaternion.Euler(placement.localEuler); _lastAppliedLayout = layout; } } private static string ResolveLayoutName() { return NormalizeLayoutName(CCTVShipSystemsBridge.GetCurrentLayoutName()); } private static string NormalizeLayoutName(string layout) { if (string.IsNullOrWhiteSpace(layout)) { layout = CCTVShipSystemsBridge.GetCurrentLayoutName(); } if (string.IsNullOrWhiteSpace(layout)) { return "Vanilla"; } string text = layout.Trim().Replace(" ", string.Empty).Replace("-", string.Empty) .Replace("_", string.Empty) .Replace("+", string.Empty); bool flag = text.IndexOf("Wider", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Wide", StringComparison.OrdinalIgnoreCase) >= 0; bool flag2 = text.IndexOf("TwoStory", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("2Story", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("2Floor", StringComparison.OrdinalIgnoreCase) >= 0; if (flag && flag2) { return "WiderAndTwoStory"; } if (flag) { return "Wider"; } if (flag2) { return "TwoStory"; } return "Vanilla"; } private static Transform ResolveShipRoot() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.elevatorTransform != (Object)null) { return instance.elevatorTransform; } GameObject val = GameObject.Find("Environment/HangarShip"); if (!((Object)(object)val != (Object)null)) { return null; } return val.transform; } private static TurretPlacementRecord GetDefaultPlacement(string layout) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) layout = NormalizeLayoutName(layout); bool flag = string.Equals(layout, "TwoStory", StringComparison.OrdinalIgnoreCase) || string.Equals(layout, "WiderAndTwoStory", StringComparison.OrdinalIgnoreCase); bool flag2 = string.Equals(layout, "Wider", StringComparison.OrdinalIgnoreCase) || string.Equals(layout, "WiderAndTwoStory", StringComparison.OrdinalIgnoreCase); return new TurretPlacementRecord { layout = layout, localPosition = new Vector3(flag2 ? 1.35f : 0f, flag ? 8.8f : 5.4f, flag2 ? (-14.6f) : (-13f)), localEuler = Vector3.zero }; } private static void EnsurePlacementProfileLoaded() { if (_profileLoaded) { return; } _profileLoaded = true; _profile = new TurretPlacementProfile(); try { if (File.Exists(PlacementProfilePath)) { TurretPlacementProfile turretPlacementProfile = ReadPlacementProfile(File.ReadAllText(PlacementProfilePath)); if (turretPlacementProfile != null && turretPlacementProfile.placements != null) { _profile = turretPlacementProfile; } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV.Turret] Failed reading placement profile: " + ex.Message)); } _profile = new TurretPlacementProfile(); } } private static bool TryGetPlacement(string layout, out TurretPlacementRecord placement) { EnsurePlacementProfileLoaded(); placement = null; if (_profile?.placements == null) { return false; } layout = NormalizeLayoutName(layout); for (int i = 0; i < _profile.placements.Count; i++) { TurretPlacementRecord turretPlacementRecord = _profile.placements[i]; if (turretPlacementRecord != null && string.Equals(NormalizeLayoutName(turretPlacementRecord.layout), layout, StringComparison.OrdinalIgnoreCase)) { placement = turretPlacementRecord; placement.layout = layout; return true; } } return false; } private static void UpsertPlacement(TurretPlacementRecord record) { EnsurePlacementProfileLoaded(); if (_profile.placements == null) { _profile.placements = new List(); } record.layout = NormalizeLayoutName(record.layout); for (int i = 0; i < _profile.placements.Count; i++) { if (string.Equals(NormalizeLayoutName(_profile.placements[i]?.layout), record.layout, StringComparison.OrdinalIgnoreCase)) { _profile.placements[i] = record; return; } } _profile.placements.Add(record); } private static void SavePlacementProfile() { try { Directory.CreateDirectory(Path.GetDirectoryName(PlacementProfilePath)); File.WriteAllText(PlacementProfilePath, WritePlacementProfile(_profile)); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV.Turret] Failed writing placement profile: " + ex.Message)); } } } private static TurretPlacementProfile ReadPlacementProfile(string json) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_0075: Unknown result type (might be due to invalid IL or missing references) Y4NGZJsonObject val = Y4NGZJson.Parse(json); if (val == null) { return null; } TurretPlacementProfile turretPlacementProfile = new TurretPlacementProfile(); Y4NGZJsonArray array = val.GetArray("placements"); if (array == null) { return turretPlacementProfile; } for (int i = 0; i < array.Count; i++) { Y4NGZJsonObject val2 = array.GetObject(i); if (val2 != null) { turretPlacementProfile.placements.Add(new TurretPlacementRecord { layout = val2.GetString("layout", ""), localPosition = val2.GetVector3("localPosition"), localEuler = val2.GetVector3("localEuler") }); } } return turretPlacementProfile; } private static string WritePlacementProfile(TurretPlacementProfile profile) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) Y4NGZJsonObject val = new Y4NGZJsonObject(); Y4NGZJsonArray val2 = val.SetArray("placements"); if (profile?.placements != null) { for (int i = 0; i < profile.placements.Count; i++) { TurretPlacementRecord turretPlacementRecord = profile.placements[i]; if (turretPlacementRecord != null) { Y4NGZJsonObject obj = val2.AddObject(); obj.SetString("layout", turretPlacementRecord.layout); obj.SetVector3("localPosition", turretPlacementRecord.localPosition); obj.SetVector3("localEuler", turretPlacementRecord.localEuler); } } } return Y4NGZJson.Write(val, true); } private static void TickAudioCues() { float unscaledTime = Time.unscaledTime; if ((Object)(object)_rotateSource != (Object)null && _rotateSource.isPlaying && unscaledTime >= _rotateCueStopAt) { _rotateSource.Stop(); } if ((Object)(object)_zoomSource != (Object)null && _zoomSource.isPlaying && unscaledTime >= _zoomCueStopAt) { _zoomSource.Stop(); } if (_lastRotateDirection != 0 && unscaledTime - _lastRotateAt > 0.55f) { _lastRotateDirection = 0; } if (_lastZoomDirection != 0 && unscaledTime - _lastZoomAt > 0.55f) { _lastZoomDirection = 0; } } private static void TickRecoil() { //IL_0027: 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) if ((Object)(object)_gunVisualRoot == (Object)null) { return; } if (!(Time.unscaledTime - _recoilStartedAt < 0.34f)) { Vector3 localPosition = _gunVisualRoot.localPosition; if (!(((Vector3)(ref localPosition)).sqrMagnitude > 0.0001f)) { return; } } ApplyAim(); } private static void TriggerRecoil() { _recoilStartedAt = Time.unscaledTime; ApplyAim(); } private static float GetCurrentRecoil01() { float num = Time.unscaledTime - _recoilStartedAt; if (num < 0f || num >= 0.34f) { return 0f; } float num2 = num / 0.34f; if (num2 < 0.14f) { return Mathf.Lerp(0f, 1f, num2 / 0.14f); } float num3 = Mathf.Clamp01((num2 - 0.14f) / 0.86f); return 1f - Mathf.SmoothStep(0f, 1f, num3); } private static void PlayShortCue(AudioSource source, AudioClip clip, float volume) { if (!((Object)(object)source == (Object)null) && !((Object)(object)clip == (Object)null)) { source.Stop(); source.clip = clip; source.volume = volume; source.loop = false; source.time = 0f; source.Play(); } } private static int ResolveDominantDirection(Vector2 delta) { //IL_0010: 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_0039: 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) if (((Vector2)(ref delta)).sqrMagnitude < 0.0001f) { return 0; } if (Mathf.Abs(delta.x) >= Mathf.Abs(delta.y)) { if (!(delta.x >= 0f)) { return -1; } return 1; } if (!(delta.y >= 0f)) { return -2; } return 2; } private static void PlayFireAudio() { EnsureAudioSources(); if (!((Object)(object)_fireSource == (Object)null)) { AudioClip val = null; if (_fireClips != null && _fireClips.Length != 0) { val = _fireClips[Random.Range(0, _fireClips.Length)]; } if ((Object)(object)val != (Object)null) { _fireSource.PlayOneShot(val, 0.88f); } } } private static void SpawnImpact(Vector3 point, Vector3 normal) { //IL_0005: 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) EnsureAssetsLoaded(); GameObject val = CreateFallbackDust(point, normal); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val, 4f); } } private static void SpawnMuzzleEffects(Vector3 origin, Vector3 direction, Vector3 endPoint) { //IL_0017: 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_001c: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_003d: 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_0043: 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) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0076: 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_009b: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((((Vector3)(ref direction)).sqrMagnitude > 0.001f) ? ((Vector3)(ref direction)).normalized : Vector3.forward); Vector3 val2 = (((Object)(object)_muzzle != (Object)null) ? _muzzle.position : origin); Quaternion rotation = Quaternion.LookRotation(val, Vector3.up); GameObject val3 = CreateMuzzleFlash(val2 + val * 0.22f, rotation); if ((Object)(object)val3 != (Object)null) { Object.Destroy((Object)(object)val3, 0.22f); } GameObject val4 = CreateMuzzleSmoke(val2 + val * 0.38f, rotation); if ((Object)(object)val4 != (Object)null) { Object.Destroy((Object)(object)val4, 1.4f); } GameObject val5 = CreateTracer(val2 + val * 0.55f, endPoint); if ((Object)(object)val5 != (Object)null) { Object.Destroy((Object)(object)val5, 0.12f); } } private static GameObject CreateMuzzleFlash(Vector3 position, Quaternion rotation) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_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_00d0: 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_00fb: 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_0182: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("LethalCCTV_TurretMuzzleFlash"); val.transform.SetPositionAndRotation(position, rotation); ParticleSystem val2 = val.AddComponent(); MainModule main = val2.main; ((MainModule)(ref main)).duration = 0.09f; ((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.045f, 0.095f); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(1.6f, 4.2f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.2f, 0.58f); ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(1f, 0.92f, 0.48f, 0.95f), new Color(1f, 0.34f, 0.06f, 0.72f)); ((MainModule)(ref main)).loop = false; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; EmissionModule emission = val2.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); ((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1] { new Burst(0f, (short)18) }); ShapeModule shape = val2.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4; ((ShapeModule)(ref shape)).angle = 17f; ((ShapeModule)(ref shape)).radius = 0.06f; ParticleSystemRenderer component = val.GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).sharedMaterial = GetMuzzleFlashMaterial(); component.renderMode = (ParticleSystemRenderMode)0; component.sortingFudge = 8f; component.maxParticleSize = 2f; } Light obj = val.AddComponent(); obj.type = (LightType)2; obj.color = new Color(1f, 0.72f, 0.28f, 1f); obj.range = 5.5f; obj.intensity = 3.2f; val2.Play(); return val; } private static GameObject CreateMuzzleSmoke(Vector3 position, Quaternion rotation) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_008f: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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) GameObject val = new GameObject("LethalCCTV_TurretMuzzleSmoke"); val.transform.SetPositionAndRotation(position, rotation); ParticleSystem val2 = val.AddComponent(); MainModule main = val2.main; ((MainModule)(ref main)).duration = 0.42f; ((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.34f, 0.82f); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.75f, 1.9f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.18f, 0.42f); ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.46f, 0.46f, 0.42f, 0.42f)); ((MainModule)(ref main)).loop = false; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; EmissionModule emission = val2.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); ((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1] { new Burst(0f, (short)16) }); ShapeModule shape = val2.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4; ((ShapeModule)(ref shape)).angle = 26f; ((ShapeModule)(ref shape)).radius = 0.08f; ParticleSystemRenderer component = val.GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).sharedMaterial = GetMuzzleSmokeMaterial(); component.renderMode = (ParticleSystemRenderMode)0; component.sortingFudge = 5f; component.maxParticleSize = 1.3f; } val2.Play(); return val; } private static GameObject CreateTracer(Vector3 start, Vector3 end) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_001d: 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_0032: 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_003b: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown Vector3 val = end - start; if (((Vector3)(ref val)).sqrMagnitude < 0.001f) { return null; } GameObject val2 = new GameObject("LethalCCTV_TurretTracer"); LineRenderer val3 = val2.AddComponent(); val3.positionCount = 2; val3.SetPosition(0, start); val3.SetPosition(1, Vector3.Lerp(start, end, 0.88f)); val3.widthMultiplier = 0.035f; val3.numCapVertices = 2; ((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val3).receiveShadows = false; Material muzzleFlashMaterial = GetMuzzleFlashMaterial(); if ((Object)(object)muzzleFlashMaterial != (Object)null) { ((Renderer)val3).sharedMaterial = muzzleFlashMaterial; } val3.startColor = new Color(1f, 0.92f, 0.52f, 0.82f); val3.endColor = new Color(1f, 0.45f, 0.04f, 0f); return val2; } private static GameObject CreateParticlePackDust(Vector3 point, Vector3 normal) { //IL_0026: 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_0031: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0043: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_0135: 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) if ((Object)(object)_dustExplosionPrefab == (Object)null) { return null; } Vector3 val = ((((Vector3)(ref normal)).sqrMagnitude > 0.001f) ? ((Vector3)(ref normal)).normalized : Vector3.up); GameObject val2 = Object.Instantiate(_dustExplosionPrefab, point + val * 0.08f, Quaternion.LookRotation(val)); ((Object)val2).name = "LethalCCTV_TurretDustExplosion"; val2.transform.localScale = Vector3.one * 0.35f; Material impactDustMaterial = GetImpactDustMaterial(); Renderer[] componentsInChildren = val2.GetComponentsInChildren(true); foreach (Renderer val3 in componentsInChildren) { val3.enabled = true; if ((Object)(object)impactDustMaterial != (Object)null) { val3.sharedMaterials = (Material[])(object)new Material[1] { impactDustMaterial }; } ParticleSystemRenderer val4 = (ParticleSystemRenderer)(object)((val3 is ParticleSystemRenderer) ? val3 : null); if (val4 != null) { val4.renderMode = (ParticleSystemRenderMode)0; val4.sortingFudge = 4f; val4.maxParticleSize = Mathf.Max(val4.maxParticleSize, 1.5f); } } ParticleSystem[] componentsInChildren2 = val2.GetComponentsInChildren(true); foreach (ParticleSystem obj in componentsInChildren2) { MainModule main = obj.main; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.54f, 0.47f, 0.36f, 0.78f)); obj.Clear(false); obj.Play(false); } return val2; } private static GameObject CreateFallbackDust(Vector3 point, Vector3 normal) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0022: 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_0027: 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_002f: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_00a7: 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_00cc: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010f: 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_012f: 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_013f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("LethalCCTV_TurretFallbackDust"); Vector3 val2 = ((((Vector3)(ref normal)).sqrMagnitude > 0.001f) ? ((Vector3)(ref normal)).normalized : Vector3.up); val.transform.position = point + val2 * 0.08f; val.transform.rotation = Quaternion.LookRotation(val2); ParticleSystem val3 = val.AddComponent(); MainModule main = val3.main; ((MainModule)(ref main)).duration = 1f; ((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.45f, 1.05f); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(4.2f, 8f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.35f, 0.95f); ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.54f, 0.47f, 0.36f, 0.82f)); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0.85f); ((MainModule)(ref main)).maxParticles = 120; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).loop = false; EmissionModule emission = val3.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); ((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1] { new Burst(0f, (short)72) }); ShapeModule shape = val3.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4; ((ShapeModule)(ref shape)).angle = 58f; ((ShapeModule)(ref shape)).radius = 0.34f; ParticleSystemRenderer component = val.GetComponent(); Material impactDustMaterial = GetImpactDustMaterial(); if ((Object)(object)component != (Object)null && (Object)(object)impactDustMaterial != (Object)null) { ((Renderer)component).sharedMaterial = impactDustMaterial; component.renderMode = (ParticleSystemRenderMode)0; component.sortingFudge = 5f; component.maxParticleSize = 2.5f; } val3.Play(); return val; } private static Material GetImpactDustMaterial() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_impactDustMaterial != (Object)null) { return _impactDustMaterial; } _impactDustMaterial = CreateSoftParticleMaterial("LethalCCTV_TurretDustMaterial", new Color(0.52f, 0.46f, 0.34f, 0.58f), additive: false); return _impactDustMaterial; } private static Material GetMuzzleFlashMaterial() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_muzzleFlashMaterial != (Object)null) { return _muzzleFlashMaterial; } _muzzleFlashMaterial = CreateSoftParticleMaterial("LethalCCTV_TurretMuzzleFlashMaterial", new Color(1f, 0.72f, 0.16f, 0.86f), additive: true); return _muzzleFlashMaterial; } private static Material GetMuzzleSmokeMaterial() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_muzzleSmokeMaterial != (Object)null) { return _muzzleSmokeMaterial; } _muzzleSmokeMaterial = CreateSoftParticleMaterial("LethalCCTV_TurretMuzzleSmokeMaterial", new Color(0.44f, 0.44f, 0.4f, 0.38f), additive: false); return _muzzleSmokeMaterial; } private static Material CreateSoftParticleMaterial(string name, Color color, bool additive) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) Shader val = Shader.Find(additive ? "Particles/Additive" : "Particles/Standard Unlit") ?? Shader.Find("HDRP/Unlit") ?? Shader.Find("Standard"); if ((Object)(object)val == (Object)null) { return null; } Material val2 = new Material(val) { name = name, color = color, renderQueue = 3000 }; Texture2D softParticleTexture = GetSoftParticleTexture(); if ((Object)(object)softParticleTexture != (Object)null) { if (val2.HasProperty("_MainTex")) { val2.SetTexture("_MainTex", (Texture)(object)softParticleTexture); } if (val2.HasProperty("_BaseColorMap")) { val2.SetTexture("_BaseColorMap", (Texture)(object)softParticleTexture); } if (val2.HasProperty("_UnlitColorMap")) { val2.SetTexture("_UnlitColorMap", (Texture)(object)softParticleTexture); } } if (val2.HasProperty("_BaseColor")) { val2.SetColor("_BaseColor", color); } if (val2.HasProperty("_UnlitColor")) { val2.SetColor("_UnlitColor", color); } if (val2.HasProperty("_Color")) { val2.SetColor("_Color", color); } if (val2.HasProperty("_SurfaceType")) { val2.SetFloat("_SurfaceType", 1f); } if (val2.HasProperty("_BlendMode")) { val2.SetFloat("_BlendMode", additive ? 1f : 0f); } if (val2.HasProperty("_AlphaCutoffEnable")) { val2.SetFloat("_AlphaCutoffEnable", 0f); } val2.EnableKeyword("_ALPHABLEND_ON"); return val2; } private static Texture2D GetSoftParticleTexture() { //IL_001a: 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) //IL_002a: 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) //IL_0039: Expected O, but got Unknown //IL_006b: 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_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) if ((Object)(object)_softParticleTexture != (Object)null) { return _softParticleTexture; } Texture2D val = new Texture2D(64, 64, (TextureFormat)4, true, false) { name = "LethalCCTV_SoftParticleTexture", wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; Color[] array = (Color[])(object)new Color[4096]; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(31.5f, 31.5f); float num = 32f; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num2 = Vector2.Distance(new Vector2((float)j, (float)i), val2) / num; float num3 = Mathf.Clamp01(1f - num2); num3 = num3 * num3 * (3f - 2f * num3); array[i * 64 + j] = new Color(1f, 1f, 1f, num3); } } val.SetPixels(array); val.Apply(true, true); _softParticleTexture = val; return _softParticleTexture; } private static void BuildVisual(Transform fixtureParent, Transform gunParent) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_0103: 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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Expected O, but got Unknown //IL_019b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_visualPrefab != (Object)null) { GameObject obj = Object.Instantiate(_visualPrefab, fixtureParent); ((Object)obj).name = "PetitCanonVisual"; obj.transform.localPosition = PitchPivotLocalPosition; obj.transform.localRotation = Quaternion.identity; obj.transform.localScale = Vector3.one; ScaleVisualToTargetSize(obj); SplitVisualIntoFixtureAndGun(obj, gunParent); NormalizeTurretMaterialsForVisibility(obj); return; } GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)obj2).name = "FallbackTurretBase"; obj2.transform.SetParent(fixtureParent, false); obj2.transform.localPosition = new Vector3(0f, 0.24f, 0f); obj2.transform.localScale = new Vector3(1.15f, 0.24f, 1.15f); GameObject obj3 = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)obj3).name = "FallbackTurretHousing"; obj3.transform.SetParent(gunParent, false); obj3.transform.localPosition = Vector3.zero; obj3.transform.localScale = new Vector3(0.95f, 0.55f, 0.78f); GameObject obj4 = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)obj4).name = "FallbackTurretBarrel"; obj4.transform.SetParent(gunParent, false); obj4.transform.localPosition = new Vector3(0f, 0.08f, 1.33f); obj4.transform.localScale = new Vector3(0.26f, 0.22f, 2.55f); Material val = new Material(Shader.Find("HDRP/Unlit") ?? Shader.Find("Standard")); val.color = new Color(0.28f, 0.29f, 0.27f, 1f); Renderer[] componentsInChildren = _root.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].sharedMaterial = val; } } private static void SplitVisualIntoFixtureAndGun(GameObject visual, Transform gunParent) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_0097: 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_00ba: 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_00d2: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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_016d: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)visual == (Object)null || (Object)(object)gunParent == (Object)null) { return; } Renderer[] array = (from renderer in visual.GetComponentsInChildren(true) where (Object)(object)renderer != (Object)null && !(renderer is ParticleSystemRenderer) select renderer).ToArray(); if (array.Length == 0) { return; } Transform transform = visual.transform; bool flag = false; Bounds val = default(Bounds); Dictionary localBoundsByRenderer = new Dictionary(); foreach (Renderer val2 in array) { Bounds val3 = ConvertWorldBoundsToLocal(val2.bounds, transform); localBoundsByRenderer[val2] = val3; if (!flag) { val = val3; flag = true; } else { ((Bounds)(ref val)).Encapsulate(val3); } } if (!flag) { return; } Vector3 size = ((Bounds)(ref val)).size; if (((Vector3)(ref size)).sqrMagnitude <= 0.0001f) { return; } float num2 = ((Bounds)(ref val)).min.y + ((Bounds)(ref val)).size.y * 0.36f; float num3 = ((Bounds)(ref val)).min.y + ((Bounds)(ref val)).size.y * 0.18f; float num4 = ((Bounds)(ref val)).center.z + ((Bounds)(ref val)).size.z * 0.16f; HashSet hashSet = new HashSet(); foreach (KeyValuePair item in localBoundsByRenderer) { Bounds value = item.Value; bool num5 = ((Bounds)(ref value)).center.y > num2; bool flag2 = ((Bounds)(ref value)).center.z > num4 && ((Bounds)(ref value)).center.y > num3; if (num5 || flag2) { hashSet.Add(item.Key); } } if (hashSet.Count == 0) { Renderer val4 = array.OrderByDescending(delegate(Renderer renderer) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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) Bounds val5 = localBoundsByRenderer[renderer]; return ((Bounds)(ref val5)).center.y + ((Bounds)(ref val5)).center.z * 0.2f; }).FirstOrDefault(); if ((Object)(object)val4 != (Object)null) { hashSet.Add(val4); } } HashSet hashSet2 = new HashSet(); foreach (Renderer item2 in hashSet.OrderByDescending((Renderer renderer) => GetTransformDepth(((Component)renderer).transform))) { Transform transform2 = ((Component)item2).transform; if (!((Object)(object)transform2 == (Object)null) && !((Object)(object)transform2 == (Object)(object)transform) && !HasMovedAncestor(transform2, hashSet2, transform)) { transform2.SetParent(gunParent, true); hashSet2.Add(transform2); } } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV.Turret] Split turret visual into fixed fixture and moving gun. renderers={array.Length} gun={hashSet2.Count}."); } } private static Bounds ConvertWorldBoundsToLocal(Bounds worldBounds, Transform localRoot) { //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_000a: 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_0018: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_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_003f: 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_0047: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0093: 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_009f: 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_00b0: 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_00b7: 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) //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_00d6: 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_00dd: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0120: 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_0127: 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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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_0183: Unknown result type (might be due to invalid IL or missing references) Vector3 extents = ((Bounds)(ref worldBounds)).extents; Vector3 center = ((Bounds)(ref worldBounds)).center; 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) }; Bounds result = default(Bounds); ((Bounds)(ref result))..ctor(localRoot.InverseTransformPoint(array[0]), Vector3.zero); for (int i = 1; i < array.Length; i++) { ((Bounds)(ref result)).Encapsulate(localRoot.InverseTransformPoint(array[i])); } return result; } private static int GetTransformDepth(Transform transform) { int num = 0; while ((Object)(object)transform != (Object)null) { num++; transform = transform.parent; } return num; } private static bool HasMovedAncestor(Transform transform, HashSet movedRoots, Transform stopAt) { Transform parent = transform.parent; while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)stopAt) { if (movedRoots.Contains(parent)) { return true; } parent = parent.parent; } return false; } private static void NormalizeTurretMaterialsForVisibility(GameObject visual) { Renderer[] array = (((Object)(object)visual != (Object)null) ? visual.GetComponentsInChildren(true) : null); if (array == null || array.Length == 0) { return; } foreach (Renderer val in array) { if ((Object)(object)val == (Object)null || val is ParticleSystemRenderer) { continue; } Material[] sharedMaterials = val.sharedMaterials; if (sharedMaterials != null && sharedMaterials.Length != 0) { Material[] array2 = (Material[])(object)new Material[sharedMaterials.Length]; for (int j = 0; j < sharedMaterials.Length; j++) { array2[j] = CreateStableUnlitMaterial(sharedMaterials[j], "LethalCCTV_TurretVisibleMaterial"); } val.sharedMaterials = array2; } } } private static Material CreateStableUnlitMaterial(Material source, string name) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) Shader val = Shader.Find("HDRP/Unlit") ?? Shader.Find("Unlit/Texture") ?? Shader.Find("Standard"); if ((Object)(object)val == (Object)null && (Object)(object)source == (Object)null) { return null; } Material val2 = (((Object)(object)val != (Object)null) ? new Material(val) : new Material(source)); ((Object)val2).name = name; Texture materialTexture = GetMaterialTexture(source); if ((Object)(object)materialTexture != (Object)null) { if (val2.HasProperty("_MainTex")) { val2.SetTexture("_MainTex", materialTexture); } if (val2.HasProperty("_BaseColorMap")) { val2.SetTexture("_BaseColorMap", materialTexture); } if (val2.HasProperty("_UnlitColorMap")) { val2.SetTexture("_UnlitColorMap", materialTexture); } } Color materialColor = GetMaterialColor(source); materialColor.a = Mathf.Max(materialColor.a, 1f); if (val2.HasProperty("_Color")) { val2.SetColor("_Color", materialColor); } if (val2.HasProperty("_BaseColor")) { val2.SetColor("_BaseColor", materialColor); } if (val2.HasProperty("_UnlitColor")) { val2.SetColor("_UnlitColor", materialColor); } if (val2.HasProperty("_EmissiveColor")) { val2.SetColor("_EmissiveColor", materialColor * 0.32f); } if (val2.HasProperty("_EmissionColor")) { val2.SetColor("_EmissionColor", materialColor * 0.32f); } val2.EnableKeyword("_EMISSION"); return val2; } private static Texture GetMaterialTexture(Material material) { if ((Object)(object)material == (Object)null) { return null; } string[] array = new string[4] { "_BaseColorMap", "_UnlitColorMap", "_MainTex", "_BaseMap" }; foreach (string text in array) { if (material.HasProperty(text)) { Texture texture = material.GetTexture(text); if ((Object)(object)texture != (Object)null) { return texture; } } } return null; } private static Color GetMaterialColor(Material material) { //IL_0009: 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_0041: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material == (Object)null) { return Color.white; } string[] array = new string[3] { "_BaseColor", "_UnlitColor", "_Color" }; foreach (string text in array) { if (material.HasProperty(text)) { return material.GetColor(text); } } return Color.white; } private static void ScaleVisualToTargetSize(GameObject visual) { //IL_0020: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0045: 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) Renderer[] array = (((Object)(object)visual != (Object)null) ? visual.GetComponentsInChildren(true) : null); if (array == null || array.Length == 0) { return; } bool flag = false; Bounds val = default(Bounds); foreach (Renderer val2 in array) { if (!((Object)(object)val2 == (Object)null)) { if (!flag) { val = val2.bounds; flag = true; } else { ((Bounds)(ref val)).Encapsulate(val2.bounds); } } } if (!flag) { return; } float num = Mathf.Max(((Bounds)(ref val)).size.x, Mathf.Max(((Bounds)(ref val)).size.y, ((Bounds)(ref val)).size.z)); if (!(num <= 0.001f)) { float num2 = Mathf.Clamp(4.35f / num, 1f, 80f); visual.transform.localScale = Vector3.one * num2; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV.Turret] Visual autoscaled maxDimension={num:0.###}m target={4.35f:0.##}m scale={num2:0.###}."); } } } private static void EnsureRenderTexture() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_003e: Expected O, but got Unknown if (!((Object)(object)_renderTexture != (Object)null)) { _renderTexture = new RenderTexture(1024, 768, 16, (RenderTextureFormat)0) { name = "LethalCCTV_ShipTurretRT", useMipMap = false, autoGenerateMips = false }; _renderTexture.Create(); } } private static void EnsureAudioSources() { if (!((Object)(object)_root == (Object)null)) { if (_fireSource == null) { _fireSource = CreateAudioSource("TurretFireAudio", spatial: true, loop: false); } if (_rotateSource == null) { _rotateSource = CreateAudioSource("TurretRotateAudio", spatial: false, loop: false); } if (_zoomSource == null) { _zoomSource = CreateAudioSource("TurretZoomAudio", spatial: false, loop: false); } } } private static AudioSource CreateAudioSource(string name, bool spatial, bool loop) { //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_001c: 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) GameObject val = new GameObject(name); val.transform.SetParent(_root.transform, false); val.transform.localPosition = Vector3.zero; AudioSource obj = val.AddComponent(); obj.playOnAwake = false; obj.loop = loop; obj.spatialBlend = (spatial ? 1f : 0f); obj.rolloffMode = (AudioRolloffMode)1; obj.minDistance = 4f; obj.maxDistance = 85f; return obj; } private static void EnsureAssetsLoaded() { if (_bundleLoadAttempted) { return; } _bundleLoadAttempted = true; string directoryName = Path.GetDirectoryName(typeof(SurveillanceBootstrap).Assembly.Location); string text = ((!string.IsNullOrEmpty(directoryName)) ? Path.Combine(directoryName, "shipturret.turretbundle") : "shipturret.turretbundle"); if (!File.Exists(text)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV.Turret] Asset bundle missing at '" + text + "'. Using fallback turret visual.")); } return; } try { _bundle = AssetBundle.LoadFromFile(text); if ((Object)(object)_bundle == (Object)null) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV.Turret] AssetBundle.LoadFromFile returned null for '" + text + "'.")); } return; } string[] allAssetNames = _bundle.GetAllAssetNames(); _visualPrefab = LoadFirst((IEnumerable)allAssetNames, new string[3] { "shipturret_prefab", "petit", "turret" }); _dustExplosionPrefab = LoadFirst((IEnumerable)allAssetNames, new string[1] { "dustexplosion" }); _fireClips = (from n in allAssetNames where n.IndexOf("cannon", StringComparison.OrdinalIgnoreCase) >= 0 || n.IndexOf("firing", StringComparison.OrdinalIgnoreCase) >= 0 || n.IndexOf("blast", StringComparison.OrdinalIgnoreCase) >= 0 select _bundle.LoadAsset(n) into c where (Object)(object)c != (Object)null select c).ToArray(); _zoomClip = LoadFirst((IEnumerable)allAssetNames, new string[1] { "zoom" }); _rotateClip = _zoomClip; ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogInfo((object)$"[LethalCCTV.Turret] Bundle loaded prefab={(Object)(object)_visualPrefab != (Object)null} dust={(Object)(object)_dustExplosionPrefab != (Object)null} fireClips={((_fireClips != null) ? _fireClips.Length : 0)} rotate={(Object)(object)_rotateClip != (Object)null} zoom={(Object)(object)_zoomClip != (Object)null}."); } } catch (Exception ex) { ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogWarning((object)("[LethalCCTV.Turret] Bundle load failed: " + ex.Message)); } } } private static T LoadFirst(IEnumerable names, params string[] tokens) where T : Object { if (names == null) { return default(T); } foreach (string name in names) { if (string.IsNullOrEmpty(name)) { continue; } bool flag = false; for (int i = 0; i < tokens.Length; i++) { if (name.IndexOf(tokens[i], StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; break; } } if (flag) { T val = _bundle.LoadAsset(name); if ((Object)(object)val != (Object)null) { return val; } } } return default(T); } } public static class ShipTurretDebugApi { public static void StartPlacement() { ShipTurretController.StartDebugPlacement(); } public static void StartPlacement(string layoutName) { ShipTurretController.StartDebugPlacement(layoutName); } public static void ShowPreview() { ShipTurretController.ShowDebugPreview(); } public static void ClearPreview() { ShipTurretController.ClearDebugPreview(); } public static string GetStatus() { return ShipTurretController.GetDebugStatus(); } } internal static class VanillaRadarFeed { private struct PlayerMarkerCounts { internal int Backings; internal int Fills; internal int Facings; internal int Glyphs; internal int Labels; } private sealed class RadarMesh { internal readonly GameObject GameObject; internal readonly Transform Transform; internal readonly MeshFilter Filter; internal readonly MeshRenderer Renderer; internal RadarMesh(GameObject gameObject, MeshFilter filter, MeshRenderer renderer) { GameObject = gameObject; Transform = (((Object)(object)gameObject != (Object)null) ? gameObject.transform : null); Filter = filter; Renderer = renderer; } } private sealed class RadarLabel { internal readonly GameObject GameObject; internal readonly Transform Transform; internal readonly TextMeshPro Text; internal readonly MeshRenderer Renderer; internal RadarLabel(GameObject gameObject, TextMeshPro text, MeshRenderer renderer) { GameObject = gameObject; Transform = (((Object)(object)gameObject != (Object)null) ? gameObject.transform : null); Text = text; Renderer = renderer; } } private const int FALLBACK_WIDTH = 1024; private const int FALLBACK_HEIGHT = 576; private const float SETUP_RETRY_SECONDS = 1f; private const float TARGET_UPDATE_INTERVAL = 1f / 6f; private const float TARGET_FLOOR_RAY_UP_M = 2f; private const float TARGET_FLOOR_RAY_DOWN_M = 24f; private const float TARGET_FLOOR_OFFSET_M = 0.06f; private const float RADAR_FPS = 4f; private const float FIXED_RADAR_ORTHOGRAPHIC_MULTIPLIER = 1f; private const float RADAR_ZOOM_MIN_MULTIPLIER = 0.55f; private const float RADAR_ZOOM_MAX_MULTIPLIER = 1.75f; private const float RADAR_ZOOM_STEP = 0.88f; private const float FLOOR_GROUP_TOLERANCE_M = 7.5f; private const float MARKER_FLOOR_OFFSET_M = 0.18f; private const float MARKER_FLOOR_WINDOW_M = 8f; private const float CAMERA_CONE_LENGTH_M = 4.25f; private const float CAMERA_CONE_HALF_ANGLE_DEG = 18f; private const float CAMERA_CONE_ACTIVE_SCALE = 1.25f; private const float CAMERA_ACTIVE_HALO_SCALE = 1.6f; private const float MARKER_BASE_RADIUS_M = 2.8f; private const float MARKER_REFERENCE_ORTHO_M = 19.7f; private const float MARKER_RATIO_PLAYER = 1f; private const float MARKER_RATIO_ENEMY = 1.15f; private const float MARKER_RATIO_OBJECTIVE = 1.75f; private const float MARKER_RATIO_CAMERA = 0.7f; private const float MARKER_RATIO_CAMERA_ACTIVE = 1.25f; private const float MARKER_RATIO_ITEM = 0.55f; private const float RADAR_BLIP_SCALE_MIN = 0.5f; private const float RADAR_BLIP_SCALE_MAX = 2.5f; private const float CAMERA_MARKER_RADIUS_M = 1.9599999f; private const float ACTIVE_CAMERA_MARKER_RADIUS_M = 3.5f; private const float PLAYER_MARKER_RADIUS_M = 2.8f; private const float ENEMY_MARKER_RADIUS_M = 3.2199998f; private const float OBJECTIVE_MARKER_RADIUS_M = 4.9f; private const float ITEM_MARKER_RADIUS_M = 1.54f; private const float OBJECTIVE_RADIUS_CROSSOVER_M = 3.55f; private const float OBJECTIVE_RADIUS_TERM_SCALE = 1.3802817f; private const float CAMERA_LABEL_OFFSET_M = 3.5f; private const float CAMERA_LABEL_HEIGHT_M = 1.9599999f; private const float PLAYER_LABEL_HEIGHT_M = 1.736f; private const float PLAYER_LABEL_OFFSET_M = 5.18f; private const int PLAYER_LABEL_MAX_CHARS = 10; private const float PLAYER_BACKING_SCALE = 1.34f; private const float PLAYER_FACING_SCALE = 0.62f; private const float PLAYER_GLYPH_SCALE = 0.54f; private const float PLAYER_GLYPH_SIDE_OFFSET_RADII = 1.55f; private const float PLAYER_HEALTH_HEALTHY_MIN = 66f; private const float PLAYER_HEALTH_HURT_MIN = 33f; private const float OFFSCREEN_EDGE_MARGIN_VIEWPORT = 0.045f; private const float ITEM_SCAN_INTERVAL = 1f; private const string LEGEND_ALPHA_HEX = "E6"; private const int MAP_RADAR_LAYER = 14; private const int ROOM_LAYER = 8; private const string StationaryMapUiPlaceholderName = "LethalCCTV_RadarPlaceholder_MapCameraStationaryUI"; private static GameObject _root; private static GameObject _targetObject; private static GameObject _markerRoot; private static ManualCameraRenderer _renderer; private static Camera _mapCamera; private static RenderTexture _texture; private static IReadOnlyList _cameras; private static float _baseOrthographicSize; private static int _originalCullingMask; private static bool _interiorRadarChecked; private static bool _interiorHasRadarSprites = true; private static bool _loggedInteriorFallback; private static float _nextCullingOverrideAt; private static bool _loggedCullingOverride; private static bool _cullingOverridesSettled; private static readonly List _deadOverrideKeys = new List(64); private static float _nextSetupAttemptTime; private static bool _loggedReady; private static bool _loggedMissing; private static float _radarZoomMultiplier = 1f; private static Material _cameraMarkerMaterial; private static Material _activeCameraMarkerMaterial; private static Material _activeCameraHaloMaterial; private static Material _cameraConeMaterial; private static Material _playerBackingMaterial; private static Material _playerHealthyMaterial; private static Material _playerHurtMaterial; private static Material _playerCriticalMaterial; private static Material _playerFacingMaterial; private static Material _playerGlyphMaterial; private static Material _enemyMarkerMaterial; private static Material _objectiveMarkerMaterial; private static Material _itemMarkerMaterial; private static Mesh _circleMesh; private static Mesh _ringMesh; private static Mesh _squareMesh; private static Mesh _diamondMesh; private static Mesh _triangleMesh; private static Mesh _coneMesh; private static Mesh _xMesh; private static float _nextTargetUpdateAt; private static bool _active = true; private static float _markerScreenScale = 1f; private static bool _radarViewValid; private static string _legendLabel; private static float _nextItemScanAt; private static readonly List _cameraMarkers = new List(64); private static readonly List _cameraCones = new List(64); private static readonly List _cameraHalos = new List(8); private static readonly List _cameraLabels = new List(64); private static readonly List _playerBackings = new List(8); private static readonly List _playerMarkers = new List(8); private static readonly List _playerFacings = new List(8); private static readonly List _playerGlyphs = new List(8); private static readonly List _playerLabels = new List(8); private static readonly List _enemyMarkers = new List(32); private static readonly List _objectiveMarkers = new List(8); private static readonly List _itemMarkers = new List(64); private static readonly List _itemScanBuffer = new List(64); private static readonly List _floorYScratch = new List(8); private static readonly Color ObjectiveMarkerColor = new Color(1f, 0.88f, 0.1f, 1f); private static readonly Color ActiveCameraMarkerColor = new Color(1f, 0.52f, 0.02f, 1f); private static readonly Color IdleCameraMarkerColor = new Color(0.42f, 0.78f, 1f, 0.98f); private static readonly Color PlayerHealthyMarkerColor = new Color(0.3f, 1f, 0.46f, 0.98f); private static readonly Color EnemyMarkerColor = new Color(1f, 0.18f, 0.1f, 1f); private static readonly Color ItemMarkerColor = new Color(0.46f, 1f, 0.84f, 0.94f); private static readonly Color CameraLabelColor = new Color(0.74f, 0.92f, 1f, 0.98f); private static readonly Color ActiveCameraLabelColor = new Color(1f, 0.68f, 0.12f, 1f); private static readonly Color PlayerLabelColor = new Color(0.92f, 0.97f, 1f, 0.98f); internal static bool IsEnabled { get { if (SurveillanceBootstrap.Config != null && SurveillanceBootstrap.Config.UseVanillaRadarFeed != null) { return SurveillanceBootstrap.Config.UseVanillaRadarFeed.Value; } return false; } } internal static bool HasLiveTexture { get { if (IsEnabled && (Object)(object)_texture != (Object)null && (Object)(object)_renderer != (Object)null) { return (Object)(object)_mapCamera != (Object)null; } return false; } } private static bool ShowItemBlips { get { if (SurveillanceBootstrap.Config?.ShowRadarItemBlips != null) { return SurveillanceBootstrap.Config.ShowRadarItemBlips.Value; } return true; } } internal static void SetCameras(IReadOnlyList cameras) { _cameras = cameras; } internal static void ClearCameras() { _cameras = null; HideAllMarkers(); _interiorRadarChecked = false; _interiorHasRadarSprites = true; _loggedInteriorFallback = false; _nextCullingOverrideAt = 0f; _loggedCullingOverride = false; _cullingOverridesSettled = false; _itemScanBuffer.Clear(); _nextItemScanAt = 0f; } internal static Texture PeekTexture() { if (!HasLiveTexture) { return null; } return (Texture)(object)_texture; } internal static Texture ResolveTexture() { if (!IsEnabled) { return null; } if (!_active) { return PeekTexture(); } EnsureReady(); TickTargetThrottled(); EnsureRadarSpritesUncullable(); if (!HasLiveTexture) { return null; } return (Texture)(object)_texture; } internal static void Tick() { if (IsEnabled && _active) { EnsureReady(); TickTargetThrottled(); EnsureRadarSpritesUncullable(); } } private static void EnsureRadarSpritesUncullable() { if (Time.unscaledTime < _nextCullingOverrideAt) { return; } _nextCullingOverrideAt = Time.unscaledTime + 5f; if (!InteriorHasRadarSprites()) { return; } if (_cullingOverridesSettled) { _nextCullingOverrideAt = Time.unscaledTime + 30f; } GameObject val = GameObject.Find("Systems/LevelGeneration/LevelGenerationRoot"); if ((Object)(object)val == (Object)null) { return; } AdjacentRoomCullingModified[] array = Object.FindObjectsOfType(true); if (array == null || array.Length == 0) { return; } List list = new List(128); CollectChildrenOnLayer(val.transform, 14, list); if (list.Count == 0) { return; } int num = 0; int num2 = 0; foreach (AdjacentRoomCullingModified val2 in array) { if ((Object)(object)val2 == (Object)null) { continue; } Dictionary dictionary = val2.OverrideRendererVisibilities; if (dictionary == null) { dictionary = (val2.OverrideRendererVisibilities = new Dictionary()); } else if (dictionary.Count > 0) { _deadOverrideKeys.Clear(); foreach (KeyValuePair item in dictionary) { if ((Object)(object)item.Key == (Object)null) { _deadOverrideKeys.Add(item.Key); } } for (int j = 0; j < _deadOverrideKeys.Count; j++) { dictionary.Remove(_deadOverrideKeys[j]); } } for (int k = 0; k < list.Count; k++) { GameObject val3 = list[k]; if ((Object)(object)val3 == (Object)null) { continue; } SpriteRenderer component = val3.GetComponent(); if (!((Object)(object)component == (Object)null)) { if (!dictionary.ContainsKey((Renderer)(object)component)) { dictionary[(Renderer)(object)component] = true; num++; val2.dirty = true; } if (!((Renderer)component).enabled) { ((Renderer)component).enabled = true; num2++; } } } } _cullingOverridesSettled = num == 0 && num2 == 0; if ((num > 0 || num2 > 0) && !_loggedCullingOverride) { _loggedCullingOverride = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV] Radar room sprites exempted from adjacent-room culling: registered={num} " + $"reenabled={num2} cullers={array.Length} (#569 black-underlay fix).")); } } } internal static void SetActive(bool active) { _active = active; if ((Object)(object)_root != (Object)null && _root.activeSelf != active) { _root.SetActive(active); } if ((Object)(object)_renderer != (Object)null && ((Behaviour)_renderer).enabled != active) { ((Behaviour)_renderer).enabled = active; } if (!active) { if ((Object)(object)_mapCamera != (Object)null) { ((Behaviour)_mapCamera).enabled = false; } HideAllMarkers(); } else if ((Object)(object)_root != (Object)null && !_root.activeSelf) { _root.SetActive(true); } } internal static string GetRenderDiagnostics() { if (!IsEnabled) { return "radar feed: disabled by config"; } string arg = (((Object)(object)_texture != (Object)null) ? $"{((Texture)_texture).width}x{((Texture)_texture).height}" : ""); bool flag = (Object)(object)_renderer != (Object)null && _renderer.renderAtLowerFramerate; float num = (((Object)(object)_renderer != (Object)null) ? _renderer.fps : 0f); bool flag2 = (Object)(object)_mapCamera != (Object)null && ((Behaviour)_mapCamera).enabled; return $"radar feed: rt={arg} fps={num:F1} renderAtLowerFramerate={flag} " + $"camEnabled={flag2} targetUpdateInterval={1f / 6f:F3}s zoom={_radarZoomMultiplier:F2}x live={HasLiveTexture}"; } internal static string GetStatusLabel() { CCTVCamera activeCamera = MonitorFocus.GetActiveCamera(); if ((Object)(object)activeCamera == (Object)null) { return "RADAR MAP STANDBY"; } return "RADAR MAP " + ResolveActiveFloorLabel(activeCamera); } internal static string GetLegendLabel() { //IL_0015: 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_0053: 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) if (_legendLabel != null) { return _legendLabel; } _legendLabel = BuildLegendEntry(ObjectiveMarkerColor, "<>", "OBJECTIVE") + " " + BuildLegendEntry(IdleCameraMarkerColor, "^", "CAM") + " " + BuildLegendEntry(PlayerHealthyMarkerColor, "O", "CREW") + " " + BuildLegendEntry(EnemyMarkerColor, "X", "THREAT"); return _legendLabel; } private static string BuildLegendEntry(Color color, string glyph, string name) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) return "" + glyph + " " + name + ""; } internal static void AdjustZoom(float wheelSteps) { if (!(Mathf.Abs(wheelSteps) < 0.001f)) { _radarZoomMultiplier = Mathf.Clamp(_radarZoomMultiplier * Mathf.Pow(0.88f, wheelSteps), 0.55f, 1.75f); ApplyZoom(MonitorFocus.GetActiveCamera()); _nextTargetUpdateAt = 0f; } } internal static void Shutdown() { if ((Object)(object)_mapCamera != (Object)null) { _mapCamera.targetTexture = null; } if ((Object)(object)_texture != (Object)null) { _texture.Release(); Object.Destroy((Object)(object)_texture); } _texture = null; if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _targetObject = null; _markerRoot = null; _renderer = null; _mapCamera = null; _baseOrthographicSize = 0f; ClearMarkerPools(); DestroyMarkerResources(); _loggedReady = false; _loggedMissing = false; _nextSetupAttemptTime = 0f; _nextTargetUpdateAt = 0f; _radarZoomMultiplier = 1f; _active = true; } private static void EnsureReady() { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_0539: Expected O, but got Unknown if (HasLiveTexture || Time.unscaledTime < _nextSetupAttemptTime) { return; } _nextSetupAttemptTime = Time.unscaledTime + 1f; ManualCameraRenderer val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.mapScreen : null); if ((Object)(object)val == (Object)null || (Object)(object)val.mapCamera == (Object)null) { LogMissingOnce("vanilla mapScreen/mapCamera unavailable"); return; } Transform itemSystems = ResolveItemSystems(); GameObject val2 = ResolveMapCameraTemplate(itemSystems, val); GameObject val3 = ResolveMapUiTemplate(itemSystems); if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { LogMissingOnce("vanilla MapCamera or MapScreenUI template unavailable"); return; } ShutdownPartial(); try { _root = new GameObject("LethalCCTV_VanillaRadarFeed"); if ((Object)(object)SurveillanceBootstrap.Instance != (Object)null) { _root.transform.SetParent(((Component)SurveillanceBootstrap.Instance).transform, false); } _targetObject = new GameObject("LethalCCTV_VanillaRadarTarget"); _targetObject.transform.SetParent(_root.transform, false); _markerRoot = new GameObject("LethalCCTV_VanillaRadarMarkers"); _markerRoot.transform.SetParent(_root.transform, false); SetLayerRecursively(_markerRoot, 14); GameObject obj = Object.Instantiate(val2, _root.transform, false); ((Object)obj).name = "LethalCCTV_VanillaRadarCamera"; TrySetUntagged(obj); DisableClonedAnimators(obj); _mapCamera = obj.GetComponent(); if ((Object)(object)_mapCamera == (Object)null) { throw new InvalidOperationException("cloned MapCamera has no Camera component"); } _originalCullingMask = _mapCamera.cullingMask; _baseOrthographicSize = _mapCamera.orthographicSize; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV] Radar map camera base ortho {_baseOrthographicSize:0.##} m " + $"(marker reference {19.7f} m).")); } ManualCameraRenderer[] components = obj.GetComponents(); for (int i = 0; i < components.Length; i++) { ((Behaviour)components[i]).enabled = false; } _texture = CreateTargetTexture(val); _mapCamera.targetTexture = _texture; ((Behaviour)_mapCamera).enabled = false; GameObject obj2 = Object.Instantiate(val3, _root.transform, false); ((Object)obj2).name = "LethalCCTV_VanillaRadarScreenUI"; DisableClonedAnimators(obj2); Canvas component = obj2.GetComponent(); if ((Object)(object)component != (Object)null) { component.worldCamera = _mapCamera; if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.radarCanvas != (Object)null) { component.planeDistance = StartOfRound.Instance.radarCanvas.planeDistance; } } DestroyChildIfPresent(obj2.transform, "PlanetVideoReel"); DestroyChildIfPresent(obj2.transform, "PlanetDescription"); LineRenderer lineFromRadarTargetToExit = CreateExitLine(val); GameObject val4 = CreateHiddenPlaceholder(obj2.transform, "ShipArrowUI"); Transform transform = CreateHiddenPlaceholder(obj2.transform, "ShipArrowPointer").transform; GameObject val5 = CreateHiddenPlaceholder(obj2.transform, "ShipIcon"); GameObject val6 = CreateHiddenPlaceholder(obj2.transform, "LostSignalUI"); Image val7 = CreateHiddenComponent(obj2.transform, "CompassRose"); RawImage val8 = CreateHiddenComponent(obj2.transform, "HeadMountedCamUI"); Image val9 = CreateHiddenComponent(obj2.transform, "LocalPlayerPlaceholder"); HideClonedChildIfPresent(obj2.transform, val.shipArrowUI, "ShipArrowUI"); HideClonedChildIfPresent(obj2.transform, val.shipIcon, "ShipIcon"); HideClonedChildIfPresent(obj2.transform, val.LostSignalUI, "LostSignalUI"); HideClonedChildIfPresent(obj2.transform, (Component)(object)val.compassRose, "CompassRose"); HideClonedChildIfPresent(obj2.transform, (Component)(object)val.headMountedCamUI, "HeadMountedCamUI"); HideClonedChildIfPresent(obj2.transform, (Component)(object)val.localPlayerPlaceholder, "LocalPlayerPlaceholder"); if ((Object)(object)val4 != (Object)null) { val4.SetActive(false); } if ((Object)(object)val5 != (Object)null) { val5.SetActive(false); } if ((Object)(object)val6 != (Object)null) { val6.SetActive(false); } if ((Object)(object)val7 != (Object)null) { ((Behaviour)val7).enabled = false; } if ((Object)(object)val8 != (Object)null) { ((Behaviour)val8).enabled = false; } if ((Object)(object)val9 != (Object)null) { ((Behaviour)val9).enabled = false; } Transform mapCameraStationaryUI = SuppressClonedStationaryMapUi(obj2.transform, val.mapCameraStationaryUI); _renderer = _root.AddComponent(); _renderer.cameraNearPlane = val.cameraNearPlane; _renderer.cameraFarPlane = val.cameraFarPlane; _renderer.cam = _mapCamera; _renderer.mapCamera = _mapCamera; _renderer.mapCameraStationaryUI = mapCameraStationaryUI; _renderer.shipArrowUI = val4; _renderer.shipArrowPointer = transform; _renderer.shipIcon = val5; _renderer.compassRose = val7; _renderer.headMountedCam = null; _renderer.headMountedCamData = null; _renderer.headMountedCamUI = val8; _renderer.localPlayerPlaceholder = val9; _renderer.LostSignalUI = val6; _renderer.mapCameraAnimator = null; _renderer.lineFromRadarTargetToExit = lineFromRadarTargetToExit; _renderer.radarTargets = new List { new TransformAndName(_targetObject.transform, "CCTV", true) }; _renderer.targetTransformIndex = 0; _renderer.targetedPlayer = null; _renderer.currentCameraDisabled = false; _renderer.overrideCameraForOtherUse = false; _renderer.overrideRadarCameraOnAlways = true; _renderer.renderAtLowerFramerate = true; _renderer.fps = 4f; ValidateManualRendererReferences(_renderer); TickTarget(); _nextTargetUpdateAt = Time.unscaledTime + 1f / 6f; LogReadyOnce(); } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Vanilla radar feed unavailable; using schematic fallback. " + ex.GetType().Name + ": " + ex.Message)); } ShutdownPartial(); } } private static void TickTargetThrottled() { if (!(Time.unscaledTime < _nextTargetUpdateAt)) { _nextTargetUpdateAt = Time.unscaledTime + 1f / 6f; TickTarget(); } } private static void TickTarget() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_003c: 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_0092: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown if (!((Object)(object)_targetObject == (Object)null) && !((Object)(object)_renderer == (Object)null)) { CCTVCamera activeCamera = MonitorFocus.GetActiveCamera(); Vector3 target = ResolveTargetPosition(activeCamera); ApplyStableTargetPose(target); ApplyInteriorFallbackMask(activeCamera, target); ApplyZoom(activeCamera); UpdateMarkers(activeCamera, target); if (_renderer.radarTargets == null) { _renderer.radarTargets = new List(); } if (_renderer.radarTargets.Count == 0) { _renderer.radarTargets.Add(new TransformAndName(_targetObject.transform, "CCTV", true)); } else { _renderer.radarTargets[0] = new TransformAndName(_targetObject.transform, ((Object)(object)activeCamera != (Object)null) ? activeCamera.ResolvedLabel : "CCTV", true); } _renderer.targetTransformIndex = 0; _renderer.targetedPlayer = null; _renderer.currentCameraDisabled = (Object)(object)activeCamera == (Object)null; } } private static Vector3 ResolveTargetPosition(CCTVCamera active) { //IL_0050: 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_0056: 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_0028: 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) //IL_0060: 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_006b: 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_0038: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)active == (Object)null) { if (!((Object)(object)StartOfRound.Instance != (Object)null) || !((Object)(object)StartOfRound.Instance.elevatorTransform != (Object)null)) { return Vector3.zero; } return StartOfRound.Instance.elevatorTransform.position; } if (TryResolveTileCenterAnchor(active, out var target)) { return target; } Vector3 position = ((Component)active).transform.position; if (TryProjectToFloor(position, out var floor)) { return floor + Vector3.up * 0.06f; } return position; } private static bool TryResolveTileCenterAnchor(CCTVCamera active, out Vector3 target) { //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_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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_008d: 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_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_00b3: 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_00bd: 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_00c1: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_00e0: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) target = Vector3.zero; Tile owningTile = active.OwningTile; if ((Object)(object)owningTile != (Object)null && owningTile.Placement != null) { Bounds val = DungeonCameraSpawner.ComputeWorldAabbLocal(owningTile); Vector3 size = ((Bounds)(ref val)).size; if (((Vector3)(ref size)).sqrMagnitude < 1E-06f) { val = owningTile.Placement.LocalBounds; } size = ((Bounds)(ref val)).size; if (((Vector3)(ref size)).sqrMagnitude > 1E-06f) { Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).min.y + 0.06f, ((Bounds)(ref val)).center.z); Vector3 val3 = owningTile.Placement.Position + owningTile.Placement.Rotation * val2; if (TryProjectToFloor(val3 + Vector3.up * 0.5f, out var floor)) { val3 = floor + Vector3.up * 0.06f; } target = val3; return true; } } return false; } private static void ApplyInteriorFallbackMask(CCTVCamera active, Vector3 target) { if ((Object)(object)_mapCamera == (Object)null) { return; } if ((Object)(object)active == (Object)null || InteriorHasRadarSprites()) { _mapCamera.cullingMask = _originalCullingMask; return; } _mapCamera.cullingMask = BuildOldInteriorRadarMask(); if (!_loggedInteriorFallback) { _loggedInteriorFallback = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Vanilla radar feed detected an interior without radar sprites; using Universal Radar-style old interior radar mask."); } } } private static bool InteriorHasRadarSprites() { if (_interiorRadarChecked) { return _interiorHasRadarSprites; } _interiorRadarChecked = true; _interiorHasRadarSprites = DetectInteriorRadarSprites(); return _interiorHasRadarSprites; } private static bool DetectInteriorRadarSprites() { //IL_009f: 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_00a8: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.Find("Systems/LevelGeneration/LevelGenerationRoot"); if ((Object)(object)val == (Object)null) { return LogSpriteVerdict(hasSprites: false, "no LevelGenerationRoot", 0, 0, 0, 0); } List list = new List(128); CollectChildrenOnLayer(val.transform, 14, list); if (list.Count < 5) { return LogSpriteVerdict(hasSprites: false, "fewer than 5 radar-layer objects", list.Count, 0, 0, 0); } int num = 0; int num2 = 0; for (int i = 0; i < list.Count; i++) { GameObject val2 = list[i]; if ((Object)(object)val2 == (Object)null) { continue; } if (val2.CompareTag("RadarRoomSprite")) { num++; } SpriteRenderer component = val2.GetComponent(); if ((Object)(object)component != (Object)null) { Bounds bounds = ((Renderer)component).bounds; float x = ((Bounds)(ref bounds)).size.x; bounds = ((Renderer)component).bounds; if (x * ((Bounds)(ref bounds)).size.z > 2f) { num2++; } } } if (num >= 5) { return LogSpriteVerdict(hasSprites: true, "tagged sprites", list.Count, num, num2, 0); } int num3 = Object.FindObjectsOfType().Length; if (num3 <= 0) { return LogSpriteVerdict(hasSprites: false, "no tiles", list.Count, num, num2, 0); } if (1f - (float)list.Count / (float)num3 > 0.1f) { return LogSpriteVerdict(hasSprites: false, "layer-object/tile ratio", list.Count, num, num2, num3); } if (1f - (float)num2 / (float)num3 > 0.1f) { return LogSpriteVerdict(hasSprites: false, "large-sprite/tile ratio", list.Count, num, num2, num3); } return LogSpriteVerdict(hasSprites: true, "sprite/tile ratios", list.Count, num, num2, num3); } private static bool LogSpriteVerdict(bool hasSprites, string reason, int layerObjects, int tagged, int large, int tiles) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV] Interior radar-sprite detection: hasSprites={hasSprites} ({reason}); " + $"radarLayerObjects={layerObjects} taggedSprites={tagged} largeSprites={large} tiles={tiles}. " + "Radar mode for this interior: " + (hasSprites ? "vanilla sprites" : "old-interior geometry fallback") + ".")); } return hasSprites; } private static void CollectChildrenOnLayer(Transform current, int targetLayer, List results) { if ((Object)(object)current == (Object)null) { return; } for (int i = 0; i < current.childCount; i++) { Transform child = current.GetChild(i); if (((Component)child).gameObject.layer == targetLayer) { results.Add(((Component)child).gameObject); } CollectChildrenOnLayer(child, targetLayer, results); } } private static int BuildOldInteriorRadarMask() { return 16640; } private static void ApplyZoom(CCTVCamera active) { if (!((Object)(object)_mapCamera == (Object)null) && _mapCamera.orthographic && !(_baseOrthographicSize <= 0f)) { _mapCamera.orthographicSize = _baseOrthographicSize * 1f * _radarZoomMultiplier; } } private static void ApplyStableTargetPose(Vector3 target) { //IL_0018: 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) if (!((Object)(object)_targetObject == (Object)null)) { _targetObject.transform.SetPositionAndRotation(target, Quaternion.identity); } } private static void UpdateMarkers(CCTVCamera active, Vector3 target) { //IL_0052: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_markerRoot == (Object)null)) { if ((Object)(object)active == (Object)null || !EnsureMarkerAssets()) { HideAllMarkers(); return; } _markerScreenScale = ResolveMarkerScreenScale(); _radarViewValid = ResolveRadarViewValid(); int markerCount = 0; int coneCount = 0; int haloCount = 0; int labelCount = 0; PlayerMarkerCounts counts = default(PlayerMarkerCounts); int count = 0; int count2 = 0; int count3 = 0; UpdateCameraMarkers(active, target, ref markerCount, ref coneCount, ref haloCount, ref labelCount); UpdatePlayerMarkers(active, target, ref counts); UpdateEnemyMarkers(active, target, ref count); UpdateObjectiveMarkers(active, target, ref count2); UpdateItemMarkers(active, target, ref count3); DeactivateUnused(_cameraMarkers, markerCount); DeactivateUnused(_cameraCones, coneCount); DeactivateUnused(_cameraHalos, haloCount); DeactivateUnused(_cameraLabels, labelCount); DeactivateUnused(_playerBackings, counts.Backings); DeactivateUnused(_playerMarkers, counts.Fills); DeactivateUnused(_playerFacings, counts.Facings); DeactivateUnused(_playerGlyphs, counts.Glyphs); DeactivateUnused(_playerLabels, counts.Labels); DeactivateUnused(_enemyMarkers, count); DeactivateUnused(_objectiveMarkers, count2); DeactivateUnused(_itemMarkers, count3); } } private static float ResolveMarkerScreenScale() { float num = ResolveBlipScale(); if ((Object)(object)_mapCamera == (Object)null || !_mapCamera.orthographic || _baseOrthographicSize <= 0f) { return num; } return _mapCamera.orthographicSize / 19.7f * num; } private static float ResolveBlipScale() { LethalCCTVConfig config = SurveillanceBootstrap.Config; if (config == null || config.RadarBlipScale == null) { return 1f; } return Mathf.Clamp(config.RadarBlipScale.Value, 0.5f, 2.5f); } private static bool ResolveRadarViewValid() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0036: 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_005b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_mapCamera == (Object)null || (Object)(object)_targetObject == (Object)null) { return false; } Vector3 val = _mapCamera.WorldToViewportPoint(_targetObject.transform.position); if (val.z > 0f && Mathf.Abs(val.x - 0.5f) <= 0.25f) { return Mathf.Abs(val.y - 0.5f) <= 0.25f; } return false; } private static void UpdateCameraMarkers(CCTVCamera active, Vector3 target, ref int markerCount, ref int coneCount, ref int haloCount, ref int labelCount) { //IL_0051: 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) bool flag = false; if (_cameras != null) { for (int i = 0; i < _cameras.Count; i++) { CCTVCamera cCTVCamera = _cameras[i]; if (!((Object)(object)cCTVCamera == (Object)null)) { if ((Object)(object)cCTVCamera == (Object)(object)active) { flag = true; } AddCameraMarker(cCTVCamera, active, target, ref markerCount, ref coneCount, ref haloCount, ref labelCount); } } } if (!flag) { AddCameraMarker(active, active, target, ref markerCount, ref coneCount, ref haloCount, ref labelCount); } } private static void AddCameraMarker(CCTVCamera camera, CCTVCamera active, Vector3 target, ref int markerCount, ref int coneCount, ref int haloCount, ref int labelCount) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_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_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)camera == (Object)null) && ShouldShowCamera(camera, active, target)) { Vector3 val = ResolveCameraMarkerPosition(camera); Vector3 val2 = FlattenForward(((Component)camera).transform.forward); bool flag = (Object)(object)camera == (Object)(object)active; RadarMesh radarMesh = EnsureRadarMesh(_cameraMarkers, markerCount++, "CameraMarker", EnsureTriangleMesh(), flag ? _activeCameraMarkerMaterial : _cameraMarkerMaterial); radarMesh.Transform.position = val; radarMesh.Transform.rotation = ((((Vector3)(ref val2)).sqrMagnitude > 1E-06f) ? Quaternion.LookRotation(val2, Vector3.up) : Quaternion.identity); float num = (flag ? 3.5f : 1.9599999f) * _markerScreenScale; radarMesh.Transform.localScale = new Vector3(num, num, num); if (flag) { RadarMesh radarMesh2 = EnsureRadarMesh(_cameraHalos, haloCount++, "CameraHalo", EnsureRingMesh(), _activeCameraHaloMaterial); radarMesh2.Transform.position = val; radarMesh2.Transform.rotation = Quaternion.identity; float num2 = num * 1.6f; radarMesh2.Transform.localScale = new Vector3(num2, num2, num2); } if (((Vector3)(ref val2)).sqrMagnitude > 1E-06f && flag) { RadarMesh radarMesh3 = EnsureRadarMesh(_cameraCones, coneCount++, "CameraCone", EnsureConeMesh(), _cameraConeMaterial); radarMesh3.Transform.position = val; radarMesh3.Transform.rotation = Quaternion.LookRotation(val2, Vector3.up); radarMesh3.Transform.localScale = Vector3.one * 1.25f * _markerScreenScale; } UpdateCameraLabel(EnsureCameraLabel(labelCount++), camera, val, flag); } } private static bool ShouldShowCamera(CCTVCamera camera, CCTVCamera active, Vector3 target) { //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) if ((Object)(object)camera == (Object)null || (Object)(object)active == (Object)null) { return false; } return IsOnActiveInteriorFloor(ResolveCameraMarkerPosition(camera), target); } private static Vector3 ResolveCameraMarkerPosition(CCTVCamera camera) { //IL_0006: 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) return ProjectMarkerPosition(((Component)camera).transform.position); } private static void UpdatePlayerMarkers(CCTVCamera active, Vector3 target, ref PlayerMarkerCounts counts) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || instance.allPlayerScripts == null) { return; } for (int i = 0; i < instance.allPlayerScripts.Length; i++) { PlayerControllerB val = instance.allPlayerScripts[i]; if (!((Object)(object)val == (Object)null) && val.isPlayerControlled && !val.isPlayerDead && val.isInsideFactory) { bool onFloor = IsOnActiveInteriorFloor(((Component)val).transform.position, target); Vector3 val2 = ProjectMarkerPosition(((Component)val).transform.position); if (!IsWithinRadarView(val2, out var clampedPosition, out var edgeDirection)) { AddOffScreenPlayerMarker(val, clampedPosition, edgeDirection, ref counts); } else { AddPlayerMarker(val, val2, onFloor, target, ref counts); } } } } private static void AddPlayerMarker(PlayerControllerB player, Vector3 markerPosition, bool onFloor, Vector3 target, ref PlayerMarkerCounts counts) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00c9: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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_016e: 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_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) float num = 2.8f * _markerScreenScale; RadarMesh radarMesh = EnsureRadarMesh(_playerBackings, counts.Backings++, "PlayerBacking", EnsureCircleMesh(), _playerBackingMaterial); radarMesh.Transform.position = markerPosition; radarMesh.Transform.rotation = Quaternion.identity; radarMesh.Transform.localScale = Vector3.one * num * 1.34f; RadarMesh radarMesh2 = EnsureRadarMesh(_playerMarkers, counts.Fills++, "PlayerMarker", onFloor ? EnsureCircleMesh() : EnsureRingMesh(), ResolvePlayerHealthMaterial(player)); radarMesh2.Transform.position = markerPosition; radarMesh2.Transform.rotation = Quaternion.identity; radarMesh2.Transform.localScale = Vector3.one * num; Vector3 val = FlattenForward(((Component)player).transform.forward); if (((Vector3)(ref val)).sqrMagnitude > 1E-06f) { RadarMesh radarMesh3 = EnsureRadarMesh(_playerFacings, counts.Facings++, "PlayerFacing", EnsureConeMesh(), _playerFacingMaterial); radarMesh3.Transform.position = markerPosition; radarMesh3.Transform.rotation = Quaternion.LookRotation(val, Vector3.up); radarMesh3.Transform.localScale = Vector3.one * 0.62f * _markerScreenScale; } if (!onFloor) { Vector3 val2 = ResolveRadarScreenUp(); bool flag = ((Component)player).transform.position.y > target.y; Vector3 offset = ResolveRadarScreenRight() * (num * 1.55f); AddPlayerGlyph(markerPosition, flag ? val2 : (-val2), offset, ref counts); } AddPlayerLabel(player, markerPosition, ref counts); } private static void AddOffScreenPlayerMarker(PlayerControllerB player, Vector3 clampedPosition, Vector3 edgeDirection, ref PlayerMarkerCounts counts) { //IL_002d: 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_0048: 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_005c: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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) RadarMesh radarMesh = EnsureRadarMesh(_playerBackings, counts.Backings++, "PlayerBacking", EnsureCircleMesh(), _playerBackingMaterial); radarMesh.Transform.position = clampedPosition; radarMesh.Transform.rotation = Quaternion.identity; radarMesh.Transform.localScale = Vector3.one * 2.8f * _markerScreenScale * 1.34f * 0.82f; AddPlayerGlyph(clampedPosition, edgeDirection, Vector3.zero, ref counts); AddPlayerLabel(player, clampedPosition, ref counts); } private static void AddPlayerGlyph(Vector3 position, Vector3 pointDirection, Vector3 offset, ref PlayerMarkerCounts counts) { //IL_002d: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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) //IL_006f: 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_0083: 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) RadarMesh radarMesh = EnsureRadarMesh(_playerGlyphs, counts.Glyphs++, "PlayerGlyph", EnsureTriangleMesh(), _playerGlyphMaterial); radarMesh.Transform.position = position + offset; radarMesh.Transform.rotation = ((((Vector3)(ref pointDirection)).sqrMagnitude > 1E-06f) ? Quaternion.LookRotation(((Vector3)(ref pointDirection)).normalized, Vector3.up) : Quaternion.identity); radarMesh.Transform.localScale = Vector3.one * 2.8f * _markerScreenScale * 0.54f; } private static void AddPlayerLabel(PlayerControllerB player, Vector3 markerPosition, ref PlayerMarkerCounts counts) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_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_008f: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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) RadarLabel radarLabel = EnsureLabel(_playerLabels, counts.Labels++, "PlayerLabel", 1.736f, PlayerLabelColor); if (radarLabel != null && !((Object)(object)radarLabel.Transform == (Object)null) && !((Object)(object)radarLabel.Text == (Object)null)) { string text = FormatPlayerLabel(player); if (((TMP_Text)radarLabel.Text).text != text) { ((TMP_Text)radarLabel.Text).text = text; } radarLabel.Transform.position = markerPosition + ResolveRadarScreenUp() * (5.18f * _markerScreenScale) + Vector3.up * 0.1f; radarLabel.Transform.rotation = ResolveRadarTextRotation(); radarLabel.Transform.localScale = Vector3.one * _markerScreenScale; } } private static Material ResolvePlayerHealthMaterial(PlayerControllerB player) { float num = (((Object)(object)player != (Object)null) ? Mathf.Clamp((float)player.health, 0f, 100f) : 100f); if (num >= 66f) { return _playerHealthyMaterial; } if (num >= 33f) { return _playerHurtMaterial; } return _playerCriticalMaterial; } private static string FormatPlayerLabel(PlayerControllerB player) { string text = (((Object)(object)player != (Object)null && !string.IsNullOrWhiteSpace(player.playerUsername)) ? player.playerUsername.Trim() : "PLAYER"); if (text.Length <= 10) { return text; } return text.Substring(0, 10); } private static Vector3 ResolveRadarScreenUp() { //IL_001d: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_mapCamera == (Object)null) { return Vector3.forward; } Vector3 up = ((Component)_mapCamera).transform.up; up.y = 0f; if (!(((Vector3)(ref up)).sqrMagnitude > 1E-06f)) { return Vector3.forward; } return ((Vector3)(ref up)).normalized; } private static Vector3 ResolveRadarScreenRight() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) return Vector3.Cross(Vector3.up, ResolveRadarScreenUp()); } private static bool IsWithinRadarView(Vector3 position, out Vector3 clampedPosition, out Vector3 edgeDirection) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0033: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_005b: Unknown result type (might be due to invalid IL or missing references) clampedPosition = position; edgeDirection = Vector3.zero; if ((Object)(object)_mapCamera == (Object)null || !_radarViewValid) { return true; } Vector3 val = _mapCamera.WorldToViewportPoint(position); if (val.x >= 0.045f && val.x <= 0.955f && val.y >= 0.045f && val.y <= 0.955f) { return true; } Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(Mathf.Clamp(val.x, 0.045f, 0.955f), Mathf.Clamp(val.y, 0.045f, 0.955f), val.z); clampedPosition = _mapCamera.ViewportToWorldPoint(val2); edgeDirection = position - clampedPosition; edgeDirection.y = 0f; if (((Vector3)(ref edgeDirection)).sqrMagnitude <= 1E-06f) { edgeDirection = ResolveRadarScreenUp(); } return false; } private static void UpdateEnemyMarkers(CCTVCamera active, Vector3 target, ref int count) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_00d2: Unknown result type (might be due to invalid IL or missing references) RoundManager instance = RoundManager.Instance; if ((Object)(object)instance == (Object)null || instance.SpawnedEnemies == null) { return; } for (int i = 0; i < instance.SpawnedEnemies.Count; i++) { EnemyAI val = instance.SpawnedEnemies[i]; if (!((Object)(object)val == (Object)null) && !val.isEnemyDead && !val.isInsidePlayerShip && !val.isOutside && IsOnActiveInteriorFloor(((Component)val).transform.position, target)) { RadarMesh radarMesh = EnsureRadarMesh(_enemyMarkers, count++, "EnemyMarker", EnsureXMesh(), _enemyMarkerMaterial); radarMesh.Transform.position = ProjectMarkerPosition(((Component)val).transform.position); radarMesh.Transform.rotation = Quaternion.identity; radarMesh.Transform.localScale = Vector3.one * 3.2199998f * _markerScreenScale; } } } private static void UpdateObjectiveMarkers(CCTVCamera active, Vector3 target, ref int count) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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) if ((Object)(object)active == (Object)null) { return; } IReadOnlyList markers = ContractObjectiveProvider.GetMarkers(); if (markers == null || markers.Count == 0) { return; } for (int i = 0; i < markers.Count; i++) { ContractObjectiveProvider.MarkerSnapshot objective = markers[i]; if (ShouldShowObjectiveOnRadar(objective) && IsOnActiveInteriorFloor(objective.Position, target)) { RadarMesh radarMesh = EnsureRadarMesh(_objectiveMarkers, count++, "ObjectiveMarker", EnsureDiamondMesh(), _objectiveMarkerMaterial); radarMesh.Transform.position = ProjectMarkerPosition(objective.Position); radarMesh.Transform.rotation = Quaternion.identity; float num = Mathf.Max(4.9f, objective.Radius * 1.3802817f); radarMesh.Transform.localScale = Vector3.one * num * _markerScreenScale; } } } private static void UpdateItemMarkers(CCTVCamera active, Vector3 target, ref int count) { //IL_006d: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)active == (Object)null || !ShowItemBlips) { return; } RefreshItemScan(); for (int i = 0; i < _itemScanBuffer.Count; i++) { GrabbableObject val = _itemScanBuffer[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val.itemProperties == (Object)null) && !val.isHeld && !val.isPocketed && !val.isHeldByEnemy && IsOnActiveInteriorFloor(((Component)val).transform.position, target) && IsWithinRadarView(((Component)val).transform.position, out var _, out var _)) { RadarMesh radarMesh = EnsureRadarMesh(_itemMarkers, count++, "ItemMarker", EnsureSquareMesh(), _itemMarkerMaterial); radarMesh.Transform.position = ProjectMarkerPosition(((Component)val).transform.position); radarMesh.Transform.rotation = Quaternion.identity; radarMesh.Transform.localScale = Vector3.one * 1.54f * _markerScreenScale; } } } private static void RefreshItemScan() { if (Time.unscaledTime < _nextItemScanAt) { return; } _nextItemScanAt = Time.unscaledTime + 1f; _itemScanBuffer.Clear(); GrabbableObject[] array = Object.FindObjectsOfType(); foreach (GrabbableObject val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.itemProperties == (Object)null) && val.itemProperties.isScrap && !val.isInShipRoom && !val.isInElevator && val.isInFactory) { _itemScanBuffer.Add(val); } } } private static bool ShouldShowObjectiveOnRadar(ContractObjectiveProvider.MarkerSnapshot objective) { return !objective.IsComplete; } private static bool IsOnActiveInteriorFloor(Vector3 position, Vector3 target) { //IL_0000: 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) return Mathf.Abs(position.y - target.y) <= 8f; } private static Vector3 ProjectMarkerPosition(Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_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) if (TryProjectToFloor(position, out var floor)) { return floor + Vector3.up * 0.18f; } return position + Vector3.up * 0.18f; } private static Vector3 FlattenForward(Vector3 forward) { //IL_0022: 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) forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 1E-06f) { return Vector3.zero; } return ((Vector3)(ref forward)).normalized; } private static string ResolveActiveFloorLabel(CCTVCamera active) { if ((Object)(object)active == (Object)null) { return "STANDBY"; } List floorYScratch = _floorYScratch; floorYScratch.Clear(); if (_cameras != null) { for (int i = 0; i < _cameras.Count; i++) { CCTVCamera cCTVCamera = _cameras[i]; if (!((Object)(object)cCTVCamera == (Object)null)) { AddFloorGroupY(floorYScratch, ResolveCameraFloorY(cCTVCamera)); } } } float y = ResolveCameraFloorY(active); AddFloorGroupY(floorYScratch, y); floorYScratch.Sort(); int num = FindFloorGroupIndex(floorYScratch, y); int num2 = ResolveMainEntranceFloorGroupIndex(floorYScratch); return FormatFloorLabel(Mathf.Max(0, num) - Mathf.Max(0, num2)); } private static float ResolveCameraFloorY(CCTVCamera camera) { //IL_00d5: 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_0033: 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) //IL_0058: 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_0050: 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_00c4: 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_007c: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)camera == (Object)null) { return 0f; } Tile owningTile = camera.OwningTile; if ((Object)(object)owningTile != (Object)null && owningTile.Placement != null) { Bounds val = DungeonCameraSpawner.ComputeWorldAabbLocal(owningTile); Vector3 size = ((Bounds)(ref val)).size; if (((Vector3)(ref size)).sqrMagnitude < 1E-06f) { val = owningTile.Placement.LocalBounds; } size = ((Bounds)(ref val)).size; if (((Vector3)(ref size)).sqrMagnitude >= 1E-06f) { Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).min.y, ((Bounds)(ref val)).center.z); return (owningTile.Placement.Position + owningTile.Placement.Rotation * val2).y; } return owningTile.Placement.Position.y; } return ((Component)camera).transform.position.y; } private static void AddFloorGroupY(List floorYs, float y) { if (floorYs != null) { int num = FindFloorGroupIndex(floorYs, y); if (num >= 0) { floorYs[num] = (floorYs[num] + y) * 0.5f; } else { floorYs.Add(y); } } } private static int FindFloorGroupIndex(List floorYs, float y) { if (floorYs == null) { return -1; } for (int i = 0; i < floorYs.Count; i++) { if (Mathf.Abs(floorYs[i] - y) <= 7.5f) { return i; } } return -1; } private static int ResolveMainEntranceFloorGroupIndex(List floorYs) { if (floorYs == null || floorYs.Count == 0) { return 0; } if (!TryResolveInteriorMainEntranceY(out var y)) { return 0; } int result = 0; float num = Mathf.Abs(floorYs[0] - y); for (int i = 1; i < floorYs.Count; i++) { float num2 = Mathf.Abs(floorYs[i] - y); if (!(num2 >= num)) { result = i; num = num2; } } return result; } private static bool TryResolveInteriorMainEntranceY(out float y) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) EntranceTeleport[] array = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); EntranceTeleport val = null; foreach (EntranceTeleport val2 in array) { if (!((Object)(object)val2 == (Object)null) && !val2.isEntranceToBuilding && ((Object)(object)val == (Object)null || val2.entranceId == 0)) { val = val2; if (val2.entranceId == 0) { break; } } } if ((Object)(object)val != (Object)null) { Transform val3 = (((Object)(object)val.entrancePoint != (Object)null) ? val.entrancePoint : ((Component)val).transform); y = val3.position.y; return true; } y = 0f; return false; } private static string FormatFloorLabel(int floorRank) { if (floorRank == 0) { return "FLOOR 1"; } if (floorRank > 0) { return "FLOOR " + (floorRank + 1); } return "BASEMENT " + -floorRank; } private static RadarMesh EnsureRadarMesh(List pool, int index, string name, Mesh mesh, Material material) { while (pool.Count <= index) { pool.Add(CreateRadarMesh(name + "_" + pool.Count.ToString("D2"))); } RadarMesh radarMesh = pool[index]; if (radarMesh == null || (Object)(object)radarMesh.GameObject == (Object)null) { radarMesh = (pool[index] = CreateRadarMesh(name + "_" + index.ToString("D2"))); } radarMesh.GameObject.SetActive(true); radarMesh.Filter.sharedMesh = mesh; ((Renderer)radarMesh.Renderer).sharedMaterial = material; return radarMesh; } private static RadarMesh CreateRadarMesh(string name) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown GameObject val = new GameObject("LethalCCTV_Radar_" + name); if ((Object)(object)_markerRoot != (Object)null) { val.transform.SetParent(_markerRoot.transform, false); } SetLayerRecursively(val, 14); MeshFilter filter = val.AddComponent(); MeshRenderer val2 = val.AddComponent(); ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; ((Renderer)val2).lightProbeUsage = (LightProbeUsage)0; ((Renderer)val2).reflectionProbeUsage = (ReflectionProbeUsage)0; return new RadarMesh(val, filter, val2); } private static RadarLabel EnsureCameraLabel(int index) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) return EnsureLabel(_cameraLabels, index, "CameraLabel", 1.9599999f, CameraLabelColor); } private static RadarLabel EnsureLabel(List pool, int index, string name, float fontSize, Color color) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) while (pool.Count <= index) { pool.Add(CreateRadarLabel(name, pool.Count, fontSize, color)); } RadarLabel radarLabel = pool[index]; if (radarLabel == null || (Object)(object)radarLabel.GameObject == (Object)null) { radarLabel = (pool[index] = CreateRadarLabel(name, index, fontSize, color)); } radarLabel.GameObject.SetActive(true); return radarLabel; } private static RadarLabel CreateRadarLabel(string name, int index, float fontSize, Color color) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_008e: 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) GameObject val = new GameObject("LethalCCTV_Radar_" + name + "_" + index.ToString("D2")); if ((Object)(object)_markerRoot != (Object)null) { val.transform.SetParent(_markerRoot.transform, false); } SetLayerRecursively(val, 14); TextMeshPro val2 = val.AddComponent(); ((TMP_Text)val2).alignment = (TextAlignmentOptions)514; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).fontSize = fontSize; ((TMP_Text)val2).fontStyle = (FontStyles)1; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; ((TMP_Text)val2).enableCulling = false; ((TMP_Text)val2).text = string.Empty; ((Graphic)val2).color = color; ((TMP_Text)val2).rectTransform.sizeDelta = new Vector2(4.4f, 1.1f); TryAssignHudFont((TMP_Text)(object)val2); MeshRenderer component = val.GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component).receiveShadows = false; ((Renderer)component).lightProbeUsage = (LightProbeUsage)0; ((Renderer)component).reflectionProbeUsage = (ReflectionProbeUsage)0; } return new RadarLabel(val, val2, component); } private static void UpdateCameraLabel(RadarLabel label, CCTVCamera camera, Vector3 markerPosition, bool isActive) { //IL_0056: 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_008c: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) if (label != null && !((Object)(object)label.Transform == (Object)null) && !((Object)(object)label.Text == (Object)null)) { string text = FormatCameraShortLabel(camera); if (((TMP_Text)label.Text).text != text) { ((TMP_Text)label.Text).text = text; } ((Graphic)label.Text).color = (isActive ? ActiveCameraLabelColor : CameraLabelColor); ((TMP_Text)label.Text).fontSize = (isActive ? 2.254f : 1.9599999f); float num = 3.5f * _markerScreenScale; label.Transform.position = markerPosition + new Vector3(num, 0.08f, num * 0.58f); label.Transform.rotation = ResolveRadarTextRotation(); label.Transform.localScale = Vector3.one * _markerScreenScale; } } private static Quaternion ResolveRadarTextRotation() { //IL_0045: 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_001c: 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_0030: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_mapCamera != (Object)null) { return Quaternion.LookRotation(-((Component)_mapCamera).transform.forward, ((Component)_mapCamera).transform.up); } return Quaternion.Euler(-90f, 0f, 0f); } private static string FormatCameraShortLabel(CCTVCamera camera) { if ((Object)(object)camera == (Object)null) { return "CAM"; } int num = ((camera.CameraIndex >= 0) ? camera.CameraIndex : IndexOfCamera(camera)); if (num < 0) { return "CAM"; } return "C" + (num + 1).ToString("00"); } private static int IndexOfCamera(CCTVCamera camera) { if ((Object)(object)camera == (Object)null || _cameras == null) { return -1; } for (int i = 0; i < _cameras.Count; i++) { if (_cameras[i] == camera) { return i; } } return -1; } private static void DeactivateUnused(List pool, int used) { for (int i = used; i < pool.Count; i++) { RadarMesh radarMesh = pool[i]; if (radarMesh != null && (Object)(object)radarMesh.GameObject != (Object)null) { radarMesh.GameObject.SetActive(false); } } } private static void DeactivateUnused(List pool, int used) { for (int i = used; i < pool.Count; i++) { RadarLabel radarLabel = pool[i]; if (radarLabel != null && (Object)(object)radarLabel.GameObject != (Object)null) { radarLabel.GameObject.SetActive(false); } } } private static void HideAllMarkers() { DeactivateUnused(_cameraMarkers, 0); DeactivateUnused(_cameraCones, 0); DeactivateUnused(_cameraHalos, 0); DeactivateUnused(_cameraLabels, 0); DeactivateUnused(_playerBackings, 0); DeactivateUnused(_playerMarkers, 0); DeactivateUnused(_playerFacings, 0); DeactivateUnused(_playerGlyphs, 0); DeactivateUnused(_playerLabels, 0); DeactivateUnused(_enemyMarkers, 0); DeactivateUnused(_objectiveMarkers, 0); DeactivateUnused(_itemMarkers, 0); } private static bool EnsureMarkerAssets() { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) _circleMesh = (((Object)(object)_circleMesh != (Object)null) ? _circleMesh : CreateCircleMesh()); _ringMesh = (((Object)(object)_ringMesh != (Object)null) ? _ringMesh : CreateRingMesh()); _squareMesh = (((Object)(object)_squareMesh != (Object)null) ? _squareMesh : CreateSquareMesh()); _diamondMesh = (((Object)(object)_diamondMesh != (Object)null) ? _diamondMesh : CreateDiamondMesh()); _triangleMesh = (((Object)(object)_triangleMesh != (Object)null) ? _triangleMesh : CreateTriangleMesh()); _coneMesh = (((Object)(object)_coneMesh != (Object)null) ? _coneMesh : CreateConeMesh()); _xMesh = (((Object)(object)_xMesh != (Object)null) ? _xMesh : CreateXMesh()); _cameraMarkerMaterial = _cameraMarkerMaterial ?? CreateRadarMaterial("LethalCCTV_RadarCameraMarker", IdleCameraMarkerColor, transparent: true); _activeCameraMarkerMaterial = _activeCameraMarkerMaterial ?? CreateRadarMaterial("LethalCCTV_RadarActiveCameraMarker", ActiveCameraMarkerColor, transparent: true); _activeCameraHaloMaterial = _activeCameraHaloMaterial ?? CreateRadarMaterial("LethalCCTV_RadarActiveCameraHalo", new Color(ActiveCameraMarkerColor.r, ActiveCameraMarkerColor.g, ActiveCameraMarkerColor.b, 0.45f), transparent: true, -2); _cameraConeMaterial = _cameraConeMaterial ?? CreateRadarMaterial("LethalCCTV_RadarCameraCone", new Color(ActiveCameraMarkerColor.r, ActiveCameraMarkerColor.g, ActiveCameraMarkerColor.b, 0.3f), transparent: true); _playerBackingMaterial = _playerBackingMaterial ?? CreateRadarMaterial("LethalCCTV_RadarPlayerBacking", new Color(0.02f, 0.04f, 0.06f, 0.94f), transparent: true, -4); _playerHealthyMaterial = _playerHealthyMaterial ?? CreateRadarMaterial("LethalCCTV_RadarPlayerHealthy", PlayerHealthyMarkerColor, transparent: true, -2); _playerHurtMaterial = _playerHurtMaterial ?? CreateRadarMaterial("LethalCCTV_RadarPlayerHurt", new Color(1f, 0.76f, 0.1f, 0.98f), transparent: true, -2); _playerCriticalMaterial = _playerCriticalMaterial ?? CreateRadarMaterial("LethalCCTV_RadarPlayerCritical", new Color(1f, 0.26f, 0.18f, 0.98f), transparent: true, -2); _playerFacingMaterial = _playerFacingMaterial ?? CreateRadarMaterial("LethalCCTV_RadarPlayerFacing", new Color(0.86f, 0.96f, 1f, 0.4f), transparent: true, -3); _playerGlyphMaterial = _playerGlyphMaterial ?? CreateRadarMaterial("LethalCCTV_RadarPlayerGlyph", new Color(0.92f, 0.98f, 1f, 0.96f), transparent: true); _enemyMarkerMaterial = _enemyMarkerMaterial ?? CreateRadarMaterial("LethalCCTV_RadarEnemyMarker", EnemyMarkerColor, transparent: true); _objectiveMarkerMaterial = _objectiveMarkerMaterial ?? CreateRadarMaterial("LethalCCTV_RadarObjectiveMarker", ObjectiveMarkerColor, transparent: true); _itemMarkerMaterial = _itemMarkerMaterial ?? CreateRadarMaterial("LethalCCTV_RadarItemMarker", ItemMarkerColor, transparent: true); if ((Object)(object)_circleMesh != (Object)null && (Object)(object)_ringMesh != (Object)null && (Object)(object)_squareMesh != (Object)null && (Object)(object)_diamondMesh != (Object)null && (Object)(object)_triangleMesh != (Object)null && (Object)(object)_coneMesh != (Object)null && (Object)(object)_xMesh != (Object)null && (Object)(object)_cameraMarkerMaterial != (Object)null && (Object)(object)_activeCameraMarkerMaterial != (Object)null && (Object)(object)_activeCameraHaloMaterial != (Object)null && (Object)(object)_cameraConeMaterial != (Object)null && (Object)(object)_playerBackingMaterial != (Object)null && (Object)(object)_playerHealthyMaterial != (Object)null && (Object)(object)_playerHurtMaterial != (Object)null && (Object)(object)_playerCriticalMaterial != (Object)null && (Object)(object)_playerFacingMaterial != (Object)null && (Object)(object)_playerGlyphMaterial != (Object)null && (Object)(object)_enemyMarkerMaterial != (Object)null && (Object)(object)_objectiveMarkerMaterial != (Object)null) { return (Object)(object)_itemMarkerMaterial != (Object)null; } return false; } private static Mesh EnsureCircleMesh() { return _circleMesh ?? (_circleMesh = CreateCircleMesh()); } private static Mesh EnsureRingMesh() { return _ringMesh ?? (_ringMesh = CreateRingMesh()); } private static Mesh EnsureSquareMesh() { return _squareMesh ?? (_squareMesh = CreateSquareMesh()); } private static Mesh EnsureDiamondMesh() { return _diamondMesh ?? (_diamondMesh = CreateDiamondMesh()); } private static Mesh EnsureTriangleMesh() { return _triangleMesh ?? (_triangleMesh = CreateTriangleMesh()); } private static Mesh EnsureConeMesh() { return _coneMesh ?? (_coneMesh = CreateConeMesh()); } private static Mesh EnsureXMesh() { return _xMesh ?? (_xMesh = CreateXMesh()); } private static Mesh CreateCircleMesh() { //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_0047: 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) Vector3[] array = (Vector3[])(object)new Vector3[19]; int[] array2 = new int[108]; array[0] = Vector3.zero; for (int i = 0; i < 18; i++) { float num = MathF.PI * 2f * (float)i / 18f; array[i + 1] = new Vector3(Mathf.Sin(num), 0f, Mathf.Cos(num)); } int num2 = 0; for (int j = 0; j < 18; j++) { int num3 = j + 1; int num4 = ((j == 17) ? 1 : (j + 2)); array2[num2++] = 0; array2[num2++] = num3; array2[num2++] = num4; array2[num2++] = 0; array2[num2++] = num4; array2[num2++] = num3; } return CreateFlatMesh("LethalCCTV_RadarCircleMesh", array, array2); } private static Mesh CreateRingMesh() { //IL_004d: 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_0066: 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) Vector3[] array = (Vector3[])(object)new Vector3[36]; int[] array2 = new int[216]; for (int i = 0; i < 18; i++) { float num = MathF.PI * 2f * (float)i / 18f; float num2 = Mathf.Sin(num); float num3 = Mathf.Cos(num); array[i * 2] = new Vector3(num2 * 0.58f, 0f, num3 * 0.58f); array[i * 2 + 1] = new Vector3(num2, 0f, num3); } int num4 = 0; for (int j = 0; j < 18; j++) { int num5 = j * 2; int num6 = num5 + 1; int num7 = (j + 1) % 18 * 2; int num8 = num7 + 1; array2[num4++] = num5; array2[num4++] = num6; array2[num4++] = num8; array2[num4++] = num5; array2[num4++] = num8; array2[num4++] = num6; array2[num4++] = num5; array2[num4++] = num8; array2[num4++] = num7; array2[num4++] = num5; array2[num4++] = num7; array2[num4++] = num8; } return CreateFlatMesh("LethalCCTV_RadarRingMesh", array, array2); } private static Mesh CreateSquareMesh() { //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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) Vector3[] vertices = (Vector3[])(object)new Vector3[4] { new Vector3(-0.78f, 0f, -0.78f), new Vector3(-0.78f, 0f, 0.78f), new Vector3(0.78f, 0f, 0.78f), new Vector3(0.78f, 0f, -0.78f) }; int[] triangles = new int[12] { 0, 1, 2, 0, 2, 1, 0, 2, 3, 0, 3, 2 }; return CreateFlatMesh("LethalCCTV_RadarSquareMesh", vertices, triangles); } private static Mesh CreateDiamondMesh() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_003e: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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) Vector3[] vertices = (Vector3[])(object)new Vector3[5] { Vector3.zero, new Vector3(0f, 0f, 1f), new Vector3(1f, 0f, 0f), new Vector3(0f, 0f, -1f), new Vector3(-1f, 0f, 0f) }; int[] triangles = new int[24] { 0, 1, 2, 0, 2, 1, 0, 2, 3, 0, 3, 2, 0, 3, 4, 0, 4, 3, 0, 4, 1, 0, 1, 4 }; return CreateFlatMesh("LethalCCTV_RadarDiamondMesh", vertices, triangles); } private static Mesh CreateTriangleMesh() { //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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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) //IL_0052: Unknown result type (might be due to invalid IL or missing references) Vector3[] vertices = (Vector3[])(object)new Vector3[3] { new Vector3(0f, 0f, 1f), new Vector3(-0.72f, 0f, -0.55f), new Vector3(0.72f, 0f, -0.55f) }; int[] triangles = new int[6] { 0, 1, 2, 0, 2, 1 }; return CreateFlatMesh("LethalCCTV_RadarTriangleMesh", vertices, triangles); } private static Mesh CreateConeMesh() { //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_0031: 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_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) float num = Mathf.Tan(MathF.PI / 10f) * 4.25f; Vector3[] vertices = (Vector3[])(object)new Vector3[3] { Vector3.zero, new Vector3(0f - num, 0f, 4.25f), new Vector3(num, 0f, 4.25f) }; int[] triangles = new int[6] { 0, 1, 2, 0, 2, 1 }; return CreateFlatMesh("LethalCCTV_RadarConeMesh", vertices, triangles); } private static Mesh CreateXMesh() { //IL_0012: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0098: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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_00df: 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_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_00f3: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Sqrt(0.5f); Vector3 val = new Vector3(num, 0f, num) * 1.05f; Vector3 val2 = new Vector3(num, 0f, 0f - num) * 0.3f; Vector3 val3 = new Vector3(num, 0f, 0f - num) * 1.05f; Vector3 val4 = new Vector3(num, 0f, num) * 0.3f; Vector3[] vertices = (Vector3[])(object)new Vector3[8] { -val - val2, -val + val2, val + val2, val - val2, -val3 - val4, -val3 + val4, val3 + val4, val3 - val4 }; int[] triangles = new int[24] { 0, 1, 2, 0, 2, 1, 0, 2, 3, 0, 3, 2, 4, 5, 6, 4, 6, 5, 4, 6, 7, 4, 7, 6 }; return CreateFlatMesh("LethalCCTV_RadarXMesh", vertices, triangles); } private static Mesh CreateFlatMesh(string name, Vector3[] vertices, int[] triangles) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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: Expected O, but got Unknown Mesh val = new Mesh { name = name, vertices = vertices, triangles = triangles }; val.RecalculateBounds(); return val; } private static Material CreateRadarMaterial(string name, Color color, bool transparent, int renderQueueOffset = 0) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0063: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0099: 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) Shader val = Shader.Find("HDRP/Unlit") ?? Shader.Find("HDRP/Lit") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Standard"); if ((Object)(object)val == (Object)null) { return null; } Material val2 = new Material(val) { name = name, color = color }; SetColorIfExists(val2, "_BaseColor", color); SetColorIfExists(val2, "_Color", color); SetColorIfExists(val2, "_UnlitColor", color); SetColorIfExists(val2, "_EmissionColor", color); SetColorIfExists(val2, "_EmissiveColor", color); SetColorIfExists(val2, "_EmissiveColorLDR", color); SetFloatIfExists(val2, "_EmissiveIntensity", 1f); SetFloatIfExists(val2, "_UseEmissiveIntensity", 1f); SetFloatIfExists(val2, "_DoubleSidedEnable", 1f); SetFloatIfExists(val2, "_CullMode", 0f); SetFloatIfExists(val2, "_CullModeForward", 0f); val2.EnableKeyword("_EMISSION"); val2.EnableKeyword("_DOUBLESIDED_ON"); if (transparent) { val2.SetOverrideTag("RenderType", "Transparent"); val2.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); val2.EnableKeyword("_ALPHABLEND_ON"); SetFloatIfExists(val2, "_SurfaceType", 1f); SetFloatIfExists(val2, "_BlendMode", 0f); SetFloatIfExists(val2, "_SrcBlend", 5f); SetFloatIfExists(val2, "_DstBlend", 10f); SetFloatIfExists(val2, "_AlphaSrcBlend", 1f); SetFloatIfExists(val2, "_AlphaDstBlend", 10f); SetFloatIfExists(val2, "_ZWrite", 0f); SetFloatIfExists(val2, "_TransparentZWrite", 0f); SetFloatIfExists(val2, "_ZTest", 8f); SetFloatIfExists(val2, "_ZTestTransparent", 8f); val2.renderQueue = 4000 + renderQueueOffset; } else { val2.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); SetFloatIfExists(val2, "_SurfaceType", 0f); SetFloatIfExists(val2, "_ZWrite", 1f); val2.renderQueue = 2020; } try { HDMaterial.ValidateMaterial(val2); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogDebug((object)("[LethalCCTV] Radar marker material validation skipped for '" + name + "': " + ex.Message)); } } return val2; } private static void SetColorIfExists(Material material, string propertyName, Color color) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material != (Object)null && material.HasProperty(propertyName)) { material.SetColor(propertyName, color); } } private static void SetFloatIfExists(Material material, string propertyName, float value) { if ((Object)(object)material != (Object)null && material.HasProperty(propertyName)) { material.SetFloat(propertyName, value); } } private static bool TryProjectToFloor(Vector3 position, out Vector3 floor) { //IL_001c: 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_0027: 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) //IL_0031: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) int num = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-5)); RaycastHit val = default(RaycastHit); if (Physics.Raycast(position + Vector3.up * 2f, Vector3.down, ref val, 26f, num, (QueryTriggerInteraction)1)) { floor = ((RaycastHit)(ref val)).point; return true; } floor = position; return false; } private static Transform ResolveItemSystems() { GameObject val = GameObject.Find("Systems/GameSystems/ItemSystems"); if (!((Object)(object)val != (Object)null)) { return null; } return val.transform; } private static GameObject ResolveMapCameraTemplate(Transform itemSystems, ManualCameraRenderer source) { Transform val = (((Object)(object)itemSystems != (Object)null) ? itemSystems.Find("MapCamera") : null); if ((Object)(object)val != (Object)null) { return ((Component)val).gameObject; } if (!((Object)(object)source.mapCamera != (Object)null)) { return null; } return ((Component)source.mapCamera).gameObject; } private static GameObject ResolveMapUiTemplate(Transform itemSystems) { Transform val = (((Object)(object)itemSystems != (Object)null) ? itemSystems.Find("MapScreenUI") : null); if ((Object)(object)val != (Object)null) { return ((Component)val).gameObject; } return GameObject.Find("Systems/GameSystems/ItemSystems/MapScreenUI"); } private static RenderTexture CreateTargetTexture(ManualCameraRenderer source) { //IL_006b: 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_0073: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0099: 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_00a8: Expected O, but got Unknown RenderTexture val = (((Object)(object)source.cam != (Object)null) ? source.cam.targetTexture : null); int num = (((Object)(object)val != (Object)null) ? ((Texture)val).width : 1024); int num2 = (((Object)(object)val != (Object)null) ? ((Texture)val).height : 576); int num3 = (((Object)(object)val != (Object)null) ? val.depth : 16); RenderTextureFormat val2 = (RenderTextureFormat)(((Object)(object)val != (Object)null) ? ((int)val.format) : 0); RenderTexture val3 = new RenderTexture(num, num2, num3, val2) { name = "LethalCCTV_VanillaRadarTexture", useDynamicScale = false, autoGenerateMips = false, filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; val3.Create(); return val3; } private static LineRenderer CreateExitLine(ManualCameraRenderer source) { //IL_003c: 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) if ((Object)(object)source.lineFromRadarTargetToExit != (Object)null) { LineRenderer obj = Object.Instantiate(source.lineFromRadarTargetToExit, _root.transform, false); ((Object)obj).name = "LethalCCTV_VanillaRadarExitLine"; ((Renderer)obj).enabled = false; return obj; } GameObject val = new GameObject("LethalCCTV_VanillaRadarExitLine"); val.transform.SetParent(_root.transform, false); LineRenderer obj2 = val.AddComponent(); ((Renderer)obj2).enabled = false; return obj2; } private static GameObject CreateHiddenPlaceholder(Transform parent, string name) { //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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_003d: 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_004e: Expected O, but got Unknown GameObject val = new GameObject("LethalCCTV_RadarPlaceholder_" + name); val.transform.SetParent(parent, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; return val; } private static T CreateHiddenComponent(Transform parent, string name) where T : Component { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_004d: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("LethalCCTV_RadarPlaceholder_" + name, new Type[2] { typeof(RectTransform), typeof(CanvasRenderer) }); val.transform.SetParent(parent, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; T val2 = val.AddComponent(); object obj = val2; Graphic val3 = (Graphic)((obj is Graphic) ? obj : null); if (val3 != null) { ((Behaviour)val3).enabled = false; val3.raycastTarget = false; val3.color = Color.clear; } return val2; } private static Transform SuppressClonedStationaryMapUi(Transform uiRoot, Transform sourceStationaryUi) { HideClonedChildIfPresent(uiRoot, ((Object)(object)sourceStationaryUi != (Object)null) ? ((Object)sourceStationaryUi).name : "MapCameraStationaryUI"); GameObject obj = CreateHiddenPlaceholder(uiRoot, "MapCameraStationaryUI"); ((Object)obj).name = "LethalCCTV_RadarPlaceholder_MapCameraStationaryUI"; obj.SetActive(false); return obj.transform; } private static void ValidateManualRendererReferences(ManualCameraRenderer renderer) { if ((Object)(object)renderer == (Object)null) { throw new InvalidOperationException("ManualCameraRenderer missing"); } if ((Object)(object)renderer.cam == (Object)null || (Object)(object)renderer.mapCamera == (Object)null) { throw new InvalidOperationException("ManualCameraRenderer camera/mapCamera missing"); } if ((Object)(object)renderer.shipArrowUI == (Object)null) { throw new InvalidOperationException("ManualCameraRenderer shipArrowUI placeholder missing"); } if ((Object)(object)renderer.shipArrowPointer == (Object)null) { throw new InvalidOperationException("ManualCameraRenderer shipArrowPointer placeholder missing"); } if ((Object)(object)renderer.shipIcon == (Object)null) { throw new InvalidOperationException("ManualCameraRenderer shipIcon placeholder missing"); } if ((Object)(object)renderer.lineFromRadarTargetToExit == (Object)null) { throw new InvalidOperationException("ManualCameraRenderer exit line placeholder missing"); } if (renderer.radarTargets == null || renderer.radarTargets.Count == 0 || (Object)(object)renderer.radarTargets[0].transform == (Object)null) { throw new InvalidOperationException("ManualCameraRenderer radar target placeholder missing"); } } private static GameObject ResolveChildGameObject(Transform root, GameObject sourceObject, string fallbackName) { //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_003d: Expected O, but got Unknown Transform val = FindDeepChild(root, ((Object)(object)sourceObject != (Object)null) ? ((Object)sourceObject).name : null); if ((Object)(object)val != (Object)null) { return ((Component)val).gameObject; } GameObject val2 = new GameObject(fallbackName); val2.transform.SetParent(root, false); return val2; } private static Transform ResolveChildTransform(Transform root, Transform sourceTransform, string fallbackName) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) Transform val = FindDeepChild(root, ((Object)(object)sourceTransform != (Object)null) ? ((Object)sourceTransform).name : null); if ((Object)(object)val != (Object)null) { return val; } GameObject val2 = new GameObject(fallbackName); val2.transform.SetParent(root, false); return val2.transform; } private static T ResolveChildComponent(Transform root, Component sourceComponent, string fallbackName) where T : Component { //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) Transform val = FindDeepChild(root, ((Object)(object)sourceComponent != (Object)null) ? ((Object)sourceComponent).name : null); if ((Object)(object)val != (Object)null) { T component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { return component; } } GameObject val2 = new GameObject(fallbackName); val2.transform.SetParent(root, false); return val2.AddComponent(); } private static Transform FindDeepChild(Transform root, string name) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(name)) { return null; } if (((Object)root).name == name) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindDeepChild(root.GetChild(i), name); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static void DestroyChildIfPresent(Transform root, string name) { Transform val = FindDeepChild(root, name); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } private static void HideClonedChildIfPresent(Transform root, Component sourceComponent, string fallbackName) { HideClonedChildIfPresent(root, ((Object)(object)sourceComponent != (Object)null) ? ((Object)sourceComponent).name : fallbackName); } private static void HideClonedChildIfPresent(Transform root, GameObject sourceObject, string fallbackName) { HideClonedChildIfPresent(root, ((Object)(object)sourceObject != (Object)null) ? ((Object)sourceObject).name : fallbackName); } private static void HideClonedChildIfPresent(Transform root, string name) { Transform val = FindDeepChild(root, name); if ((Object)(object)val == (Object)null) { return; } ((Component)val).gameObject.SetActive(false); Graphic[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (!((Object)(object)componentsInChildren[i] == (Object)null)) { ((Behaviour)componentsInChildren[i]).enabled = false; componentsInChildren[i].raycastTarget = false; } } } private static void TrySetUntagged(GameObject go) { if ((Object)(object)go == (Object)null) { return; } try { go.tag = "Untagged"; } catch { } } private static void DisableClonedAnimators(GameObject root) { if ((Object)(object)root == (Object)null) { return; } Animator[] componentsInChildren = root.GetComponentsInChildren(true); foreach (Animator val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { try { val.cullingMode = (AnimatorCullingMode)2; } catch { } try { ((Behaviour)val).enabled = false; } catch { } } } } private static void SetLayerRecursively(GameObject go, int layer) { if (!((Object)(object)go == (Object)null)) { go.layer = layer; Transform transform = go.transform; for (int i = 0; i < transform.childCount; i++) { SetLayerRecursively(((Component)transform.GetChild(i)).gameObject, layer); } } } private static void TryAssignHudFont(TMP_Text target) { if ((Object)(object)target == (Object)null) { return; } try { HUDManager instance = HUDManager.Instance; TextMeshProUGUI[] array = (((Object)(object)instance != (Object)null) ? instance.controlTipLines : null); if (array != null && array.Length != 0 && (Object)(object)array[0] != (Object)null && (Object)(object)((TMP_Text)array[0]).font != (Object)null) { target.font = ((TMP_Text)array[0]).font; } } catch { } } private static void ShutdownPartial() { if ((Object)(object)_mapCamera != (Object)null) { _mapCamera.targetTexture = null; } if ((Object)(object)_texture != (Object)null) { _texture.Release(); Object.Destroy((Object)(object)_texture); } _texture = null; if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _targetObject = null; _markerRoot = null; _renderer = null; _mapCamera = null; _baseOrthographicSize = 0f; _originalCullingMask = 0; _interiorRadarChecked = false; _interiorHasRadarSprites = true; _loggedInteriorFallback = false; _nextTargetUpdateAt = 0f; ClearMarkerPools(); } private static void ClearMarkerPools() { _cameraMarkers.Clear(); _cameraCones.Clear(); _cameraHalos.Clear(); _cameraLabels.Clear(); _playerBackings.Clear(); _playerMarkers.Clear(); _playerFacings.Clear(); _playerGlyphs.Clear(); _playerLabels.Clear(); _enemyMarkers.Clear(); _objectiveMarkers.Clear(); _itemMarkers.Clear(); _itemScanBuffer.Clear(); _nextItemScanAt = 0f; } private static void DestroyMarkerResources() { DestroyMaterial(ref _cameraMarkerMaterial); DestroyMaterial(ref _activeCameraMarkerMaterial); DestroyMaterial(ref _activeCameraHaloMaterial); DestroyMaterial(ref _cameraConeMaterial); DestroyMaterial(ref _playerBackingMaterial); DestroyMaterial(ref _playerHealthyMaterial); DestroyMaterial(ref _playerHurtMaterial); DestroyMaterial(ref _playerCriticalMaterial); DestroyMaterial(ref _playerFacingMaterial); DestroyMaterial(ref _playerGlyphMaterial); DestroyMaterial(ref _enemyMarkerMaterial); DestroyMaterial(ref _objectiveMarkerMaterial); DestroyMaterial(ref _itemMarkerMaterial); DestroyMesh(ref _circleMesh); DestroyMesh(ref _ringMesh); DestroyMesh(ref _squareMesh); DestroyMesh(ref _diamondMesh); DestroyMesh(ref _triangleMesh); DestroyMesh(ref _coneMesh); DestroyMesh(ref _xMesh); } private static void DestroyMaterial(ref Material material) { if (!((Object)(object)material == (Object)null)) { Object.Destroy((Object)(object)material); material = null; } } private static void DestroyMesh(ref Mesh mesh) { if (!((Object)(object)mesh == (Object)null)) { Object.Destroy((Object)(object)mesh); mesh = null; } } private static void LogReadyOnce() { if (!_loggedReady) { _loggedReady = true; _loggedMissing = false; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Vanilla radar feed initialized; CCTV radar inset is using cloned MapCamera output with schematic fallback available."); } } } private static void LogMissingOnce(string reason) { if (!_loggedMissing) { _loggedMissing = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Vanilla radar feed waiting: " + reason + "; schematic fallback remains active.")); } } } } internal static class VanillaShaderInfo { private static bool _probed; internal static bool ProbeSucceeded { get; private set; } internal static Material SourceMaterial { get; private set; } internal static string ShaderName { get; private set; } internal static string MainTexturePropertyName { get; private set; } internal static void EnsureProbed() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 if (_probed) { return; } _probed = true; Material val = TryResolveVanillaScreenMaterial(); if ((Object)(object)val == (Object)null || (Object)(object)val.shader == (Object)null) { SurveillanceBootstrap.Log.LogError((object)"[LethalCCTV][VanillaProbe] ERROR — could not resolve vanilla mapScreen material. Aborting QuadMonitor construction. Cameras remain spawned; focus mode unavailable. See Phase 1.5 retrospective."); ProbeSucceeded = false; return; } List list = new List(); int propertyCount = val.shader.GetPropertyCount(); for (int i = 0; i < propertyCount; i++) { if ((int)val.shader.GetPropertyType(i) == 4) { list.Add(val.shader.GetPropertyName(i)); } } if (list.Count == 0) { SurveillanceBootstrap.Log.LogError((object)"[LethalCCTV][VanillaProbe] ERROR — vanilla material shader exposes no texture properties. Aborting QuadMonitor construction. Cameras remain spawned; focus mode unavailable. See Phase 1.5 retrospective."); ProbeSucceeded = false; return; } string text; if (list.Contains("_UnlitColorMap")) { text = "_UnlitColorMap"; } else if (list.Contains("_BaseColorMap")) { text = "_BaseColorMap"; } else { text = list[0]; SurveillanceBootstrap.Log.LogWarning((object)("[LethalCCTV][VanillaProbe] Neither _UnlitColorMap nor _BaseColorMap present. Falling back to shader-order index 0 ('" + text + "'). Verify in Round 2 if display is empty.")); } SourceMaterial = val; ShaderName = ((Object)val.shader).name; MainTexturePropertyName = text; ProbeSucceeded = true; } private static Material TryResolveVanillaScreenMaterial() { try { GameObject val = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube.001"); if ((Object)(object)val != (Object)null) { MeshRenderer component = val.GetComponent(); if ((Object)(object)component != (Object)null) { Material val2 = PickScreenMaterial(((Renderer)component).sharedMaterials); if ((Object)(object)val2 != (Object)null) { return val2; } } } } catch (Exception ex) { SurveillanceBootstrap.Log.LogWarning((object)("[LethalCCTV][VanillaProbe] Primary path threw: " + ex.Message)); } try { MeshRenderer[] array = Object.FindObjectsOfType(); foreach (MeshRenderer val3 in array) { if ((Object)(object)val3 != (Object)null && ((Object)((Component)val3).gameObject).name == "Cube.001") { Material val4 = PickScreenMaterial(((Renderer)val3).sharedMaterials); if ((Object)(object)val4 != (Object)null) { return val4; } } } } catch (Exception ex2) { SurveillanceBootstrap.Log.LogWarning((object)("[LethalCCTV][VanillaProbe] Secondary path threw: " + ex2.Message)); } return null; } private static Material PickScreenMaterial(Material[] mats) { if (mats == null) { return null; } if (mats.Length > 1 && (Object)(object)mats[1] != (Object)null && (Object)(object)mats[1].shader != (Object)null) { return mats[1]; } for (int i = 0; i < mats.Length; i++) { if ((Object)(object)mats[i] != (Object)null && (Object)(object)mats[i].shader != (Object)null) { return mats[i]; } } return null; } } internal static class Y4NGZPlayerAnimationBridge { private enum FirstPersonRightHandTuneTarget { None, Blue, Green } internal struct FirstPersonRightHandPoseTuning { internal Vector3 Offset; internal Vector3 Euler; } private struct RequiredAnimatorParameter { internal readonly string Name; internal readonly AnimatorControllerParameterType Type; internal RequiredAnimatorParameter(string name, AnimatorControllerParameterType type) { //IL_0008: 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) Name = name; Type = type; } } [CompilerGenerated] private static class <>O { public static Action <0>__OnChairEntered; public static Action <1>__OnChairExited; public static Action <2>__OnCameraSelected; public static Action <3>__OnCameraControlChanged; public static Action <4>__OnJoystickMoved; public static Action <5>__OnActionButtonPressed; public static Action <6>__OnRadarViewChanged; public static CameraCallback <7>__OnCameraPreCull; public static Action <8>__OnBeginCameraRendering; } private const string PrimaryBundleFile = "y4ngz-cctv-playeranimations.lethalbundle"; private const string SecondaryBundleFile = "y4ngz-cctv-playeranimations.bundle"; private const string PrimaryControllerAsset = "Y4NGZ_CCTV_PlayerMetarig.controller"; private const string SecondaryControllerAsset = "Y4NGZ_CCTV_PlayerMetarig"; internal const string SeatedBool = "Y4NGZ_CCTV_Seated"; internal const string CameraControlBool = "Y4NGZ_CCTV_CameraControl"; internal const string RadarLookBool = "Y4NGZ_CCTV_RadarLook"; internal const string JoystickXFloat = "Y4NGZ_CCTV_JoystickX"; internal const string JoystickYFloat = "Y4NGZ_CCTV_JoystickY"; internal const string ActiveSlotInt = "Y4NGZ_CCTV_ActiveSlot"; internal const string ActionButtonInt = "Y4NGZ_CCTV_ActionButton"; internal const string EnterTrigger = "Y4NGZ_CCTV_Enter"; internal const string ExitTrigger = "Y4NGZ_CCTV_Exit"; internal const string SelectCameraTrigger = "Y4NGZ_CCTV_SelectCamera"; internal const string JoystickGrabTrigger = "Y4NGZ_CCTV_JoystickGrab"; internal const string JoystickReleaseTrigger = "Y4NGZ_CCTV_JoystickRelease"; internal const string ButtonPressTrigger = "Y4NGZ_CCTV_ButtonPress"; private const float FirstPersonRightHandTuneMoveSpeed = 0.35f; private const float FirstPersonRightHandTuneMoveFastSpeed = 1.25f; private const float FirstPersonRightHandTuneRotationSpeed = 42f; private const float FirstPersonRightHandTuneRotationFastSpeed = 120f; private const float FirstPersonRightHandTuneOffsetMax = 2f; private const float FirstPersonRightHandTuneEulerMax = 180f; private const float FirstPersonRightHandTuneStatusInterval = 0.25f; private static readonly RequiredAnimatorParameter[] RequiredParameters = new RequiredAnimatorParameter[13] { new RequiredAnimatorParameter("Y4NGZ_CCTV_Seated", (AnimatorControllerParameterType)4), new RequiredAnimatorParameter("Y4NGZ_CCTV_CameraControl", (AnimatorControllerParameterType)4), new RequiredAnimatorParameter("Y4NGZ_CCTV_RadarLook", (AnimatorControllerParameterType)4), new RequiredAnimatorParameter("Y4NGZ_CCTV_JoystickX", (AnimatorControllerParameterType)1), new RequiredAnimatorParameter("Y4NGZ_CCTV_JoystickY", (AnimatorControllerParameterType)1), new RequiredAnimatorParameter("Y4NGZ_CCTV_ActiveSlot", (AnimatorControllerParameterType)3), new RequiredAnimatorParameter("Y4NGZ_CCTV_ActionButton", (AnimatorControllerParameterType)3), new RequiredAnimatorParameter("Y4NGZ_CCTV_Enter", (AnimatorControllerParameterType)9), new RequiredAnimatorParameter("Y4NGZ_CCTV_Exit", (AnimatorControllerParameterType)9), new RequiredAnimatorParameter("Y4NGZ_CCTV_SelectCamera", (AnimatorControllerParameterType)9), new RequiredAnimatorParameter("Y4NGZ_CCTV_JoystickGrab", (AnimatorControllerParameterType)9), new RequiredAnimatorParameter("Y4NGZ_CCTV_JoystickRelease", (AnimatorControllerParameterType)9), new RequiredAnimatorParameter("Y4NGZ_CCTV_ButtonPress", (AnimatorControllerParameterType)9) }; private static readonly string[] ExpectedAdditiveLayerNames = new string[3] { "CCTVFirstPersonArms", "CCTVLeftHand", "CCTVGlance" }; private static readonly string[] RequiredVanillaLayerNames = new string[5] { "UpperBodyEmotes", "EmotesNoArms", "HoldingItemsRightHand", "HoldingItemsBothHands", "SpecialAnimations" }; private static bool _initialized; private static OperatorAnimSession _localSession; private static AssetBundle _controllerBundle; private static RuntimeAnimatorController _cctvController; private static bool _controllerLoadAttempted; private static bool _missingControllerLogged; private static bool _controllerDiagnosticsLogged; private static bool _controllerContractLogged; private static bool _controllerLayerWarningLogged; private static bool _controllerRejected; private static bool _controllerRejectedLogged; private static string _rejectedControllerName; private static string _controllerRejectReason; private static bool _localAuthoredSuppressedLogged; private static FirstPersonRightHandTuneTarget _firstPersonRightHandTuneTarget; private static bool _firstPersonRightHandEditModeActive; private static bool _firstPersonRightHandTuneEditingLastFrame; private static float _nextFirstPersonRightHandTuneStatusAt; private static bool _firstPersonLeftHandEditModeActive; private static FirstPersonRightHandPoseTuning _blueRightHandPoseTuning; private static FirstPersonRightHandPoseTuning _greenRightHandPoseTuning; private static FirstPersonRightHandPoseTuning _leftHandPoseTuning; private static bool _firstPersonLeftHandTuneEditingLastFrame; private static float _nextFirstPersonLeftHandTuneStatusAt; private static bool _localThirdPersonPreviewEnabled; internal static bool IsFirstPersonRightHandTuningHotkeyActive { get; private set; } internal static bool IsFirstPersonLeftHandTuningHotkeyActive { get; private set; } internal static bool IsFirstPersonHandTuningHotkeyActive { get { if (!IsFirstPersonRightHandTuningHotkeyActive) { return IsFirstPersonLeftHandTuningHotkeyActive; } return true; } } internal static bool IsFirstPersonHandEditModeActive { get { if (!_firstPersonRightHandEditModeActive) { return _firstPersonLeftHandEditModeActive; } return true; } } internal static bool UseLocalAuthoredOperatorAnimations { get { if (SurveillanceBootstrap.Config?.LocalAuthoredOperatorAnimationsEnabled != null) { return SurveillanceBootstrap.Config.LocalAuthoredOperatorAnimationsEnabled.Value; } return false; } } internal static bool UseInteractionsApiOperatorSession => CCTVOperatorInteractionsBridge.ConfigEnabled; internal static bool UseAuthoredLegacyOperatorPresentation { get { if (!UseLocalAuthoredOperatorAnimations) { return UseInteractionsApiOperatorSession; } return true; } } internal static bool UseLiveArmsForLocalOperator => true; internal static bool IsLocalInteractionsApiSessionActive { get { if (_localSession != null && _localSession.UsesInteractionsApi) { if (!_localSession.IsActive) { return _localSession.IsWindingDown; } return true; } return false; } } internal static bool ShouldUseLegacyFirstPersonArmsPresentation { get { if (UseInteractionsApiOperatorSession) { if (_localSession != null) { return !_localSession.UsesInteractionsApi; } return false; } return true; } } internal static bool ShouldShowAuthoredFirstPersonArms { get { if (_localSession == null) { return UseAuthoredLegacyOperatorPresentation; } return !_localSession.UsesDedicatedLocalViewmodel; } } internal static bool UseManualFirstPersonArmIk => true; internal static bool UseFirstPersonShoulderAnchor => true; internal static bool UseApiOperatorRootAtFloorLevel => true; internal static bool UseApiStationShoulderAnchor => true; internal static Vector3 ApiShoulderAnchorStation => new Vector3(0.06f, 1.62f, 0.6f); internal static bool UseApiCameraRelativeIntroAnchor => true; internal static bool ApiKeepCameraAnchorDuringControl => true; internal static bool UseApiExitRetractToRest => true; internal static float ApiExitRetractSeconds => 0.3f; internal static Vector3 ApiCameraAnchorOffset => new Vector3(0f, -0.25f, -0.32f); internal static bool UseApiShoulderCapPlugs => true; internal static float ApiShoulderCapPlugDiameter => 0.16f; internal static float ApiShoulderCapPlugThickness => 0.1f; internal static bool UseApiLeftTargetFromAuthoredTable => true; internal static bool UseApiElbowPoleHints => true; internal static Vector3 ApiLeftElbowPoleStation => new Vector3(0.2f, 0.9f, 0.9f); internal static Vector3 ApiRightElbowPoleStation => new Vector3(0.22f, 0.9f, 0.2f); internal static bool PinRightHandRestToStationDuringApiSession => true; internal static bool ShoulderAnchorIgnoresCameraPitch => true; internal static Vector3 FirstPersonShoulderAnchorCameraOffset => new Vector3(0f, -0.25f, -0.12f); internal static float FirstPersonLeverFollowMotionScale => 1.6f; internal static Vector3 FirstPersonLeverLeftShoulderOffset => new Vector3(0f, -0.25f, -0.1f); internal static bool HideRightFirstPersonArmDuringEnterAndExit => true; internal static bool HideLocalPlayerHeadDuringApiSession => false; internal static Vector3 FirstPersonRightHandRestOffset => new Vector3(0.24f, -0.7f, 0.05f); internal static Vector3 FirstPersonRightHandRestEuler => Vector3.zero; internal static Vector3 FirstPersonLeftHandRestOffset => new Vector3(-0.24f, -0.7f, 0.05f); internal static Vector3 FirstPersonLeftHandRestEuler => Vector3.zero; private static bool ShouldApplyLocalAuthoredController { get { if (!UseAuthoredLegacyOperatorPresentation) { return _localThirdPersonPreviewEnabled; } return true; } } internal static void SetLocalThirdPersonPreviewEnabled(bool enabled) { if (_localThirdPersonPreviewEnabled != enabled) { _localThirdPersonPreviewEnabled = enabled; RefreshLocalSessionForPreview(enabled ? "third-person-preview-enabled" : "third-person-preview-disabled"); } } internal static void StartFirstPersonRightHandBlueEditMode(string reason) { if (EnsureFirstPersonHandEditAvailable("right-hand-blue-edit")) { EnterFirstPersonRightHandEditMode(FirstPersonRightHandTuneTarget.Blue, reason); } } internal static void StartFirstPersonRightHandGreenEditMode(string reason) { if (EnsureFirstPersonHandEditAvailable("right-hand-green-edit")) { EnterFirstPersonRightHandEditMode(FirstPersonRightHandTuneTarget.Green, reason); } } internal static void StartFirstPersonLeftHandEditMode(string reason) { if (EnsureFirstPersonHandEditAvailable("left-hand-edit")) { EnterFirstPersonLeftHandEditMode(reason); } } internal static void ExitFirstPersonHandEditModes(string reason) { ExitFirstPersonRightHandEditMode(reason); ExitFirstPersonLeftHandEditMode(reason); } private static bool EnsureFirstPersonHandEditAvailable(string label) { if (!MonitorFocus.IsFocused || !MonitorFocus.IsStationEditMenuOpen) { return false; } if (MonitorFocus.IsStationThirdPersonDebugViewActive) { MonitorFocus.ShowOperatorTuningStatus("HAND EDIT UNAVAILABLE IN 3P"); return false; } int num; if (string.Equals(label, "left-hand-edit", StringComparison.Ordinal)) { num = (IsLocalInteractionsApiSessionActive ? 1 : 0); if (num != 0) { goto IL_007b; } } else { num = 0; } if (!UseLocalAuthoredOperatorAnimations && SurveillanceBootstrap.Config?.LocalAuthoredOperatorAnimationsEnabled != null) { SurveillanceBootstrap.Config.LocalAuthoredOperatorAnimationsEnabled.Value = true; RefreshLocalAuthoredOperatorAnimationSetting(label + "-enabled-first-person-arms"); MonitorFocus.RefreshLocalOperatorFirstPersonVisibility(); } goto IL_007b; IL_007b: if ((num == 0 && !UseLocalAuthoredOperatorAnimations) || _localSession == null || !_localSession.IsActive) { MonitorFocus.ShowOperatorTuningStatus("HAND EDIT UNAVAILABLE"); return false; } return true; } internal static void RefreshLocalAuthoredOperatorAnimationSetting(string reason) { RefreshLocalSessionForPreview(string.IsNullOrWhiteSpace(reason) ? "local-authored-setting-changed" : reason); } internal static bool IsLocalSessionActive(PlayerControllerB player) { if (_localSession != null && (_localSession.IsActive || _localSession.IsWindingDown)) { return (Object)(object)_localSession.Player == (Object)(object)player; } return false; } internal static void Initialize() { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown //IL_0108: 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_0113: Expected O, but got Unknown if (!_initialized) { _initialized = true; CCTVOperatorInteractionsBridge.Initialize(); CCTVStationEvents.ChairEntered += OnChairEntered; CCTVStationEvents.ChairExited += OnChairExited; CCTVStationEvents.CameraSelected += OnCameraSelected; CCTVStationEvents.CameraControlChanged += OnCameraControlChanged; CCTVStationEvents.JoystickMoved += OnJoystickMoved; CCTVStationEvents.ActionButtonPressed += OnActionButtonPressed; CCTVStationEvents.RadarViewChanged += OnRadarViewChanged; CameraCallback onPreCull = Camera.onPreCull; object obj = <>O.<7>__OnCameraPreCull; if (obj == null) { CameraCallback val = OnCameraPreCull; <>O.<7>__OnCameraPreCull = val; obj = (object)val; } Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)onPreCull, (Delegate?)obj); RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering; CCTVOperatorAnimSync.Initialize(); } } internal static void CaptureInteractionBeginPresentation(PlayerControllerB player) { OperatorAnimSession.CaptureInteractionBeginPresentation(player); } internal static void AbortInteractionBeginPresentation(PlayerControllerB player, string reason) { OperatorAnimSession.AbortInteractionBeginPresentation(player, reason); } internal static void Shutdown() { //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown if (_initialized) { CCTVStationEvents.ChairEntered -= OnChairEntered; CCTVStationEvents.ChairExited -= OnChairExited; CCTVStationEvents.CameraSelected -= OnCameraSelected; CCTVStationEvents.CameraControlChanged -= OnCameraControlChanged; CCTVStationEvents.JoystickMoved -= OnJoystickMoved; CCTVStationEvents.ActionButtonPressed -= OnActionButtonPressed; CCTVStationEvents.RadarViewChanged -= OnRadarViewChanged; CameraCallback onPreCull = Camera.onPreCull; object obj = <>O.<7>__OnCameraPreCull; if (obj == null) { CameraCallback val = OnCameraPreCull; <>O.<7>__OnCameraPreCull = val; obj = (object)val; } Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)onPreCull, (Delegate?)obj); RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering; OperatorAnimSession.TickDeferredVanillaRigRebuild(force: true, "bridge-shutdown"); OperatorAnimSession.AbortInteractionBeginPresentation(null, "shutdown"); _localSession?.EndImmediate("shutdown"); _localSession = null; OperatorAnimSession.ClearPostExitArmsTelemetry(); CCTVOperatorAnimSync.Shutdown(); CCTVOperatorInteractionsBridge.Shutdown(); if ((Object)(object)_controllerBundle != (Object)null) { _controllerBundle.Unload(false); _controllerBundle = null; } _cctvController = null; _controllerLoadAttempted = false; _controllerRejected = false; _controllerRejectedLogged = false; _rejectedControllerName = null; _controllerRejectReason = null; _localThirdPersonPreviewEnabled = false; _initialized = false; } } internal static void Tick() { CCTVOperatorInteractionsBridge.Tick(); TickFirstPersonRightHandTuningHotkeys(); TickFirstPersonLeftHandTuningHotkeys(); if (_localSession != null) { _localSession.Tick(); if (!_localSession.IsActive && !_localSession.IsWindingDown) { _localSession = null; } else { CCTVOperatorAnimSync.TickLocalJoystickSend(_localSession); } } OperatorAnimSession.TickDeferredVanillaRigRebuild(); CCTVOperatorAnimSync.Tick(); } internal static void TickLocalFirstPersonHandsAfterCamera() { _localSession?.TickFirstPersonHandsAfterCamera(); OperatorAnimSession.TickPostExitArmsTelemetry(); } private static void OnCameraPreCull(Camera camera) { _localSession?.TraceFirstPersonHandsPreCull(camera); } private static void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera) { _localSession?.TraceFirstPersonHandsPreCull(camera); } private static void TickFirstPersonRightHandTuningHotkeys() { //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_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) IsFirstPersonRightHandTuningHotkeyActive = false; Keyboard current = Keyboard.current; if (current == null || _localSession == null || !_localSession.IsActive || !MonitorFocus.IsFocused || MonitorFocus.IsStationThirdPersonDebugViewActive) { ExitFirstPersonRightHandEditMode("unavailable"); return; } if (!MonitorFocus.IsStationEditMenuOpen) { ExitFirstPersonRightHandEditMode("station-edit-menu-closed"); return; } if (!UseLocalAuthoredOperatorAnimations) { ExitFirstPersonRightHandEditMode("first-person-arms-disabled"); return; } if (!_firstPersonRightHandEditModeActive) { FinishFirstPersonRightHandTuneEditing(); return; } if (_firstPersonRightHandTuneTarget == FirstPersonRightHandTuneTarget.None) { SetFirstPersonRightHandTuneTarget(FirstPersonRightHandTuneTarget.Blue); } IsFirstPersonRightHandTuningHotkeyActive = true; _firstPersonRightHandTuneEditingLastFrame = true; _localSession.PreviewFirstPersonRightHandTune(GetActionButtonForTuneTarget(_firstPersonRightHandTuneTarget)); if (((ButtonControl)current.digit0Key).wasPressedThisFrame || ((ButtonControl)current.numpad0Key).wasPressedThisFrame) { SetFirstPersonRightHandPoseTuning(_firstPersonRightHandTuneTarget, default(FirstPersonRightHandPoseTuning)); ShowFirstPersonRightHandTuneStatus(force: true); return; } bool num = ((ButtonControl)current.leftCtrlKey).isPressed || ((ButtonControl)current.rightCtrlKey).isPressed; bool flag = ((ButtonControl)current.leftShiftKey).isPressed || ((ButtonControl)current.rightShiftKey).isPressed; float num2 = Mathf.Max(Time.unscaledDeltaTime, 0.001f); Vector3 zero = Vector3.zero; Vector3 zero2 = Vector3.zero; if (num) { if (((ButtonControl)current.wKey).isPressed) { zero2.x += 1f; } if (((ButtonControl)current.sKey).isPressed) { zero2.x -= 1f; } if (((ButtonControl)current.aKey).isPressed) { zero2.y -= 1f; } if (((ButtonControl)current.dKey).isPressed) { zero2.y += 1f; } if (((ButtonControl)current.rKey).isPressed || ((ButtonControl)current.pageUpKey).isPressed) { zero2.z += 1f; } if (((ButtonControl)current.fKey).isPressed || ((ButtonControl)current.pageDownKey).isPressed) { zero2.z -= 1f; } } else { if (((ButtonControl)current.aKey).isPressed) { zero.x -= 1f; } if (((ButtonControl)current.dKey).isPressed) { zero.x += 1f; } if (((ButtonControl)current.fKey).isPressed || ((ButtonControl)current.pageDownKey).isPressed) { zero.y -= 1f; } if (((ButtonControl)current.rKey).isPressed || ((ButtonControl)current.pageUpKey).isPressed) { zero.y += 1f; } if (((ButtonControl)current.sKey).isPressed) { zero.z -= 1f; } if (((ButtonControl)current.wKey).isPressed) { zero.z += 1f; } } if (!(((Vector3)(ref zero)).sqrMagnitude <= 0.0001f) || !(((Vector3)(ref zero2)).sqrMagnitude <= 0.0001f)) { FirstPersonRightHandPoseTuning firstPersonRightHandPoseTuning = GetFirstPersonRightHandPoseTuning(_firstPersonRightHandTuneTarget); if (((Vector3)(ref zero)).sqrMagnitude > 0.0001f) { float num3 = (flag ? 1.25f : 0.35f); firstPersonRightHandPoseTuning.Offset = ClampFirstPersonRightHandTuneOffset(firstPersonRightHandPoseTuning.Offset + ((Vector3)(ref zero)).normalized * num3 * num2); } if (((Vector3)(ref zero2)).sqrMagnitude > 0.0001f) { float num4 = (flag ? 120f : 42f); firstPersonRightHandPoseTuning.Euler = ClampFirstPersonRightHandTuneEuler(firstPersonRightHandPoseTuning.Euler + ((Vector3)(ref zero2)).normalized * num4 * num2); } SetFirstPersonRightHandPoseTuning(_firstPersonRightHandTuneTarget, firstPersonRightHandPoseTuning); ShowFirstPersonRightHandTuneStatus(force: false); } } private static void TickFirstPersonLeftHandTuningHotkeys() { //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) IsFirstPersonLeftHandTuningHotkeyActive = false; Keyboard current = Keyboard.current; if (current == null || _localSession == null || !_localSession.IsActive || !MonitorFocus.IsFocused || MonitorFocus.IsStationThirdPersonDebugViewActive) { ExitFirstPersonLeftHandEditMode("unavailable"); return; } if (!MonitorFocus.IsStationEditMenuOpen) { ExitFirstPersonLeftHandEditMode("station-edit-menu-closed"); return; } if (!UseLocalAuthoredOperatorAnimations && !IsLocalInteractionsApiSessionActive) { ExitFirstPersonLeftHandEditMode("first-person-arms-disabled"); return; } if (!_firstPersonLeftHandEditModeActive) { FinishFirstPersonLeftHandTuneEditing(); return; } IsFirstPersonLeftHandTuningHotkeyActive = true; _firstPersonLeftHandTuneEditingLastFrame = true; if (((ButtonControl)current.digit0Key).wasPressedThisFrame || ((ButtonControl)current.numpad0Key).wasPressedThisFrame) { SetFirstPersonLeftHandPoseTuning(default(FirstPersonRightHandPoseTuning)); ShowFirstPersonLeftHandTuneStatus(force: true); return; } bool num = ((ButtonControl)current.leftCtrlKey).isPressed || ((ButtonControl)current.rightCtrlKey).isPressed; bool flag = ((ButtonControl)current.leftShiftKey).isPressed || ((ButtonControl)current.rightShiftKey).isPressed; float num2 = Mathf.Max(Time.unscaledDeltaTime, 0.001f); Vector3 zero = Vector3.zero; Vector3 zero2 = Vector3.zero; if (num) { if (((ButtonControl)current.wKey).isPressed) { zero2.x += 1f; } if (((ButtonControl)current.sKey).isPressed) { zero2.x -= 1f; } if (((ButtonControl)current.aKey).isPressed) { zero2.y -= 1f; } if (((ButtonControl)current.dKey).isPressed) { zero2.y += 1f; } if (((ButtonControl)current.rKey).isPressed || ((ButtonControl)current.pageUpKey).isPressed) { zero2.z += 1f; } if (((ButtonControl)current.fKey).isPressed || ((ButtonControl)current.pageDownKey).isPressed) { zero2.z -= 1f; } } else { if (((ButtonControl)current.aKey).isPressed) { zero.x -= 1f; } if (((ButtonControl)current.dKey).isPressed) { zero.x += 1f; } if (((ButtonControl)current.fKey).isPressed || ((ButtonControl)current.pageDownKey).isPressed) { zero.y -= 1f; } if (((ButtonControl)current.rKey).isPressed || ((ButtonControl)current.pageUpKey).isPressed) { zero.y += 1f; } if (((ButtonControl)current.sKey).isPressed) { zero.z -= 1f; } if (((ButtonControl)current.wKey).isPressed) { zero.z += 1f; } } if (!(((Vector3)(ref zero)).sqrMagnitude <= 0.0001f) || !(((Vector3)(ref zero2)).sqrMagnitude <= 0.0001f)) { FirstPersonRightHandPoseTuning firstPersonLeftHandPoseTuning = GetFirstPersonLeftHandPoseTuning(); if (((Vector3)(ref zero)).sqrMagnitude > 0.0001f) { float num3 = (flag ? 1.25f : 0.35f); firstPersonLeftHandPoseTuning.Offset = ClampFirstPersonRightHandTuneOffset(firstPersonLeftHandPoseTuning.Offset + ((Vector3)(ref zero)).normalized * num3 * num2); } if (((Vector3)(ref zero2)).sqrMagnitude > 0.0001f) { float num4 = (flag ? 120f : 42f); firstPersonLeftHandPoseTuning.Euler = ClampFirstPersonRightHandTuneEuler(firstPersonLeftHandPoseTuning.Euler + ((Vector3)(ref zero2)).normalized * num4 * num2); } SetFirstPersonLeftHandPoseTuning(firstPersonLeftHandPoseTuning); ShowFirstPersonLeftHandTuneStatus(force: false); } } private static void FinishFirstPersonRightHandTuneEditing() { if (_firstPersonRightHandTuneEditingLastFrame) { _firstPersonRightHandTuneEditingLastFrame = false; ShowFirstPersonRightHandTuneStatus(force: true); } } private static void EnterFirstPersonRightHandEditMode(FirstPersonRightHandTuneTarget target, string reason) { if (target == FirstPersonRightHandTuneTarget.None) { target = FirstPersonRightHandTuneTarget.Blue; } ExitFirstPersonLeftHandEditMode("right-hand-edit-entered"); _firstPersonRightHandEditModeActive = true; _firstPersonRightHandTuneEditingLastFrame = true; SetFirstPersonRightHandTuneTarget(target); try { _localSession?.SetCameraControl(controllingCamera: false); } catch { } ShowFirstPersonRightHandTuneStatus(force: true); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] First-person right-hand edit mode entered: target={target}, reason={reason}."); } } internal static void ExitFirstPersonRightHandEditMode(string reason) { if (_firstPersonRightHandEditModeActive || _firstPersonRightHandTuneEditingLastFrame) { FirstPersonRightHandTuneTarget firstPersonRightHandTuneTarget = _firstPersonRightHandTuneTarget; _firstPersonRightHandEditModeActive = false; _firstPersonRightHandTuneTarget = FirstPersonRightHandTuneTarget.None; FinishFirstPersonRightHandTuneEditing(); MonitorFocus.ShowOperatorTuningStatus("RH EDIT OFF"); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] First-person right-hand edit mode exited: previous={firstPersonRightHandTuneTarget}, reason={reason}."); } } } private static void FinishFirstPersonLeftHandTuneEditing() { if (_firstPersonLeftHandTuneEditingLastFrame) { _firstPersonLeftHandTuneEditingLastFrame = false; ShowFirstPersonLeftHandTuneStatus(force: true); } } private static void EnterFirstPersonLeftHandEditMode(string reason) { ExitFirstPersonRightHandEditMode("left-hand-edit-entered"); _firstPersonLeftHandEditModeActive = true; _firstPersonLeftHandTuneEditingLastFrame = true; try { _localSession?.SetCameraControl(controllingCamera: false); } catch { } ShowFirstPersonLeftHandTuneStatus(force: true); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] First-person left-hand edit mode entered: reason=" + reason + ".")); } } internal static void ExitFirstPersonLeftHandEditMode(string reason) { if (_firstPersonLeftHandEditModeActive || _firstPersonLeftHandTuneEditingLastFrame) { _firstPersonLeftHandEditModeActive = false; FinishFirstPersonLeftHandTuneEditing(); MonitorFocus.ShowOperatorTuningStatus("LH EDIT OFF"); ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] First-person left-hand edit mode exited: reason=" + reason + ".")); } } } private static void SetFirstPersonRightHandTuneTarget(FirstPersonRightHandTuneTarget target) { if (_firstPersonRightHandTuneTarget != target) { _firstPersonRightHandTuneTarget = target; ShowFirstPersonRightHandTuneStatus(force: true); } } private static int GetActionButtonForTuneTarget(FirstPersonRightHandTuneTarget target) { return (target == FirstPersonRightHandTuneTarget.Blue) ? 1 : 0; } internal static bool IsBlueRightHandAction(int actionButton) { if (actionButton != 1) { return actionButton == 4; } return true; } internal static bool IsGreenRightHandAction(int actionButton) { if (actionButton != 0) { return actionButton == 2; } return true; } internal static FirstPersonRightHandPoseTuning GetFirstPersonRightHandPoseTuning(int actionButton) { if (IsBlueRightHandAction(actionButton)) { return GetFirstPersonRightHandPoseTuning(FirstPersonRightHandTuneTarget.Blue); } if (IsGreenRightHandAction(actionButton)) { return GetFirstPersonRightHandPoseTuning(FirstPersonRightHandTuneTarget.Green); } return default(FirstPersonRightHandPoseTuning); } private static FirstPersonRightHandPoseTuning GetFirstPersonRightHandPoseTuning(FirstPersonRightHandTuneTarget target) { return target switch { FirstPersonRightHandTuneTarget.Blue => _blueRightHandPoseTuning, FirstPersonRightHandTuneTarget.Green => _greenRightHandPoseTuning, _ => default(FirstPersonRightHandPoseTuning), }; } internal static FirstPersonRightHandPoseTuning GetFirstPersonLeftHandPoseTuning() { return _leftHandPoseTuning; } private static void SetFirstPersonRightHandPoseTuning(FirstPersonRightHandTuneTarget target, FirstPersonRightHandPoseTuning tuning) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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) tuning.Offset = ClampFirstPersonRightHandTuneOffset(tuning.Offset); tuning.Euler = ClampFirstPersonRightHandTuneEuler(tuning.Euler); switch (target) { case FirstPersonRightHandTuneTarget.Blue: _blueRightHandPoseTuning = tuning; break; case FirstPersonRightHandTuneTarget.Green: _greenRightHandPoseTuning = tuning; break; } } private static void SetFirstPersonLeftHandPoseTuning(FirstPersonRightHandPoseTuning tuning) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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) tuning.Offset = ClampFirstPersonRightHandTuneOffset(tuning.Offset); tuning.Euler = ClampFirstPersonRightHandTuneEuler(tuning.Euler); _leftHandPoseTuning = tuning; } private static Vector3 ClampFirstPersonRightHandTuneOffset(Vector3 value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) return new Vector3(Mathf.Clamp(value.x, -2f, 2f), Mathf.Clamp(value.y, -2f, 2f), Mathf.Clamp(value.z, -2f, 2f)); } private static Vector3 ClampFirstPersonRightHandTuneEuler(Vector3 value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) return new Vector3(Mathf.Clamp(value.x, -180f, 180f), Mathf.Clamp(value.y, -180f, 180f), Mathf.Clamp(value.z, -180f, 180f)); } private static void ShowFirstPersonRightHandTuneStatus(bool force) { //IL_0067: 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) if (force || !(Time.unscaledTime < _nextFirstPersonRightHandTuneStatusAt)) { _nextFirstPersonRightHandTuneStatusAt = Time.unscaledTime + 0.25f; if (_firstPersonRightHandTuneTarget == FirstPersonRightHandTuneTarget.None) { MonitorFocus.ShowOperatorTuningStatus("RH TUNE OFF"); return; } FirstPersonRightHandPoseTuning firstPersonRightHandPoseTuning = GetFirstPersonRightHandPoseTuning(_firstPersonRightHandTuneTarget); string text = ((_firstPersonRightHandTuneTarget == FirstPersonRightHandTuneTarget.Blue) ? "RH BLUE" : "RH GREEN"); MonitorFocus.ShowOperatorTuningStatus(text + " P " + FormatTuningVector(firstPersonRightHandPoseTuning.Offset) + " R " + FormatTuningVector(firstPersonRightHandPoseTuning.Euler)); } } private static void ShowFirstPersonLeftHandTuneStatus(bool force) { //IL_003e: 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) if (force || !(Time.unscaledTime < _nextFirstPersonLeftHandTuneStatusAt)) { _nextFirstPersonLeftHandTuneStatusAt = Time.unscaledTime + 0.25f; if (!_firstPersonLeftHandEditModeActive) { MonitorFocus.ShowOperatorTuningStatus("LH TUNE OFF"); return; } FirstPersonRightHandPoseTuning firstPersonLeftHandPoseTuning = GetFirstPersonLeftHandPoseTuning(); MonitorFocus.ShowOperatorTuningStatus("LH LEVER P " + FormatTuningVector(firstPersonLeftHandPoseTuning.Offset) + " R " + FormatTuningVector(firstPersonLeftHandPoseTuning.Euler)); } } private static string FormatTuningVector(Vector3 value) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"{value.x:+0.00;-0.00;0.00},{value.y:+0.00;-0.00;0.00},{value.z:+0.00;-0.00;0.00}"; } internal static string GetFirstPersonHandEditOverlayText() { string firstPersonRightHandEditOverlayText = GetFirstPersonRightHandEditOverlayText(); if (!string.IsNullOrWhiteSpace(firstPersonRightHandEditOverlayText)) { return firstPersonRightHandEditOverlayText; } return GetFirstPersonLeftHandEditOverlayText(); } internal static string GetFirstPersonRightHandEditOverlayText() { //IL_0046: 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) if (!_firstPersonRightHandEditModeActive) { return null; } string text = ((_firstPersonRightHandTuneTarget == FirstPersonRightHandTuneTarget.Green) ? "GREEN ACTION" : "BLUE CAMERA"); FirstPersonRightHandPoseTuning firstPersonRightHandPoseTuning = GetFirstPersonRightHandPoseTuning(_firstPersonRightHandTuneTarget); return "RIGHT HAND EDIT\nTARGET " + text + "\nPOS " + FormatTuningVector(firstPersonRightHandPoseTuning.Offset) + "\nROT " + FormatTuningVector(firstPersonRightHandPoseTuning.Euler) + "\n1/2 SELECT TARGET\nWASD X/Z MOVE\nR/F UP/DOWN\nCTRL ROTATE MODE\nSHIFT FAST\n0 RESET TARGET\nF1/ESC EXIT EDIT"; } internal static string GetFirstPersonLeftHandEditOverlayText() { //IL_0020: 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) if (!_firstPersonLeftHandEditModeActive) { return null; } FirstPersonRightHandPoseTuning firstPersonLeftHandPoseTuning = GetFirstPersonLeftHandPoseTuning(); return "LEFT HAND EDIT\nTARGET BRAKE LEVER\nPOS " + FormatTuningVector(firstPersonLeftHandPoseTuning.Offset) + "\nROT " + FormatTuningVector(firstPersonLeftHandPoseTuning.Euler) + "\nWASD X/Z MOVE\nR/F UP/DOWN\nCTRL ROTATE MODE\nSHIFT FAST\n0 RESET TARGET\nF1/ESC EXIT EDIT"; } private static void OnChairEntered(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return; } OperatorAnimSession.TickDeferredVanillaRigRebuild(force: true, "new-chair-session"); bool shouldApplyLocalAuthoredController = ShouldApplyLocalAuthoredController; long timestamp = Stopwatch.GetTimestamp(); RuntimeAnimatorController controller = (shouldApplyLocalAuthoredController ? ResolveControllerShared() : null); long timestamp2 = Stopwatch.GetTimestamp(); _localSession?.EndImmediate("replaced"); _localSession = new OperatorAnimSession(player, isLocal: true); bool enterFlourish = UseInteractionsApiOperatorSession || shouldApplyLocalAuthoredController; bool flag = _localSession.Begin(controller, enterFlourish); long timestamp3 = Stopwatch.GetTimestamp(); double num = 1000.0 / (double)Stopwatch.Frequency; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)($"[LethalCCTV][EnterPerf] chair-entered: controller-load={(double)(timestamp2 - timestamp) * num:F1}ms " + $"session-begin={(double)(timestamp3 - timestamp2) * num:F1}ms began={flag}.")); } if (!flag) { OperatorAnimSession.AbortInteractionBeginPresentation(player, "session-begin-failed"); _localSession = null; return; } MonitorFocus.RefreshLocalOperatorFirstPersonVisibility(); if (!_localSession.UsesInteractionsApi) { if (shouldApplyLocalAuthoredController) { LogMissingControllerOnce(); } else { LogRuntimeControllerDiagnosticsOnce(ResolveControllerShared()); LogLocalAuthoredSuppressedOnce(); } } CCTVOperatorAnimSync.SendEnter(player, MonitorFocus.ActiveSlot); } private static void RefreshLocalSessionForPreview(string reason) { //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) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if (_localSession == null || !_localSession.IsActive || _localSession.IsWindingDown) { return; } if (_localSession.UsesInteractionsApi) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV][ApiPort] legacy_preview_change_ignored reason='" + reason + "' while the Interactions API session owns the animator.")); } return; } PlayerControllerB player = _localSession.Player; if ((Object)(object)player == (Object)null) { return; } bool cameraControlActive = _localSession.CameraControlActive; Vector2 joystickSmoothed = _localSession.JoystickSmoothed; RuntimeAnimatorController val = (ShouldApplyLocalAuthoredController ? ResolveControllerShared() : null); _localSession.EndImmediate(reason + "-restart"); OperatorAnimSession operatorAnimSession = new OperatorAnimSession(player, isLocal: true); if (!operatorAnimSession.Begin(val)) { _localSession = null; return; } operatorAnimSession.SetActiveSlotQuiet(MonitorFocus.ActiveSlot); operatorAnimSession.SetCameraControl(cameraControlActive); if (cameraControlActive) { operatorAnimSession.SetJoystickTargetAbsolute(joystickSmoothed, immediate: true); } _localSession = operatorAnimSession; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] Local operator anim session refreshed for " + reason + "; " + $"thirdPersonPreview={_localThirdPersonPreviewEnabled}, " + $"localAuthoredConfig={UseLocalAuthoredOperatorAnimations}, " + "controllerRequested=" + (((Object)(object)val != (Object)null) ? ((Object)val).name : "") + ".")); } } private static void OnChairExited(PlayerControllerB player) { if (_localSession != null && (!((Object)(object)player != (Object)null) || !((Object)(object)_localSession.Player != (Object)null) || !((Object)(object)_localSession.Player != (Object)(object)player)) && !_localSession.IsWindingDown) { PlayerControllerB player2 = _localSession.Player; _localSession.BeginGracefulEnd("chair-exited"); CCTVOperatorAnimSync.SendExit(player2); } } private static void OnCameraSelected(int slot) { if (_localSession != null && _localSession.IsActive && !_firstPersonRightHandEditModeActive) { if (ShouldSuppressCameraUnsafeRightHandAction("camera-select")) { _localSession.SetActiveSlotQuiet(slot); return; } _localSession.SelectCamera(slot); CCTVOperatorAnimSync.SendSelectCamera(_localSession.Player, slot); } } private static void OnCameraControlChanged(bool controllingCamera) { if (_localSession != null && _localSession.IsActive && !_firstPersonRightHandEditModeActive) { _localSession.SetCameraControl(controllingCamera); CCTVOperatorAnimSync.SendCameraControl(_localSession.Player, controllingCamera); } } private static void OnJoystickMoved(Vector2 appliedDeltaDeg) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (_localSession != null && _localSession.IsActive && !_firstPersonRightHandEditModeActive) { _localSession.OnJoystickMoved(appliedDeltaDeg); } } private static void OnActionButtonPressed(string actionId) { if (_localSession != null && _localSession.IsActive && !_firstPersonRightHandEditModeActive && !ShouldSuppressCameraUnsafeRightHandAction(actionId)) { int num = ResolveActionButtonId(actionId); PlayerControllerB player = _localSession.Player; _localSession.PressButton(num, num == 3); if (num == 3) { CCTVOperatorAnimSync.SendExit(player); } else { CCTVOperatorAnimSync.SendButtonPress(player, num); } } } private static void OnRadarViewChanged(bool lookingAtRadar) { if (_localSession != null && _localSession.IsActive && !_firstPersonRightHandEditModeActive) { _localSession.SetRadarLook(lookingAtRadar); CCTVOperatorAnimSync.SendRadarLook(_localSession.Player, lookingAtRadar); } } private static bool ShouldSuppressCameraUnsafeRightHandAction(string actionId) { return false; } internal static int ResolveActionButtonId(string actionId) { if (string.Equals(actionId, "camera-select", StringComparison.OrdinalIgnoreCase)) { return 1; } if (string.Equals(actionId, "monitor-mode-toggle", StringComparison.OrdinalIgnoreCase)) { return 2; } if (string.Equals(actionId, "stand-up", StringComparison.OrdinalIgnoreCase)) { return 3; } if (string.Equals(actionId, "camera-page", StringComparison.OrdinalIgnoreCase)) { return 4; } return 0; } internal static void WarmUpAuthoredController() { ResolveControllerShared(); } internal static RuntimeAnimatorController ResolveControllerShared() { if ((Object)(object)_cctvController != (Object)null) { return _cctvController; } if (_controllerLoadAttempted) { LogMissingControllerOnce(); return null; } _controllerLoadAttempted = true; string pluginDirectory = GetPluginDirectory(); if (string.IsNullOrEmpty(pluginDirectory)) { LogMissingControllerOnce(); return null; } if (TryAcceptLoadedController(FindControllerInLoadedBundles(), "loaded-bundle-scan")) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] CCTV player animator controller resolved from an already-loaded bundle (LethalLevelLoader auto-load)."); } return _cctvController; } string[] array = new string[2] { "y4ngz-cctv-playeranimations.lethalbundle", "y4ngz-cctv-playeranimations.bundle" }; for (int i = 0; i < array.Length; i++) { string text = Path.Combine(pluginDirectory, array[i]); if (!File.Exists(text)) { continue; } try { _controllerBundle = AssetBundle.LoadFromFile(text); if ((Object)(object)_controllerBundle != (Object)null) { RuntimeAnimatorController val = LoadControllerFromBundle(_controllerBundle); if (TryAcceptLoadedController(val, Path.GetFileName(text))) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] Loaded CCTV player animator controller '" + ((Object)_cctvController).name + "' from " + Path.GetFileName(text) + ".")); } return _cctvController; } if ((Object)(object)val == (Object)null) { ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV] CCTV player animation bundle contains no expected controller: " + text)); } } continue; } } catch (Exception ex) { ManualLogSource log4 = SurveillanceBootstrap.Log; if (log4 != null) { log4.LogWarning((object)("[LethalCCTV] CCTV player animation bundle load failed '" + text + "': " + ex.Message)); } } if (TryAcceptLoadedController(FindControllerInLoadedBundles(), "loaded-bundle-scan")) { ManualLogSource log5 = SurveillanceBootstrap.Log; if (log5 != null) { log5.LogInfo((object)"[LethalCCTV] CCTV player animator controller recovered from an already-loaded bundle (LethalLevelLoader auto-load)."); } return _cctvController; } } LogMissingControllerOnce(); return null; } private static bool TryAcceptLoadedController(RuntimeAnimatorController controller, string sourceLabel) { if ((Object)(object)controller == (Object)null) { return false; } if (!PreflightControllerContract(controller, sourceLabel)) { if ((Object)(object)_controllerBundle != (Object)null) { try { _controllerBundle.Unload(false); } catch { } _controllerBundle = null; } return false; } _cctvController = controller; _controllerRejected = false; _rejectedControllerName = null; _controllerRejectReason = null; return true; } private static bool PreflightControllerContract(RuntimeAnimatorController controller, string sourceLabel) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown GameObject val = null; try { val = new GameObject("LethalCCTV_CCTVAnimatorPreflight") { hideFlags = (HideFlags)61 }; Animator obj = val.AddComponent(); obj.runtimeAnimatorController = controller; LogAnimatorControllerDiagnosticsOnce(obj, controller); bool num = ValidateAnimatorControllerContract(obj, controller, "bundle-preflight:" + sourceLabel); if (!num) { RejectLoadedController(controller, "controller contract invalid during bundle preflight; preserve vanilla player animator layers [" + string.Join(", ", RequiredVanillaLayerNames) + "] by cloning/overriding the vanilla metarig controller instead of shipping a standalone CCTV-only controller"); } return num; } catch (Exception ex) { RejectLoadedController(controller, "controller preflight exception: " + ex.Message); return false; } finally { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } } private static void RejectLoadedController(RuntimeAnimatorController controller, string reason) { _controllerRejected = true; _rejectedControllerName = (((Object)(object)controller != (Object)null) ? ((Object)controller).name : ""); _controllerRejectReason = reason; if (!_controllerRejectedLogged) { _controllerRejectedLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Authored CCTV animator controller rejected before live player apply: controller='" + _rejectedControllerName + "', reason='" + _controllerRejectReason + "'. Runtime pose fallback will remain active; no live player controller swap was attempted.")); } } } private static RuntimeAnimatorController FindControllerInLoadedBundles() { try { foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { if (!((Object)(object)allLoadedAssetBundle == (Object)null) && BundleLikelyContainsController(allLoadedAssetBundle)) { RuntimeAnimatorController val = LoadControllerFromBundle(allLoadedAssetBundle); if ((Object)(object)val != (Object)null) { return val; } } } foreach (AssetBundle allLoadedAssetBundle2 in AssetBundle.GetAllLoadedAssetBundles()) { if (!((Object)(object)allLoadedAssetBundle2 == (Object)null) && !BundleLikelyContainsController(allLoadedAssetBundle2)) { RuntimeAnimatorController val2 = LoadControllerFromBundle(allLoadedAssetBundle2); if ((Object)(object)val2 != (Object)null) { return val2; } } } } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] Loaded-bundle scan for CCTV controller failed: " + ex.Message)); } } return null; } private static bool BundleLikelyContainsController(AssetBundle bundle) { try { string name = ((Object)bundle).name; if (!string.IsNullOrEmpty(name) && name.IndexOf("y4ngz-cctv-playeranimations", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } return bundle.Contains("Y4NGZ_CCTV_PlayerMetarig.controller") || bundle.Contains("Y4NGZ_CCTV_PlayerMetarig"); } catch { return false; } } private static RuntimeAnimatorController LoadControllerFromBundle(AssetBundle bundle) { if ((Object)(object)bundle == (Object)null) { return null; } try { RuntimeAnimatorController val = bundle.LoadAsset("Y4NGZ_CCTV_PlayerMetarig.controller"); if ((Object)(object)val != (Object)null) { return val; } val = bundle.LoadAsset("Y4NGZ_CCTV_PlayerMetarig"); if ((Object)(object)val != (Object)null) { return val; } RuntimeAnimatorController[] array = bundle.LoadAllAssets(); foreach (RuntimeAnimatorController val2 in array) { if (!((Object)(object)val2 == (Object)null) && (string.Equals(((Object)val2).name, "Y4NGZ_CCTV_PlayerMetarig.controller", StringComparison.OrdinalIgnoreCase) || string.Equals(((Object)val2).name, "Y4NGZ_CCTV_PlayerMetarig", StringComparison.OrdinalIgnoreCase))) { return val2; } } } catch { return null; } return null; } private static string GetPluginDirectory() { try { string location = Assembly.GetExecutingAssembly().Location; return string.IsNullOrEmpty(location) ? null : Path.GetDirectoryName(location); } catch { return null; } } private static void LogMissingControllerOnce() { if ((Object)(object)_cctvController != (Object)null || _missingControllerLogged) { return; } _missingControllerLogged = true; if (_controllerRejected) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] CCTV player animation controller unavailable because the bundled controller was rejected: controller='" + (_rejectedControllerName ?? "") + "', reason='" + (_controllerRejectReason ?? "unknown") + "'. Remote and local third-person preview animation will use the station body-pose fallback.")); } } else { string text = GetPluginDirectory() ?? ""; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] CCTV player animation controller not loaded. Checked 'y4ngz-cctv-playeranimations.lethalbundle' and 'y4ngz-cctv-playeranimations.bundle' beside the plugin in '" + text + "'. Remote third-person operator animation will use the station body-pose fallback only.")); } } } private static void LogLocalAuthoredSuppressedOnce() { if (!_localAuthoredSuppressedLogged) { _localAuthoredSuppressedLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)"[LethalCCTV] Local authored CCTV operator animations are disabled by default; first-person arms are hidden in station focus. Remote operator animation sync remains enabled."); } } } internal static void LogAnimatorControllerDiagnosticsOnce(Animator animator, RuntimeAnimatorController controller) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (_controllerDiagnosticsLogged || (Object)(object)animator == (Object)null || (Object)(object)controller == (Object)null) { return; } _controllerDiagnosticsLogged = true; try { List list = new List(); int num = Mathf.Max(0, animator.layerCount); for (int i = 0; i < num; i++) { list.Add(i + ":" + animator.GetLayerName(i)); } List list2 = new List(); AnimatorControllerParameter[] parameters = animator.parameters; foreach (AnimatorControllerParameter val in parameters) { list2.Add(val.name + ":" + ((object)val.type/*cast due to .constrained prefix*/).ToString()); } ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)("[LethalCCTV] CCTV animator controller diagnostics: " + $"controller='{((Object)controller).name}', layerCount={num}, " + "layers=[" + string.Join(", ", list.ToArray()) + "], parameters=[" + string.Join(", ", list2.ToArray()) + "].")); } } catch (Exception ex) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] CCTV animator controller diagnostics failed: " + ex.Message)); } } } internal unsafe static bool ValidateAnimatorControllerContract(Animator animator, RuntimeAnimatorController controller, string context) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)animator == (Object)null || (Object)(object)controller == (Object)null) { return false; } bool flag = true; List list = new List(); Dictionary dictionary = new Dictionary(); try { AnimatorControllerParameter[] parameters = animator.parameters; foreach (AnimatorControllerParameter val in parameters) { dictionary[val.name] = val.type; } for (int j = 0; j < RequiredParameters.Length; j++) { RequiredAnimatorParameter requiredAnimatorParameter = RequiredParameters[j]; if (!dictionary.TryGetValue(requiredAnimatorParameter.Name, out var value)) { list.Add(requiredAnimatorParameter.Name + ":missing"); flag = false; } else if (value != requiredAnimatorParameter.Type) { list.Add(requiredAnimatorParameter.Name + ":expected " + ((object)requiredAnimatorParameter.Type/*cast due to .constrained prefix*/).ToString() + " got " + ((object)(*(AnimatorControllerParameterType*)(&value))/*cast due to .constrained prefix*/).ToString()); flag = false; } } if (animator.layerCount <= 0) { list.Add("layerCount:expected >=1 got " + animator.layerCount); flag = false; } for (int k = 0; k < RequiredVanillaLayerNames.Length; k++) { string text = RequiredVanillaLayerNames[k]; bool flag2 = false; for (int l = 0; l < animator.layerCount; l++) { if (string.Equals(animator.GetLayerName(l), text, StringComparison.Ordinal)) { flag2 = true; break; } } if (!flag2) { list.Add("layer:" + text + ":missing"); flag = false; } } if (!_controllerLayerWarningLogged) { List list2 = new List(); for (int m = 0; m < ExpectedAdditiveLayerNames.Length; m++) { string text2 = ExpectedAdditiveLayerNames[m]; bool flag3 = false; for (int n = 0; n < animator.layerCount; n++) { if (string.Equals(animator.GetLayerName(n), text2, StringComparison.Ordinal)) { flag3 = true; break; } } if (!flag3) { list2.Add(text2); } } if (list2.Count > 0) { _controllerLayerWarningLogged = true; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] CCTV animator controller is missing optional action layers [" + string.Join(", ", list2.ToArray()) + "] in " + context + "; base pose may still work, but button/radar overlays will not.")); } } } if (!_controllerContractLogged || !flag) { _controllerContractLogged = true; string text3 = (flag ? "OK" : "INVALID"); string text4 = ((list.Count == 0) ? "all required parameters present" : string.Join(", ", list.ToArray())); ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] CCTV animator controller contract " + text3 + ": controller='" + ((Object)controller).name + "', context='" + context + "', " + text4 + ".")); } } } catch (Exception ex) { flag = false; ManualLogSource log3 = SurveillanceBootstrap.Log; if (log3 != null) { log3.LogWarning((object)("[LethalCCTV] CCTV animator controller contract validation failed in " + context + ": " + ex.Message)); } } return flag; } private static void LogRuntimeControllerDiagnosticsOnce(RuntimeAnimatorController controller) { //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_0026: Expected O, but got Unknown if (_controllerDiagnosticsLogged || (Object)(object)controller == (Object)null) { return; } GameObject val = null; try { val = new GameObject("LethalCCTV_CCTVAnimatorDiagnostics") { hideFlags = (HideFlags)61 }; Animator obj = val.AddComponent(); obj.runtimeAnimatorController = controller; LogAnimatorControllerDiagnosticsOnce(obj, controller); } catch (Exception ex) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] CCTV animator controller diagnostics probe failed: " + ex.Message)); } } finally { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } } internal static Vector3? ResolveAccessButtonPressPoint() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!TryResolveAccessButtonPressSurface(out var point, out var _)) { return null; } return point; } internal static Vector3? ResolveLeverGripPoint() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!CCTVOperatorStation.TryResolveLeverGripPoint(out var point, out var _)) { return null; } return point; } internal static bool TryResolveAccessButtonPressSurface(out Vector3 point, out Vector3 normal) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_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) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (CCTVAccessButton.TryGetPressSurface(out point, out normal)) { return true; } Transform redButtonTransform = CCTVVanillaMonitorButtons.RedButtonTransform; if ((Object)(object)redButtonTransform == (Object)null) { point = Vector3.zero; normal = Vector3.up; return false; } Renderer componentInChildren = ((Component)redButtonTransform).GetComponentInChildren(); Bounds val = (Bounds)(((Object)(object)componentInChildren != (Object)null) ? componentInChildren.bounds : new Bounds(redButtonTransform.position, Vector3.zero)); point = ((Bounds)(ref val)).center; normal = Vector3.up; Camera val2 = (((Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null) ? GameNetworkManager.Instance.localPlayerController.gameplayCamera : null); if ((Object)(object)val2 != (Object)null) { Vector3 val3 = ((Component)val2).transform.position - point; if (((Vector3)(ref val3)).sqrMagnitude > 0.0001f) { normal = ((Vector3)(ref val3)).normalized; } } Vector3 extents = ((Bounds)(ref val)).extents; float num = Mathf.Abs(normal.x) * extents.x + Mathf.Abs(normal.y) * extents.y + Mathf.Abs(normal.z) * extents.z; point += normal * Mathf.Max(num, 0.015f); return true; } } } namespace Y4NGZCompany.ShipSystems.Surveillance.OutlineEffect { internal enum CctvOutlineChannel { Hostile, Item, Player } internal enum CctvOutlineSource { Cctv } internal static class CctvOutlineEffectBridge { private sealed class CctvOutlineTarget : MonoBehaviour { private const int MapRadarLayer = 14; private const int MapOnlyLayer = 22; private static int _cullingMaskFrame = -1; private static int _cullingMask; private readonly List _records = new List(); private readonly Dictionary _requests = new Dictionary(); private readonly HashSet _lodManagedRenderers = new HashSet(); private readonly HashSet _activeLodRenderers = new HashSet(); private int _channel; private Camera _camera; private PlayerControllerB _targetPlayer; private EnemyAI _targetEnemy; private GrabbableObject _targetItem; internal bool Show(Camera camera, CctvOutlineSource source, int channel, float duration) { _camera = camera; _requests[source] = new OutlineRequest { Channel = channel, ExpiresAt = Time.time + duration }; EnsureRenderers(camera); ResolveActiveChannel(); return ApplyChannel() > 0; } internal void Clear(CctvOutlineSource source) { _requests.Remove(source); if (_requests.Count <= 0) { Object.Destroy((Object)(object)this); return; } ResolveActiveChannel(); ApplyChannel(); } private void Update() { List list = null; foreach (KeyValuePair request in _requests) { if (!(Time.time < request.Value.ExpiresAt)) { if (list == null) { list = new List(); } list.Add(request.Key); } } if (list != null) { for (int i = 0; i < list.Count; i++) { _requests.Remove(list[i]); } } if (_requests.Count <= 0) { Object.Destroy((Object)(object)this); return; } Camera camera = ActiveCamera ?? _camera; EnsureRenderers(camera); if (list != null) { ResolveActiveChannel(); } ApplyChannel(); } private void EnsureRenderers(Camera camera) { _targetPlayer = ((Component)this).GetComponent(); _targetEnemy = ((Component)this).GetComponent(); _targetItem = ((Component)this).GetComponent(); RefreshActiveLodRendererSets(camera); Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(false); for (int i = 0; i < componentsInChildren.Length; i++) { TryTrackRenderer(componentsInChildren[i]); } } private void RefreshActiveLodRendererSets(Camera camera) { _lodManagedRenderers.Clear(); _activeLodRenderers.Clear(); LODGroup[] componentsInChildren = ((Component)this).GetComponentsInChildren(false); foreach (LODGroup val in componentsInChildren) { if ((Object)(object)val == (Object)null || !val.enabled) { continue; } LOD[] lODs = val.GetLODs(); int num = -1; for (int j = 0; j < lODs.Length; j++) { Renderer[] renderers = lODs[j].renderers; if (renderers == null) { continue; } bool flag = false; foreach (Renderer val2 in renderers) { if (!((Object)(object)val2 == (Object)null)) { _lodManagedRenderers.Add(val2); flag = true; } } if (num < 0 && flag) { num = j; } } int num2 = ResolveActiveLodIndex(val, lODs, camera, num); if (num2 < 0 || num2 >= lODs.Length) { continue; } Renderer[] renderers2 = lODs[num2].renderers; if (renderers2 == null) { continue; } foreach (Renderer val3 in renderers2) { if ((Object)(object)val3 != (Object)null) { _activeLodRenderers.Add(val3); } } } } private static int ResolveActiveLodIndex(LODGroup group, LOD[] lods, Camera camera, int fallbackLod) { if ((Object)(object)group == (Object)null || lods == null || lods.Length == 0) { return -1; } if ((Object)(object)camera == (Object)null) { return fallbackLod; } float num = CalculateRelativeScreenHeight(group, camera); int result = lods.Length - 1; for (int i = 0; i < lods.Length; i++) { if (num >= lods[i].screenRelativeTransitionHeight) { result = i; break; } } return result; } private static float CalculateRelativeScreenHeight(LODGroup group, Camera camera) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)group == (Object)null || (Object)(object)camera == (Object)null) { return 1f; } Transform transform = ((Component)group).transform; Vector3 val = transform.TransformPoint(group.localReferencePoint); float num = Vector3.Distance(((Component)camera).transform.position, val); if (num <= 0.01f) { return 1f; } float num2 = Mathf.Max(0.01f, group.size * MaxAbsScale(transform.lossyScale)); if (camera.orthographic) { return num2 / Mathf.Max(0.01f, camera.orthographicSize * 2f); } return num2 / (2f * num * Mathf.Tan(camera.fieldOfView * 0.5f * (MathF.PI / 180f))) * Mathf.Max(0.01f, QualitySettings.lodBias); } private static float MaxAbsScale(Vector3 scale) { //IL_0000: 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_0016: Unknown result type (might be due to invalid IL or missing references) return Mathf.Max(Mathf.Abs(scale.x), Mathf.Max(Mathf.Abs(scale.y), Mathf.Abs(scale.z))); } private static bool IsGameplayVisibleLayer(int layer) { if (layer < 0 || layer > 31) { return false; } int num = ResolveGameplayCullingMask(); if (num != 0) { return (num & (1 << layer)) != 0; } if (layer != 14) { return layer != 22; } return false; } private static int ResolveGameplayCullingMask() { if (_cullingMaskFrame == Time.frameCount) { return _cullingMask; } _cullingMaskFrame = Time.frameCount; _cullingMask = 0; PlayerControllerB val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null && (Object)(object)GameNetworkManager.Instance != (Object)null) { val = GameNetworkManager.Instance.localPlayerController; } Camera val2 = (((Object)(object)val != (Object)null) ? val.gameplayCamera : null); if ((Object)(object)val2 != (Object)null) { _cullingMask = val2.cullingMask; } return _cullingMask; } private void TryTrackRenderer(Renderer renderer) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 if ((Object)(object)renderer == (Object)null || !renderer.enabled || renderer is ParticleSystemRenderer || renderer is LineRenderer || renderer is TrailRenderer || (int)renderer.shadowCastingMode == 3 || !IsGameplayVisibleLayer(((Component)renderer).gameObject.layer) || !RendererBelongsToTarget(renderer)) { return; } for (int i = 0; i < _records.Count; i++) { if ((Object)(object)_records[i].Renderer == (Object)(object)renderer) { return; } } Outline outline = ((Component)renderer).GetComponent(); bool created = (Object)(object)outline == (Object)null; bool previousEnabled = false; int previousColor = 0; bool previousEraseRenderer = false; if ((Object)(object)outline == (Object)null) { outline = ((Component)renderer).gameObject.AddComponent(); } else { previousEnabled = ((Behaviour)outline).enabled; previousColor = outline.color; previousEraseRenderer = outline.eraseRenderer; } _records.Add(new OutlineRecord { Renderer = renderer, Outline = outline, Created = created, PreviousEnabled = previousEnabled, PreviousColor = previousColor, PreviousEraseRenderer = previousEraseRenderer }); } private bool RendererBelongsToTarget(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return false; } if ((Object)(object)_targetPlayer != (Object)null) { if ((Object)(object)((Component)renderer).GetComponentInParent() != (Object)(object)_targetPlayer) { return false; } if ((Object)(object)((Component)renderer).GetComponentInParent() != (Object)null) { return false; } if (!IsActiveLodRenderer(renderer) || IsHelperRenderer(renderer)) { return false; } return (Object)(object)((Component)renderer).GetComponentInParent() == (Object)null; } if ((Object)(object)_targetEnemy != (Object)null) { if ((Object)(object)((Component)renderer).GetComponentInParent() != (Object)(object)_targetEnemy) { return false; } if ((Object)(object)((Component)renderer).GetComponentInParent() != (Object)null) { return false; } if (!IsActiveLodRenderer(renderer) || IsHelperRenderer(renderer)) { return false; } return (Object)(object)((Component)renderer).GetComponentInParent() == (Object)null; } if ((Object)(object)_targetItem != (Object)null) { if ((Object)(object)((Component)renderer).GetComponentInParent() == (Object)(object)_targetItem) { return IsActiveLodRenderer(renderer); } return false; } if (((Component)renderer).transform.IsChildOf(((Component)this).transform)) { return IsActiveLodRenderer(renderer); } return false; } private bool IsActiveLodRenderer(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return false; } if (_lodManagedRenderers.Count <= 0) { return true; } if (_lodManagedRenderers.Contains(renderer)) { return _activeLodRenderers.Contains(renderer); } return true; } private static bool IsHelperRenderer(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return true; } if (ContainsAny(BuildTransformPath(((Component)renderer).transform).ToLowerInvariant(), "scannode", "scan node", "mapdot", "map dot", "radar", "minimap", "shadow")) { return true; } if (HasParentComponentNamed(((Component)renderer).transform, "ScanNodeProperties")) { return true; } if (ContainsAny(GetMeshName(renderer).ToLowerInvariant(), "scannode", "mapdot", "radar", "minimap")) { return true; } return ContainsAny(GetMaterialNames(renderer).ToLowerInvariant(), "scannode", "scan node", "mapdot", "map dot", "radar", "minimap", "shadow"); } private static string BuildTransformPath(Transform current) { if ((Object)(object)current == (Object)null) { return string.Empty; } string text = ((Object)current).name; Transform parent = current.parent; int num = 0; while ((Object)(object)parent != (Object)null && num++ < 48) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private static bool HasParentComponentNamed(Transform transform, string componentTypeName) { Transform val = transform; int num = 0; while ((Object)(object)val != (Object)null && num++ < 48) { Component[] components = ((Component)val).GetComponents(); foreach (Component val2 in components) { if ((Object)(object)val2 != (Object)null && ((object)val2).GetType().Name == componentTypeName) { return true; } } val = val.parent; } return false; } private static string GetMeshName(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return string.Empty; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMesh != (Object)null) { return ((Object)val.sharedMesh).name; } MeshFilter component = ((Component)renderer).GetComponent(); if (!((Object)(object)component != (Object)null) || !((Object)(object)component.sharedMesh != (Object)null)) { return string.Empty; } return ((Object)component.sharedMesh).name; } private static string GetMaterialNames(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return string.Empty; } Material[] sharedMaterials = renderer.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { return string.Empty; } string text = string.Empty; foreach (Material val in sharedMaterials) { if (!((Object)(object)val == (Object)null)) { if (text.Length > 0) { text += " "; } text += ((Object)val).name; } } return text; } private static bool ContainsAny(string value, params string[] needles) { if (string.IsNullOrEmpty(value)) { return false; } foreach (string value2 in needles) { if (!string.IsNullOrEmpty(value2) && value.Contains(value2)) { return true; } } return false; } private void ResolveActiveChannel() { int channel = 1; float num = -1f; foreach (KeyValuePair request in _requests) { float num2 = ChannelPriority(request.Value.Channel); if (!(num2 < num)) { num = num2; channel = request.Value.Channel; } } _channel = channel; } private static float ChannelPriority(int channel) { return channel switch { 0 => 3f, 2 => 2f, _ => 1f, }; } private int ApplyChannel() { int num = 0; for (int i = 0; i < _records.Count; i++) { Outline outline = _records[i].Outline; if (!((Object)(object)outline == (Object)null)) { bool flag = RendererBelongsToTarget(_records[i].Renderer); outline.color = _channel; outline.eraseRenderer = false; if (((Behaviour)outline).enabled != flag) { ((Behaviour)outline).enabled = flag; } if (flag) { num++; } } } return num; } private void OnDestroy() { for (int i = 0; i < _records.Count; i++) { OutlineRecord outlineRecord = _records[i]; if (!((Object)(object)outlineRecord.Outline == (Object)null)) { if (outlineRecord.Created) { Object.Destroy((Object)(object)outlineRecord.Outline); continue; } outlineRecord.Outline.color = outlineRecord.PreviousColor; outlineRecord.Outline.eraseRenderer = outlineRecord.PreviousEraseRenderer; ((Behaviour)outlineRecord.Outline).enabled = outlineRecord.PreviousEnabled; } } _records.Clear(); } } private struct OutlineRequest { internal int Channel; internal float ExpiresAt; } private struct OutlineRecord { internal Renderer Renderer; internal Outline Outline; internal bool Created; internal bool PreviousEnabled; internal int PreviousColor; internal bool PreviousEraseRenderer; } private static readonly Color HostileColor = new Color(1f, 0.06f, 0.04f, 1f); private static readonly Color ItemColor = new Color(0.1f, 1f, 0.28f, 1f); private static readonly Color PlayerColor = Color.white; private static Camera _camera; private static OutlineEffect _effect; private static float _nextMissingShaderLogAt; internal static Camera ActiveCamera => _camera; internal static bool Show(Camera camera, GameObject targetRoot, CctvOutlineChannel channel, float duration) { if ((Object)(object)camera == (Object)null || (Object)(object)targetRoot == (Object)null || duration <= 0f) { return false; } if (!EnsureEffect(camera)) { return false; } CctvOutlineTarget cctvOutlineTarget = targetRoot.GetComponent(); if ((Object)(object)cctvOutlineTarget == (Object)null) { cctvOutlineTarget = targetRoot.AddComponent(); } return cctvOutlineTarget.Show(camera, CctvOutlineSource.Cctv, (int)channel, duration); } internal static void Clear(GameObject targetRoot) { if (!((Object)(object)targetRoot == (Object)null)) { CctvOutlineTarget component = targetRoot.GetComponent(); if ((Object)(object)component != (Object)null) { component.Clear(CctvOutlineSource.Cctv); } } } internal static void DisableActiveEffect() { if ((Object)(object)_effect != (Object)null && ((Behaviour)_effect).enabled) { ((Behaviour)_effect).enabled = false; } } private static bool EnsureEffect(Camera camera) { Shader obj = OutlineRuntimeAssets.LoadShader("OutlineShader"); Shader val = OutlineRuntimeAssets.LoadShader("OutlineBufferShader"); Shader val2 = OutlineRuntimeAssets.LoadShader("Y4NGZOutlineOverlayShader"); if ((Object)(object)obj == (Object)null || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { if (Time.unscaledTime >= _nextMissingShaderLogAt) { _nextMissingShaderLogAt = Time.unscaledTime + 10f; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] CCTV OutlineEffect shaders are unavailable; real CCTV outlines will not render."); } } return false; } if ((Object)(object)_effect != (Object)null && (Object)(object)_camera == (Object)(object)camera) { ConfigureEffect(_effect, camera); return true; } _camera = camera; _effect = ((Component)camera).GetComponent(); if ((Object)(object)_effect == (Object)null) { _effect = ((Component)camera).gameObject.AddComponent(); } ConfigureEffect(_effect, camera); return true; } private static void ConfigureEffect(OutlineEffect effect, Camera camera) { //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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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) if (!((Object)(object)effect == (Object)null)) { ((Behaviour)effect).enabled = true; effect.sourceCamera = camera; effect.lineThickness = 1.35f; effect.lineIntensity = 2.25f; effect.fillAmount = 0f; effect.lineColor0 = HostileColor; effect.lineColor1 = ItemColor; effect.lineColor2 = PlayerColor; effect.additiveRendering = true; effect.backfaceCulling = false; effect.useFillColor = false; effect.cornerOutlines = true; effect.addLinesBetweenColors = false; effect.autoEnableOutlines = false; effect.UpdateMaterialsPublicProperties(); } } } public sealed class LinkedSet : IEnumerable, IEnumerable { private readonly LinkedList _list = new LinkedList(); private readonly Dictionary> _dictionary = new Dictionary>(); public int Count => _list.Count; public bool Add(T item) { if (_dictionary.ContainsKey(item)) { return false; } LinkedListNode value = _list.AddLast(item); _dictionary.Add(item, value); return true; } public bool Remove(T item) { if (!_dictionary.TryGetValue(item, out var value)) { return false; } _dictionary.Remove(item); _list.Remove(value); return true; } public bool Contains(T item) { return _dictionary.ContainsKey(item); } public IEnumerator GetEnumerator() { return _list.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } [RequireComponent(typeof(Renderer))] public sealed class Outline : MonoBehaviour { private Material[] _sharedMaterials; public int color; public bool eraseRenderer; public Renderer Renderer { get; private set; } public SpriteRenderer SpriteRenderer { get; private set; } public SkinnedMeshRenderer SkinnedMeshRenderer { get; private set; } public MeshFilter MeshFilter { get; private set; } public Material[] SharedMaterials { get { if (_sharedMaterials == null && (Object)(object)Renderer != (Object)null) { _sharedMaterials = Renderer.sharedMaterials; } return (Material[])(((object)_sharedMaterials) ?? ((object)new Material[0])); } } private void Awake() { Renderer = ((Component)this).GetComponent(); SkinnedMeshRenderer = ((Component)this).GetComponent(); SpriteRenderer = ((Component)this).GetComponent(); MeshFilter = ((Component)this).GetComponent(); } private void OnEnable() { OutlineEffect.Instance?.AddOutline(this); } private void OnDisable() { OutlineEffect.Instance?.RemoveOutline(this); } } [DisallowMultipleComponent] [RequireComponent(typeof(Camera))] public sealed class OutlineEffect : MonoBehaviour { public sealed class Y4NGZHDRPOutlinePass : CustomPass { internal OutlineEffect Owner; public override void Execute(CustomPassContext ctx) { //IL_0010: 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_0021: 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_007a: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) OutlineEffect owner = Owner; if ((Object)(object)owner == (Object)null || ctx.cmd == null || ctx.hdCamera == null) { return; } Camera camera = ctx.hdCamera.camera; if (!((Object)(object)camera == (Object)null) && !((Object)(object)camera != (Object)(object)owner.ResolveSourceCamera()) && owner.HasActiveOutlines()) { int width = Mathf.Max(1, ctx.hdCamera.actualWidth); int height = Mathf.Max(1, ctx.hdCamera.actualHeight); owner.sourceCamera = camera; if (owner.RenderOutlineBuffer(ctx.cmd) && !((Object)(object)owner.outlineOverlayMaterial == (Object)null) && !((Object)(object)owner.renderTexture == (Object)null) && owner._outlineTextureValid) { owner.outlineOverlayMaterial.SetTexture(OutlineSourceId, (Texture)(object)owner.renderTexture); HDUtils.DrawFullScreen(ctx.cmd, owner.outlineOverlayMaterial, ctx.cameraColorBuffer, ctx.cameraDepthBuffer, (MaterialPropertyBlock)null, 0); owner.TraceHdrpComposite(width, height); } } } } private readonly LinkedSet _outlines = new LinkedSet(); private readonly List _materialBuffer = new List(); [Range(1f, 6f)] public float lineThickness = 1.25f; [Range(0f, 10f)] public float lineIntensity = 0.5f; [Range(0f, 1f)] public float fillAmount = 0.2f; public Color lineColor0 = Color.red; public Color lineColor1 = Color.green; public Color lineColor2 = Color.blue; public bool additiveRendering; public bool backfaceCulling = true; public Color fillColor = Color.blue; public bool useFillColor; public bool cornerOutlines; public bool addLinesBetweenColors; public bool scaleWithScreenSize = true; [Range(0f, 1f)] public float alphaCutoff = 0.5f; public bool flipY; public Camera sourceCamera; public bool autoEnableOutlines; public Camera outlineCamera; public Material outlineShaderMaterial; private Material outlineOverlayMaterial; public RenderTexture renderTexture; public RenderTexture extraRenderTexture; private Material _outline1Material; private Material _outline2Material; private Material _outline3Material; private Material _outlineEraseMaterial; private Shader _outlineShader; private Shader _outlineBufferShader; private Shader _outlineOverlayShader; private Shader _maskShader; private CommandBuffer _immediateCommandBuffer; private GameObject _customPassVolumeObject; private CustomPassVolume _customPassVolume; private Y4NGZHDRPOutlinePass _customPass; private bool _renderNextFrame; private bool _pipelineCallbacksRegistered; private bool _outlineTextureValid; private float _nextHdrpTraceAt; private float _nextHdrpWarningAt; private static readonly int CompositeTempId = Shader.PropertyToID("_Y4NGZOutlineCompositeTemp"); private static readonly int OutlineSourceId = Shader.PropertyToID("_OutlineSource"); public static OutlineEffect Instance { get; private set; } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)Instance); } Instance = this; } private void Start() { CreateMaterialsIfNeeded(); UpdateMaterialsPublicProperties(); if ((Object)(object)sourceCamera == (Object)null) { sourceCamera = ((Component)this).GetComponent() ?? Camera.main; } RecreateRenderTexturesIfNeeded(); EnsureHdrpCustomPass(); } private void OnEnable() { if ((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null) { EnsureHdrpCustomPass(); } else { RegisterPipelineCallbacks(); } Outline[] array = Object.FindObjectsOfType(); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null && !_outlines.Contains(array[i])) { _outlines.Add(array[i]); } } } private void OnDisable() { UnregisterPipelineCallbacks(); if ((Object)(object)_customPassVolume != (Object)null) { ((Behaviour)_customPassVolume).enabled = false; } } private void OnPreRender() { //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_002c: Expected O, but got Unknown if (!((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null)) { if (_immediateCommandBuffer == null) { _immediateCommandBuffer = new CommandBuffer { name = "Y4NGZ Outline Buffer" }; } _immediateCommandBuffer.Clear(); if (RenderOutlineBuffer(_immediateCommandBuffer)) { Graphics.ExecuteCommandBuffer(_immediateCommandBuffer); } } } [ImageEffectOpaque] private void OnRenderImage(RenderTexture source, RenderTexture destination) { if ((Object)(object)outlineShaderMaterial == (Object)null || (Object)(object)renderTexture == (Object)null || !_outlineTextureValid) { Graphics.Blit((Texture)(object)source, destination); return; } outlineShaderMaterial.SetTexture("_OutlineSource", (Texture)(object)renderTexture); if (addLinesBetweenColors && (Object)(object)extraRenderTexture != (Object)null) { Graphics.Blit((Texture)(object)source, extraRenderTexture, outlineShaderMaterial, 0); outlineShaderMaterial.SetTexture("_OutlineSource", (Texture)(object)extraRenderTexture); } Graphics.Blit((Texture)(object)source, destination, outlineShaderMaterial, 1); } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } UnregisterPipelineCallbacks(); if ((Object)(object)_customPassVolumeObject != (Object)null) { Object.Destroy((Object)(object)_customPassVolumeObject); _customPassVolumeObject = null; _customPassVolume = null; _customPass = null; } if (_immediateCommandBuffer != null) { _immediateCommandBuffer.Release(); _immediateCommandBuffer = null; } if ((Object)(object)renderTexture != (Object)null) { renderTexture.Release(); } if ((Object)(object)extraRenderTexture != (Object)null) { extraRenderTexture.Release(); } DestroyMaterials(); } public void AddOutline(Outline outline) { if (!((Object)(object)outline == (Object)null)) { _outlines.Add(outline); EnsureHdrpCustomPass(); } } public void RemoveOutline(Outline outline) { if ((Object)(object)outline != (Object)null) { _outlines.Remove(outline); } } private bool HasActiveOutlines() { if (_outlines.Count == 0) { return false; } foreach (Outline outline in _outlines) { if ((Object)(object)outline != (Object)null && ((Behaviour)outline).enabled && (Object)(object)outline.Renderer != (Object)null && outline.Renderer.enabled) { return true; } } return false; } private void EnsureHdrpCustomPass() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0184: 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_019c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)GraphicsSettings.currentRenderPipeline == (Object)null) { return; } Camera val = ResolveSourceCamera(); if ((Object)(object)val == (Object)null) { return; } if ((Object)(object)_customPassVolume != (Object)null && _customPass != null) { _customPass.Owner = this; _customPassVolume.targetCamera = null; ((Behaviour)_customPassVolume).enabled = ((Behaviour)this).isActiveAndEnabled; return; } if ((Object)(object)_customPassVolumeObject == (Object)null) { _customPassVolumeObject = new GameObject("Y4NGZ_OutlineCustomPassVolume") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)(object)_customPassVolumeObject); } _customPassVolume = _customPassVolumeObject.GetComponent(); if ((Object)(object)_customPassVolume == (Object)null) { _customPassVolume = _customPassVolumeObject.AddComponent(); } _customPassVolume.isGlobal = true; _customPassVolume.priority = 1000f; _customPassVolume.injectionPoint = (CustomPassInjectionPoint)3; _customPassVolume.targetCamera = null; _customPassVolume.customPasses.Clear(); CustomPass val2 = _customPassVolume.AddPassOfType(typeof(Y4NGZHDRPOutlinePass)); _customPass = val2 as Y4NGZHDRPOutlinePass; if (_customPass == null) { if (Time.unscaledTime >= _nextHdrpWarningAt) { _nextHdrpWarningAt = Time.unscaledTime + 10f; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)"[LethalCCTV] OutlineEffect failed to register HDRP custom pass; CCTV outlines may be invisible."); } } return; } ((CustomPass)_customPass).name = "Y4NGZ Outline Composite"; ((CustomPass)_customPass).enabled = true; ((CustomPass)_customPass).targetColorBuffer = (TargetBuffer)0; ((CustomPass)_customPass).targetDepthBuffer = (TargetBuffer)0; ((CustomPass)_customPass).clearFlags = (ClearFlag)0; _customPass.Owner = this; ((Behaviour)_customPassVolume).enabled = ((Behaviour)this).isActiveAndEnabled; ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogInfo((object)("[LethalCCTV] OutlineEffect HDRP custom pass registered for '" + ((Object)val).name + "'.")); } } private void TraceHdrpComposite(int width, int height) { if (!(Time.unscaledTime < _nextHdrpTraceAt)) { _nextHdrpTraceAt = Time.unscaledTime + 5f; ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogInfo((object)$"[LethalCCTV] OutlineEffect HDRP custom pass compositing {_outlines.Count} outline renderer(s) at {width}x{height}."); } } } public void UpdateMaterialsPublicProperties() { if (CreateMaterialsIfNeeded() && !((Object)(object)outlineShaderMaterial == (Object)null)) { float num = 1f; if (scaleWithScreenSize) { num = (float)Screen.height / 360f; } float thicknessScale = ((scaleWithScreenSize && num >= 1f) ? num : 1f); ApplyMaterialProperties(outlineShaderMaterial, thicknessScale, legacyComposite: true); if ((Object)(object)outlineOverlayMaterial != (Object)null) { ApplyMaterialProperties(outlineOverlayMaterial, thicknessScale, legacyComposite: false); } Shader.SetGlobalFloat("_OutlineAlphaCutoff", alphaCutoff); } } private void ApplyMaterialProperties(Material material, float thicknessScale, bool legacyComposite) { //IL_0075: 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_006d: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null)) { material.SetFloat("_LineThicknessX", thicknessScale * (lineThickness / Mathf.Max(1f, (float)Screen.width))); material.SetFloat("_LineThicknessY", thicknessScale * (lineThickness / Mathf.Max(1f, (float)Screen.height))); material.SetFloat("_LineIntensity", lineIntensity); material.SetColor("_LineColor1", legacyComposite ? (lineColor0 * lineColor0) : lineColor0); material.SetColor("_LineColor2", legacyComposite ? (lineColor1 * lineColor1) : lineColor1); material.SetColor("_LineColor3", legacyComposite ? (lineColor2 * lineColor2) : lineColor2); material.SetInt("_CornerOutlines", cornerOutlines ? 1 : 0); if (legacyComposite) { material.SetFloat("_FillAmount", fillAmount); material.SetColor("_FillColor", fillColor); material.SetFloat("_UseFillColor", useFillColor ? 1f : 0f); material.SetInt("_FlipY", flipY ? 1 : 0); material.SetInt("_Dark", (!additiveRendering) ? 1 : 0); } } } private void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera) { if ((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null || (Object)(object)camera == (Object)null || (Object)(object)camera != (Object)(object)ResolveSourceCamera()) { return; } CommandBuffer val = CommandBufferPool.Get("Y4NGZ Outline Buffer"); try { if (RenderOutlineBuffer(val)) { ((ScriptableRenderContext)(ref context)).ExecuteCommandBuffer(val); } } finally { CommandBufferPool.Release(val); } } private void OnEndCameraRendering(ScriptableRenderContext context, Camera camera) { //IL_0098: 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_00b9: 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) if ((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null || (Object)(object)camera == (Object)null || (Object)(object)camera != (Object)(object)ResolveSourceCamera() || (Object)(object)outlineShaderMaterial == (Object)null || (Object)(object)renderTexture == (Object)null || !_outlineTextureValid) { return; } int num = Mathf.Max(1, camera.pixelWidth); int num2 = Mathf.Max(1, camera.pixelHeight); CommandBuffer val = CommandBufferPool.Get("Y4NGZ Outline Composite"); try { outlineShaderMaterial.SetTexture("_OutlineSource", (Texture)(object)renderTexture); val.GetTemporaryRT(CompositeTempId, num, num2, 0, (FilterMode)1, (RenderTextureFormat)7); val.Blit(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)2), RenderTargetIdentifier.op_Implicit(CompositeTempId), outlineShaderMaterial, 1); val.Blit(RenderTargetIdentifier.op_Implicit(CompositeTempId), RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)2)); val.ReleaseTemporaryRT(CompositeTempId); ((ScriptableRenderContext)(ref context)).ExecuteCommandBuffer(val); } finally { CommandBufferPool.Release(val); } } private bool RenderOutlineBuffer(CommandBuffer commandBuffer) { //IL_0069: 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_00a3: 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_00bf: Unknown result type (might be due to invalid IL or missing references) if (commandBuffer == null) { return false; } if ((Object)(object)ResolveSourceCamera() == (Object)null) { return false; } if (_outlines.Count == 0) { if (!_renderNextFrame) { return false; } _renderNextFrame = false; } else { _renderNextFrame = true; } if (!CreateMaterialsIfNeeded()) { return false; } RecreateRenderTexturesIfNeeded(); UpdateMaterialsPublicProperties(); if ((Object)(object)renderTexture == (Object)null) { return false; } commandBuffer.SetRenderTarget(RenderTargetIdentifier.op_Implicit((Texture)(object)renderTexture)); commandBuffer.SetViewport(new Rect(0f, 0f, (float)((Texture)renderTexture).width, (float)((Texture)renderTexture).height)); commandBuffer.ClearRenderTarget(true, true, Color.clear); commandBuffer.SetViewProjectionMatrices(sourceCamera.worldToCameraMatrix, sourceCamera.projectionMatrix); foreach (Outline outline in _outlines) { DrawOutline(commandBuffer, outline); } _outlineTextureValid = true; return true; } private Camera ResolveSourceCamera() { if ((Object)(object)sourceCamera == (Object)null) { sourceCamera = ((Component)this).GetComponent() ?? Camera.main; } return sourceCamera; } private void RegisterPipelineCallbacks() { if (!_pipelineCallbacksRegistered) { RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering; RenderPipelineManager.endCameraRendering += OnEndCameraRendering; _pipelineCallbacksRegistered = true; } } private void UnregisterPipelineCallbacks() { if (_pipelineCallbacksRegistered) { RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering; RenderPipelineManager.endCameraRendering -= OnEndCameraRendering; _pipelineCallbacksRegistered = false; } } private void DrawOutline(CommandBuffer commandBuffer, Outline outline) { if ((Object)(object)outline == (Object)null || (Object)(object)outline.Renderer == (Object)null || !((Behaviour)outline).enabled) { return; } Material[] sharedMaterials = outline.SharedMaterials; for (int i = 0; i < sharedMaterials.Length; i++) { Material val = ResolveBufferMaterial(outline, sharedMaterials[i]); if ((Object)(object)val == (Object)null) { continue; } if (val.HasProperty("_Culling")) { val.SetInt("_Culling", backfaceCulling ? 2 : 0); } if (val.HasProperty("_Cull")) { val.SetInt("_Cull", backfaceCulling ? 2 : 0); } MeshFilter meshFilter = outline.MeshFilter; SkinnedMeshRenderer skinnedMeshRenderer = outline.SkinnedMeshRenderer; SpriteRenderer spriteRenderer = outline.SpriteRenderer; int num = ResolveMaskMaterialPass(val); if ((Object)(object)meshFilter != (Object)null && (Object)(object)meshFilter.sharedMesh != (Object)null) { if (i < meshFilter.sharedMesh.subMeshCount) { commandBuffer.DrawRenderer(outline.Renderer, val, i, num); } } else if ((Object)(object)skinnedMeshRenderer != (Object)null && (Object)(object)skinnedMeshRenderer.sharedMesh != (Object)null) { if (i < skinnedMeshRenderer.sharedMesh.subMeshCount) { commandBuffer.DrawRenderer(outline.Renderer, val, i, num); } } else if ((Object)(object)spriteRenderer != (Object)null) { commandBuffer.DrawRenderer(outline.Renderer, val, i, num); } } } private Material ResolveBufferMaterial(Outline outline, Material sourceMaterial) { if ((Object)(object)outline == (Object)null) { return null; } if (!outline.eraseRenderer) { return GetMaterialFromId(outline.color); } return _outlineEraseMaterial; } private Material GetMaterialFromId(int id) { return (Material)(id switch { 1 => _outline2Material, 2 => _outline3Material, _ => _outline1Material, }); } private void EnsureOutlineCamera() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown if ((Object)(object)sourceCamera == (Object)null || (Object)(object)outlineCamera != (Object)null) { return; } Camera[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && ((Object)componentsInChildren[i]).name == "Outline Camera") { outlineCamera = componentsInChildren[i]; ((Behaviour)outlineCamera).enabled = false; return; } } GameObject val = new GameObject("Outline Camera"); val.transform.SetParent(((Component)sourceCamera).transform, false); outlineCamera = val.AddComponent(); ((Behaviour)outlineCamera).enabled = false; } private void RecreateRenderTexturesIfNeeded() { //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_00bd: Expected O, but got Unknown //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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown if ((Object)(object)sourceCamera == (Object)null) { return; } int num = Mathf.Max(1, sourceCamera.pixelWidth); int num2 = Mathf.Max(1, sourceCamera.pixelHeight); if ((Object)(object)renderTexture == (Object)null || ((Texture)renderTexture).width != num || ((Texture)renderTexture).height != num2) { if ((Object)(object)renderTexture != (Object)null) { renderTexture.Release(); } if ((Object)(object)extraRenderTexture != (Object)null) { extraRenderTexture.Release(); } _outlineTextureValid = false; renderTexture = new RenderTexture(num, num2, 16, (RenderTextureFormat)0) { filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; extraRenderTexture = new RenderTexture(num, num2, 16, (RenderTextureFormat)0) { filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; if ((Object)(object)outlineCamera != (Object)null) { outlineCamera.targetTexture = renderTexture; } } } private bool CreateMaterialsIfNeeded() { //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_00ae: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_outlineShader == (Object)null) { _outlineShader = OutlineRuntimeAssets.LoadShader("OutlineShader"); } if ((Object)(object)_outlineBufferShader == (Object)null) { _outlineBufferShader = OutlineRuntimeAssets.LoadShader("OutlineBufferShader"); } if ((Object)(object)_outlineOverlayShader == (Object)null) { _outlineOverlayShader = OutlineRuntimeAssets.LoadShader("Y4NGZOutlineOverlayShader"); } if ((Object)(object)_outlineShader == (Object)null) { return false; } if ((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null && (Object)(object)_outlineOverlayShader == (Object)null) { return false; } if ((Object)(object)outlineShaderMaterial == (Object)null) { outlineShaderMaterial = new Material(_outlineShader) { hideFlags = (HideFlags)61 }; } if ((Object)(object)outlineOverlayMaterial == (Object)null && (Object)(object)_outlineOverlayShader != (Object)null) { outlineOverlayMaterial = new Material(_outlineOverlayShader) { hideFlags = (HideFlags)61 }; } if ((Object)(object)_outlineEraseMaterial == (Object)null) { _outlineEraseMaterial = CreateMaterial(new Color(0f, 0f, 0f, 0f)); } if ((Object)(object)_outline1Material == (Object)null) { _outline1Material = CreateMaterial(new Color(1f, 0f, 0f, 1f)); } if ((Object)(object)_outline2Material == (Object)null) { _outline2Material = CreateMaterial(new Color(0f, 1f, 0f, 1f)); } if ((Object)(object)_outline3Material == (Object)null) { _outline3Material = CreateMaterial(new Color(0f, 0f, 1f, 1f)); } if ((Object)(object)outlineShaderMaterial != (Object)null && ((Object)(object)GraphicsSettings.currentRenderPipeline == (Object)null || (Object)(object)outlineOverlayMaterial != (Object)null) && (Object)(object)_outlineEraseMaterial != (Object)null && (Object)(object)_outline1Material != (Object)null && (Object)(object)_outline2Material != (Object)null) { return (Object)(object)_outline3Material != (Object)null; } return false; } private Material CreateMaterial(Color emissionColor) { //IL_0013: 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_0020: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_0033: Expected O, but got Unknown Shader val = ResolveMaskShader(); if ((Object)(object)val == (Object)null) { return null; } Material val2 = new Material(val) { hideFlags = (HideFlags)61, renderQueue = 2500 }; ConfigureMaskMaterial(val2, emissionColor); return val2; } private Shader ResolveMaskShader() { if ((Object)(object)_maskShader != (Object)null) { return _maskShader; } if ((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null) { _maskShader = Shader.Find("HDRP/Unlit") ?? Shader.Find("Hidden/Internal-Colored") ?? Shader.Find("Unlit/Color"); } if ((Object)(object)_maskShader == (Object)null) { _maskShader = _outlineBufferShader; } return _maskShader; } private static void ConfigureMaskMaterial(Material material, Color color) { //IL_0010: 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_0028: 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) if (!((Object)(object)material == (Object)null)) { SetColorIfPresent(material, "_Color", color); SetColorIfPresent(material, "_BaseColor", color); SetColorIfPresent(material, "_UnlitColor", color); SetColorIfPresent(material, "_EmissiveColor", color); SetFloatIfPresent(material, "_SurfaceType", 0f); SetFloatIfPresent(material, "_AlphaCutoffEnable", 0f); SetFloatIfPresent(material, "_ZWrite", 0f); SetFloatIfPresent(material, "_ZTestDepthEqualForOpaque", 8f); SetIntIfPresent(material, "_SrcBlend", 1); SetIntIfPresent(material, "_DstBlend", 0); SetIntIfPresent(material, "_Cull", 0); SetIntIfPresent(material, "_Culling", 0); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); } } private static int ResolveMaskMaterialPass(Material material) { if ((Object)(object)material == (Object)null) { return 0; } string[] array = new string[4] { "ForwardOnly", "Forward", "SRPDefaultUnlit", "DepthForwardOnly" }; for (int i = 0; i < array.Length; i++) { int num = material.FindPass(array[i]); if (num >= 0) { return num; } } return 0; } private static void SetColorIfPresent(Material material, string name, Color value) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (material.HasProperty(name)) { material.SetColor(name, value); } } private static void SetFloatIfPresent(Material material, string name, float value) { if (material.HasProperty(name)) { material.SetFloat(name, value); } } private static void SetIntIfPresent(Material material, string name, int value) { if (material.HasProperty(name)) { material.SetInt(name, value); } } private void UpdateOutlineCameraFromSource() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)outlineCamera == (Object)null) && !((Object)(object)sourceCamera == (Object)null)) { outlineCamera.CopyFrom(sourceCamera); outlineCamera.renderingPath = (RenderingPath)1; outlineCamera.backgroundColor = new Color(0f, 0f, 0f, 0f); outlineCamera.clearFlags = (CameraClearFlags)2; outlineCamera.rect = new Rect(0f, 0f, 1f, 1f); outlineCamera.cullingMask = 0; outlineCamera.targetTexture = renderTexture; ((Behaviour)outlineCamera).enabled = false; outlineCamera.allowHDR = false; } } private void DestroyMaterials() { for (int i = 0; i < _materialBuffer.Count; i++) { if ((Object)(object)_materialBuffer[i] != (Object)null) { Object.Destroy((Object)(object)_materialBuffer[i]); } } _materialBuffer.Clear(); if ((Object)(object)outlineShaderMaterial != (Object)null) { Object.Destroy((Object)(object)outlineShaderMaterial); } if ((Object)(object)outlineOverlayMaterial != (Object)null) { Object.Destroy((Object)(object)outlineOverlayMaterial); } if ((Object)(object)_outlineEraseMaterial != (Object)null) { Object.Destroy((Object)(object)_outlineEraseMaterial); } if ((Object)(object)_outline1Material != (Object)null) { Object.Destroy((Object)(object)_outline1Material); } if ((Object)(object)_outline2Material != (Object)null) { Object.Destroy((Object)(object)_outline2Material); } if ((Object)(object)_outline3Material != (Object)null) { Object.Destroy((Object)(object)_outline3Material); } } } internal static class OutlineRuntimeAssets { internal const string BundleName = "y4ngz-outlineeffect.bundle"; private static readonly Dictionary ShaderCache = new Dictionary(); private static AssetBundle _bundle; private static bool _loadAttempted; internal static Shader LoadShader(string shaderName) { if (string.IsNullOrWhiteSpace(shaderName)) { return null; } if (ShaderCache.TryGetValue(shaderName, out var value) && (Object)(object)value != (Object)null) { return value; } Shader val = Resources.Load(shaderName); if ((Object)(object)val == (Object)null) { val = LoadShaderFromBundles(shaderName); } if ((Object)(object)val != (Object)null) { ShaderCache[shaderName] = val; } else { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] OutlineEffect shader '" + shaderName + "' could not be loaded. Missing y4ngz-outlineeffect.bundle?")); } } return val; } private static Shader LoadShaderFromBundles(string shaderName) { foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { if (!((Object)(object)allLoadedAssetBundle == (Object)null)) { Shader val = allLoadedAssetBundle.LoadAsset(shaderName); if ((Object)(object)val != (Object)null) { return val; } } } EnsureBundleLoaded(); if (!((Object)(object)_bundle != (Object)null)) { return null; } return _bundle.LoadAsset(shaderName); } private static void EnsureBundleLoaded() { if (_loadAttempted) { return; } _loadAttempted = true; string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty, "y4ngz-outlineeffect.bundle"); if (!File.Exists(text)) { ManualLogSource log = SurveillanceBootstrap.Log; if (log != null) { log.LogWarning((object)("[LethalCCTV] OutlineEffect bundle is missing at " + text + ".")); } return; } _bundle = AssetBundle.LoadFromFile(text); if ((Object)(object)_bundle == (Object)null) { ManualLogSource log2 = SurveillanceBootstrap.Log; if (log2 != null) { log2.LogWarning((object)("[LethalCCTV] Failed to load outline effect bundle at " + text + ".")); } } } } } namespace Y4NGZCompany.Facility.Stash { public static class CompanyStashCodeDebugApi { public static string GetStatus() { return CctvSupportApi.GetStashCodeDebugReport(); } } public sealed class CompanyStashController : NetworkBehaviour, ICompanyStashKeypadClient { private sealed class AmmoLootEntry { internal readonly string ItemName; internal readonly int Weight; internal readonly int Count; internal AmmoLootEntry(string itemName, int weight, int count) { ItemName = itemName; Weight = weight; Count = count; } } public const int CodeDigits = 4; private const int ScanNodeLayer = 22; private const float ResultDisplaySeconds = 1.15f; private const float LootSpawnDelaySeconds = 0.65f; private const float LootLateralOffsetStep = 0.25f; private const string AccessDeniedText = "Denied"; private const string AccessGrantedText = "Granted"; private static readonly Vector3 KeypadMountedRootLocalPosition = new Vector3(-0.17f, 1.28f, 0.26f); private static readonly Vector3 GoldBarStableRootLocalPosition = new Vector3(0f, 0.75f, -0.08f); private readonly NetworkVariable _isUnlocked = new NetworkVariable(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private int _assignedCode = -1; private string _displayName = "Company Stash"; private string _localInput = string.Empty; private float _resultDisplayUntil; private CompanyStashKeypadInteractor _keypad; private Transform _keypadVisualRoot; private Animator _animator; private Animation _legacyAnimation; private Transform _leftDoor; private Transform _rightDoor; private Transform _goldBarSpawnAnchor; private Quaternion _leftClosedRotation; private Quaternion _rightClosedRotation; private bool _capturedDoorRotations; private bool _fallbackOpening; private float _fallbackOpenProgress; private bool _openVisualStarted; private bool _lootSpawned; private bool _keypadMounted; private bool _localSubmitPending; private Coroutine _lootSpawnRoutine; public bool IsUnlocked => _isUnlocked.Value; public string DisplayName { get { if (!string.IsNullOrWhiteSpace(_displayName)) { return _displayName; } return "Company Stash"; } } internal bool HasLocalKeypadInput => !string.IsNullOrEmpty(_localInput); bool ICompanyStashKeypadClient.HasLocalKeypadInput => HasLocalKeypadInput; bool ICompanyStashKeypadClient.AllowsFallbackDisplayText => true; bool ICompanyStashKeypadClient.AllowsFallbackButtonVisuals => true; string ICompanyStashKeypadClient.MissingButtonVisualsWarning => null; public void InitializeAssignedCode(int code, string displayName) { _assignedCode = Mathf.Clamp(code, 0, 9999); if (!string.IsNullOrWhiteSpace(displayName)) { _displayName = displayName; } } private void Awake() { EnsureRuntimeComponents(); } private void Start() { EnsureRuntimeComponents(); ApplyUnlockedStateLocal(force: true); } public override void OnNetworkSpawn() { ((NetworkBehaviour)this).OnNetworkSpawn(); EnsureRuntimeComponents(); CctvSupportState.RegisterRuntimeStash(this); NetworkVariable isUnlocked = _isUnlocked; isUnlocked.OnValueChanged = (OnValueChangedDelegate)(object)Delegate.Combine((Delegate?)(object)isUnlocked.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate(OnUnlockedChanged)); if (((NetworkBehaviour)this).IsServer && _assignedCode < 0 && CctvSupportState.TryGetAssignedStashCode(0, out var code)) { _assignedCode = code; } ApplyUnlockedStateLocal(force: true); } public override void OnNetworkDespawn() { if (_lootSpawnRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_lootSpawnRoutine); _lootSpawnRoutine = null; } CctvSupportState.UnregisterRuntimeStash(this); NetworkVariable isUnlocked = _isUnlocked; isUnlocked.OnValueChanged = (OnValueChangedDelegate)(object)Delegate.Remove((Delegate?)(object)isUnlocked.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate(OnUnlockedChanged)); ((NetworkBehaviour)this).OnNetworkDespawn(); } private void Update() { EnsureRuntimeComponents(); UpdateFallbackOpenAnimation(); if (_resultDisplayUntil > 0f && Time.time >= _resultDisplayUntil && !IsUnlocked) { _resultDisplayUntil = 0f; UpdateKeypadEntryDisplay(); } } internal void PressKeypadButtonLocally(int button, PlayerControllerB player) { EnsureRuntimeComponents(); if (IsUnlocked) { ShowKeypadStatus("Granted", (CompanyStashKeypadDisplayState)2, 1.15f); } else { if (_localSubmitPending) { return; } if (button == -1) { SubmitLocalInput(); return; } int num = Mathf.Clamp(button, 0, 9); if (_localInput.Length >= 4) { _localInput = string.Empty; } _localInput += num; UpdateKeypadEntryDisplay(); if (_localInput.Length >= 4) { SubmitLocalInput(); } } } internal string GetKeypadButtonTip(int button) { if (button == -1) { return "Press [Enter]"; } return $"Press [{Mathf.Clamp(button, 0, 9)}]"; } internal string GetKeypadDisabledTip() { if (!IsUnlocked) { return "[ Keypad unavailable ]"; } return "[ Granted ]"; } bool ICompanyStashKeypadClient.IsKeypadInteractable() { return IsKeypadInteractable(); } string ICompanyStashKeypadClient.GetKeypadButtonTip(int button) { return GetKeypadButtonTip(button); } string ICompanyStashKeypadClient.GetKeypadDisabledTip() { return GetKeypadDisabledTip(); } void ICompanyStashKeypadClient.PressKeypadButtonLocally(int button, PlayerControllerB player) { PressKeypadButtonLocally(button, player); } string ICompanyStashKeypadClient.GetKeypadLockedDisplayText() { if (!IsUnlocked) { return "LOCKED"; } return "GRANTED"; } CompanyStashKeypadDisplayState ICompanyStashKeypadClient.GetKeypadLockedDisplayState() { if (IsUnlocked) { return (CompanyStashKeypadDisplayState)2; } return (CompanyStashKeypadDisplayState)1; } internal bool IsKeypadInteractable() { return !IsUnlocked; } private void SubmitLocalInput() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) int result; if (_localInput.Length != 4) { _localInput = string.Empty; ShowKeypadStatus("Denied", (CompanyStashKeypadDisplayState)1, 1.15f); } else if (!int.TryParse(_localInput, out result)) { _localInput = string.Empty; ShowKeypadStatus("Denied", (CompanyStashKeypadDisplayState)1, 1.15f); } else { _localSubmitPending = true; SubmitCodeServerRpc(result); } } [ServerRpc(RequireOwnership = false)] private void SubmitCodeServerRpc(int code, ServerRpcParams rpcParams = default(ServerRpcParams)) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: 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_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(251010402u, rpcParams, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, code); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 251010402u, rpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost)) { return; } base.__rpc_exec_stage = (__RpcExecStage)0; if (!((NetworkBehaviour)this).IsServer || _isUnlocked.Value) { return; } if (!IsSenderCloseEnough(rpcParams.Receive.SenderClientId)) { SendKeypadResultClientRpc(granted: false, "Denied", BuildTargetClientParams(rpcParams.Receive.SenderClientId)); return; } bool flag = _assignedCode >= 0 && Mathf.Clamp(code, 0, 9999) == _assignedCode; ManualLogSource log = CctvModuleConfig.Log; if (log != null) { log.LogInfo((object)string.Format("[MoonContracts] Company Stash '{0}' keypad submit code={1:D4} assigned={2} granted={3}.", DisplayName, code, (_assignedCode >= 0) ? _assignedCode.ToString("D4") : "none", flag)); } if (!flag) { SendKeypadResultClientRpc(granted: false, "Denied", BuildTargetClientParams(rpcParams.Receive.SenderClientId)); return; } _isUnlocked.Value = true; ManualLogSource log2 = CctvModuleConfig.Log; if (log2 != null) { log2.LogInfo((object)$"[MoonContracts] Company Stash '{DisplayName}' unlocked with code {_assignedCode:D4}."); } SendKeypadResultClientRpc(granted: true, "Granted", BuildTargetClientParams(rpcParams.Receive.SenderClientId)); ApplyUnlockedStateLocal(force: true); BeginSpawnGoldBarLootServer(); } [ServerRpc(RequireOwnership = false)] public void UnlockFromRemoteHackServerRpc(ServerRpcParams rpcParams = default(ServerRpcParams)) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_00dd: 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_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(4141495960u, rpcParams, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 4141495960u, rpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost)) { return; } base.__rpc_exec_stage = (__RpcExecStage)0; if (((NetworkBehaviour)this).IsServer && !_isUnlocked.Value && IsSenderWithinRemoteHackRange(rpcParams.Receive.SenderClientId)) { _isUnlocked.Value = true; ManualLogSource log = CctvModuleConfig.Log; if (log != null) { log.LogInfo((object)("[MoonContracts] Company Stash '" + DisplayName + "' unlocked via remote hack.")); } SendKeypadResultClientRpc(granted: true, "Granted", BuildTargetClientParams(rpcParams.Receive.SenderClientId)); ApplyUnlockedStateLocal(force: true); BeginSpawnGoldBarLootServer(); } } [ClientRpc] private void SendKeypadResultClientRpc(bool granted, string message, ClientRpcParams clientRpcParams = default(ClientRpcParams)) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2540321899u, clientRpcParams, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe(ref granted, default(ForPrimitives)); bool flag = message != null; ((FastBufferWriter)(ref val)).WriteValueSafe(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val)).WriteValueSafe(message, false); } ((NetworkBehaviour)this).__endSendClientRpc(ref val, 2540321899u, clientRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; _localInput = string.Empty; _localSubmitPending = false; ShowKeypadStatus((!string.IsNullOrWhiteSpace(message)) ? message : (granted ? "Granted" : "Denied"), (CompanyStashKeypadDisplayState)((!granted) ? 1 : 2), granted ? 0f : 1.15f); } } private static ClientRpcParams BuildTargetClientParams(ulong clientId) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) return new ClientRpcParams { Send = new ClientRpcSendParams { TargetClientIds = new ulong[1] { clientId } } }; } private void OnUnlockedChanged(bool previous, bool current) { if (current) { ApplyUnlockedStateLocal(force: true); } } private void ApplyUnlockedStateLocal(bool force) { if (force || IsUnlocked) { if (IsUnlocked) { _localInput = string.Empty; _localSubmitPending = false; ShowKeypadStatus("Granted", (CompanyStashKeypadDisplayState)2, 0f); StartOpenVisualLocal(); } else { UpdateKeypadEntryDisplay(); } CompanyStashKeypadInteractor keypad = _keypad; if (keypad != null) { keypad.RefreshButtons(); } UpdateLockerScanNode(); } } private void UpdateKeypadEntryDisplay() { if (!((Object)(object)_keypad == (Object)null)) { char[] array = new char[4] { '_', '_', '_', '_' }; for (int i = 0; i < Mathf.Min(_localInput.Length, array.Length); i++) { array[i] = _localInput[i]; } _keypad.SetDisplayText($"{array[0]} {array[1]} {array[2]} {array[3]}", (CompanyStashKeypadDisplayState)0); } } private void ShowKeypadStatus(string text, CompanyStashKeypadDisplayState state, float seconds) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) CompanyStashKeypadInteractor keypad = _keypad; if (keypad != null) { keypad.SetDisplayText(text, state); } _resultDisplayUntil = ((seconds > 0f) ? (Time.time + seconds) : 0f); } private void EnsureRuntimeComponents() { if ((Object)(object)_keypadVisualRoot == (Object)null) { _keypadVisualRoot = FindKeypadVisualRoot(); } if ((Object)(object)_keypad == (Object)null) { _keypad = ((Component)this).GetComponentInChildren(true); if ((Object)(object)_keypad == (Object)null) { Transform val = (((Object)(object)_keypadVisualRoot != (Object)null) ? _keypadVisualRoot : ((Component)this).transform); _keypad = ((Component)val).gameObject.AddComponent(); } } if ((Object)(object)_animator == (Object)null) { _animator = FindComponentOutsideKeypad(); } if ((Object)(object)_legacyAnimation == (Object)null) { _legacyAnimation = FindComponentOutsideKeypad(); } if ((Object)(object)_leftDoor == (Object)null) { _leftDoor = FindDoorTransform(rightDoor: false) ?? FindChildByNameToken(((Component)this).transform, "door-l") ?? FindChildByNameToken(((Component)this).transform, "door_l") ?? FindChildByNameToken(((Component)this).transform, "leftdoor") ?? FindChildByNameToken(((Component)this).transform, "doorleft"); } if ((Object)(object)_rightDoor == (Object)null) { _rightDoor = FindDoorTransform(rightDoor: true) ?? FindChildByNameToken(((Component)this).transform, "door-r") ?? FindChildByNameToken(((Component)this).transform, "door_r") ?? FindChildByNameToken(((Component)this).transform, "rightdoor") ?? FindChildByNameToken(((Component)this).transform, "doorright"); } if ((Object)(object)_goldBarSpawnAnchor == (Object)null) { _goldBarSpawnAnchor = FindChildByNameToken(((Component)this).transform, "GoldBarSpawnAnchor") ?? FindChildByNameToken(((Component)this).transform, "LootSpawnAnchor") ?? FindChildByNameToken(((Component)this).transform, "LootAnchor"); } CaptureDoorRotations(); MountKeypadToDoor(); EnsureScanNodes(); } private void BeginSpawnGoldBarLootServer() { if (((NetworkBehaviour)this).IsServer && !_lootSpawned && _lootSpawnRoutine == null) { _lootSpawnRoutine = ((MonoBehaviour)this).StartCoroutine(SpawnGoldBarLootDelayedServer()); } } private IEnumerator SpawnGoldBarLootDelayedServer() { yield return (object)new WaitForSeconds(0.65f); _lootSpawnRoutine = null; SpawnGoldBarLootServer(); try { SpawnExtraAmmoLootServer(); } catch (Exception arg) { ManualLogSource log = CctvModuleConfig.Log; if (log != null) { log.LogWarning((object)$"[MoonContracts] Company Stash '{DisplayName}' extra ammo loot rolls failed: {arg}"); } } } private void SpawnGoldBarLootServer() { if (!((NetworkBehaviour)this).IsServer || _lootSpawned) { return; } EnsureRuntimeComponents(); Item val = ResolveGoldBarItem(); if ((Object)(object)val?.spawnPrefab == (Object)null) { ManualLogSource log = CctvModuleConfig.Log; if (log != null) { log.LogWarning((object)("[MoonContracts] Company Stash '" + DisplayName + "' could not spawn loot: vanilla Gold bar item was not found.")); } return; } GameObject val2 = SpawnStashLootItem(val, 0); if ((Object)(object)val2 == (Object)null) { return; } if ((Object)(object)val2.GetComponent() == (Object)null) { ManualLogSource log2 = CctvModuleConfig.Log; if (log2 != null) { log2.LogWarning((object)("[MoonContracts] Company Stash '" + DisplayName + "' spawned Gold bar loot without a NetworkObject.")); } return; } _lootSpawned = true; ManualLogSource log3 = CctvModuleConfig.Log; if (log3 != null) { log3.LogInfo((object)$"[MoonContracts] Company Stash '{DisplayName}' spawned Gold bar loot value={val2.GetComponent()?.scrapValue ?? 0}."); } } private void SpawnExtraAmmoLootServer() { if (!((NetworkBehaviour)this).IsServer || !_lootSpawned) { return; } int num = Mathf.Max(0, CctvModuleConfig.StashExtraAmmoRolls?.Value ?? 0); if (num == 0) { return; } List list = ParseAmmoLootEntries(CctvModuleConfig.StashAmmoItems?.Value); if (list.Count == 0) { ManualLogSource log = CctvModuleConfig.Log; if (log != null) { log.LogInfo((object)$"[MoonContracts] Company Stash '{DisplayName}' has no valid ammo loot entries; skipping {num} extra roll(s)."); } return; } int num2 = 1; for (int i = 0; i < num; i++) { AmmoLootEntry ammoLootEntry = PickWeightedAmmoLootEntry(list); if (ammoLootEntry == null) { continue; } Item val = ResolveAmmoLootItem(ammoLootEntry.ItemName); if ((Object)(object)val == (Object)null) { ManualLogSource log2 = CctvModuleConfig.Log; if (log2 != null) { log2.LogInfo((object)$"[MoonContracts] Company Stash '{DisplayName}' skipped ammo loot roll {i + 1}/{num}: item '{ammoLootEntry.ItemName}' was not found or is not network-spawnable."); } continue; } int num3 = 0; for (int j = 0; j < ammoLootEntry.Count; j++) { GameObject obj = SpawnStashLootItem(val, num2); num2++; if ((Object)(object)((obj != null) ? obj.GetComponent() : null) != (Object)null) { num3++; } } ManualLogSource log3 = CctvModuleConfig.Log; if (log3 != null) { log3.LogInfo((object)$"[MoonContracts] Company Stash '{DisplayName}' spawned {num3}x '{val.itemName}' ammo loot for roll {i + 1}/{num}."); } } } private GameObject SpawnStashLootItem(Item item, int lateralOffsetIndex) { //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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_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) if ((Object)(object)item?.spawnPrefab == (Object)null) { return null; } Vector3 val = ResolveLootSpawnPosition(lateralOffsetIndex); Quaternion val2 = ResolveLootSpawnRotation(); Transform val3 = StartOfRound.Instance?.propsContainer; GameObject val4 = Object.Instantiate(item.spawnPrefab, val, val2, val3); if ((Object)(object)val4 == (Object)null) { return null; } if (!val4.activeSelf) { val4.SetActive(true); } val4.transform.SetPositionAndRotation(val, val2); PrepareStashLoot(val4, item); NetworkObject component = val4.GetComponent(); if ((Object)(object)component != (Object)null && !component.IsSpawned) { component.Spawn(false); if ((Object)(object)val3 != (Object)null) { component.TrySetParent(val3, true); } } return val4; } private Vector3 ResolveLootSpawnPosition(int lateralOffsetIndex) { //IL_0006: 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_0015: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)this).transform.TransformPoint(GoldBarStableRootLocalPosition); if (lateralOffsetIndex <= 0) { return val; } int num = (lateralOffsetIndex + 1) / 2; float num2 = ((lateralOffsetIndex % 2 == 0) ? (-1f) : 1f); return val + ((Component)this).transform.right * (0.25f * (float)num * num2); } private Quaternion ResolveLootSpawnRotation() { //IL_0006: 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_001f: Unknown result type (might be due to invalid IL or missing references) return ((Component)this).transform.rotation * Quaternion.Euler(0f, 90f, 0f); } private static void PrepareStashLoot(GameObject spawned, Item item) { //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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)spawned == (Object)null || (Object)(object)item == (Object)null) { return; } GrabbableObject component = spawned.GetComponent(); if (!((Object)(object)component == (Object)null)) { component.itemProperties = item; component.isInFactory = true; component.fallTime = 0f; component.hasHitGround = true; component.reachedFloorTarget = true; component.startFallingPosition = spawned.transform.localPosition; component.targetFloorPosition = spawned.transform.localPosition; component.isHeld = false; component.isPocketed = false; component.heldByPlayerOnServer = false; component.playerHeldBy = null; Rigidbody val = (((Object)(object)component.propBody != (Object)null) ? component.propBody : spawned.GetComponent()); if ((Object)(object)val != (Object)null) { val.velocity = Vector3.zero; val.angularVelocity = Vector3.zero; val.useGravity = false; val.isKinematic = true; val.constraints = (RigidbodyConstraints)112; } if (item.isScrap && (item.minValue > 0 || item.maxValue > 0)) { int num = Mathf.Max(50, item.minValue); int num2 = Mathf.Max(num + 15, item.maxValue); int scrapValue = Mathf.RoundToInt((float)Random.Range(num, num2) * Mathf.Max(1f, ((Object)(object)RoundManager.Instance != (Object)null) ? RoundManager.Instance.scrapValueMultiplier : 1f)); component.SetScrapValue(scrapValue); AddLootScrapValueToLevel(component.scrapValue); } } } private static void AddLootScrapValueToLevel(int value) { if ((Object)(object)RoundManager.Instance != (Object)null) { RoundManager instance = RoundManager.Instance; instance.totalScrapValueInLevel += (float)Mathf.Max(0, value); } } private static Item ResolveGoldBarItem() { List list = StartOfRound.Instance?.allItemsList?.itemsList; if (list == null || list.Count == 0) { return null; } Item val = null; for (int i = 0; i < list.Count; i++) { Item val2 = list[i]; if (IsSpawnableScrapItem(val2)) { if (string.Equals(val2.itemName, "Gold bar", StringComparison.OrdinalIgnoreCase) || string.Equals(val2.itemName, "GoldBar", StringComparison.OrdinalIgnoreCase)) { return val2; } if ((Object)(object)val == (Object)null && Contains(val2.itemName, "gold") && Contains(val2.itemName, "bar")) { val = val2; } } } return val; } private List ParseAmmoLootEntries(string configuredItems) { List list = new List(); if (string.IsNullOrWhiteSpace(configuredItems)) { return list; } string[] array = configuredItems.Split(';'); for (int i = 0; i < array.Length; i++) { string text = array[i]?.Trim(); if (string.IsNullOrWhiteSpace(text)) { continue; } string[] array2 = text.Split('|'); if (array2.Length != 3 || string.IsNullOrWhiteSpace(array2[0]) || !int.TryParse(array2[1].Trim(), out var result) || result <= 0 || !int.TryParse(array2[2].Trim(), out var result2) || result2 <= 0) { ManualLogSource log = CctvModuleConfig.Log; if (log != null) { log.LogWarning((object)("[MoonContracts] Company Stash '" + DisplayName + "' ignored malformed ammo loot entry '" + text + "'; expected name|positive weight|positive count.")); } } else { list.Add(new AmmoLootEntry(array2[0].Trim(), result, result2)); } } return list; } private static AmmoLootEntry PickWeightedAmmoLootEntry(List entries) { if (entries == null || entries.Count == 0) { return null; } long num = 0L; for (int i = 0; i < entries.Count; i++) { num += entries[i].Weight; } if (num <= 0) { return null; } double num2 = Random.value * (float)num; long num3 = 0L; for (int j = 0; j < entries.Count; j++) { num3 += entries[j].Weight; if (num2 < (double)num3) { return entries[j]; } } return entries[entries.Count - 1]; } private static Item ResolveAmmoLootItem(string itemName) { List list = StartOfRound.Instance?.allItemsList?.itemsList; if (list == null || list.Count == 0 || string.IsNullOrWhiteSpace(itemName)) { return null; } for (int i = 0; i < list.Count; i++) { Item val = list[i]; if (IsSpawnableStashLootItem(val) && string.Equals(val.itemName, itemName, StringComparison.OrdinalIgnoreCase)) { return val; } } return null; } private static bool IsSpawnableScrapItem(Item item) { if ((Object)(object)item != (Object)null && item.isScrap && (Object)(object)item.spawnPrefab != (Object)null) { return (Object)(object)item.spawnPrefab.GetComponent() != (Object)null; } return false; } private static bool IsSpawnableStashLootItem(Item item) { if ((Object)(object)item != (Object)null && (Object)(object)item.spawnPrefab != (Object)null && (Object)(object)item.spawnPrefab.GetComponent() != (Object)null) { return (Object)(object)item.spawnPrefab.GetComponent() != (Object)null; } return false; } private static bool Contains(string value, string fragment) { if (!string.IsNullOrEmpty(value)) { return value.IndexOf(fragment, StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private void EnsureScanNodes() { //IL_0033: 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) EnsureScanNode(((Component)this).transform, "CompanyStashScanNode", "Company Stash", IsUnlocked ? "access granted" : "secured", new Vector3(0f, 1.05f, 0f), 0.52f, 32); EnsureScanNode(((Object)(object)_keypadVisualRoot != (Object)null) ? _keypadVisualRoot : (((Object)(object)_keypad != (Object)null && (Object)(object)((Component)_keypad).transform != (Object)(object)((Component)this).transform) ? ((Component)_keypad).transform : ((Component)this).transform), "CompanyStashKeypadScanNode", "Keypad", IsUnlocked ? "granted" : "locked", Vector3.zero, 0.22f, 18); } private void UpdateLockerScanNode() { ScanNodeProperties[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); foreach (ScanNodeProperties val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { if (string.Equals(val.headerText, "Company Stash", StringComparison.OrdinalIgnoreCase)) { val.subText = (IsUnlocked ? "access granted" : "secured"); } else if (string.Equals(val.headerText, "Keypad", StringComparison.OrdinalIgnoreCase)) { val.subText = (IsUnlocked ? "granted" : "locked"); } } } } private static void EnsureScanNode(Transform parent, string name, string header, string subText, Vector3 localPosition, float radius, int maxRange) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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) if (!((Object)(object)parent == (Object)null)) { Transform val = parent.Find(name); GameObject val2 = (GameObject)(((Object)(object)val != (Object)null) ? ((object)((Component)val).gameObject) : ((object)new GameObject(name))); val2.transform.SetParent(parent, false); val2.transform.localPosition = localPosition; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = Vector3.one; val2.layer = ResolveLayer("ScanNode", 22); SphereCollider val3 = val2.GetComponent(); if ((Object)(object)val3 == (Object)null) { val3 = val2.AddComponent(); } ((Collider)val3).enabled = true; ((Collider)val3).isTrigger = true; val3.center = Vector3.zero; val3.radius = Mathf.Max(0.1f, radius); ScanNodeProperties val4 = val2.GetComponent(); if ((Object)(object)val4 == (Object)null) { val4 = val2.AddComponent(); } val4.headerText = header; val4.subText = subText; val4.minRange = 1; val4.maxRange = Mathf.Max(1, maxRange); val4.requiresLineOfSight = false; val4.nodeType = 0; val4.creatureScanID = -1; val4.scrapValue = 0; } } private void StartOpenVisualLocal() { if (_openVisualStarted) { return; } _openVisualStarted = true; if (TryPlayAuthoredOpenAnimation()) { return; } CaptureDoorRotations(); if (!((Object)(object)_leftDoor == (Object)null) || !((Object)(object)_rightDoor == (Object)null)) { _fallbackOpening = true; _fallbackOpenProgress = 0f; ManualLogSource log = CctvModuleConfig.Log; if (log != null) { log.LogInfo((object)("[MoonContracts] Company Stash '" + DisplayName + "' opening doors with fallback animation left=" + (((Object)(object)_leftDoor != (Object)null) ? ((Object)_leftDoor).name : "none") + " right=" + (((Object)(object)_rightDoor != (Object)null) ? ((Object)_rightDoor).name : "none") + ".")); } } } private bool TryPlayAuthoredOpenAnimation() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown if ((Object)(object)_legacyAnimation != (Object)null && !IsKeypadDescendant(((Component)_legacyAnimation).transform)) { ((Behaviour)_legacyAnimation).enabled = true; _legacyAnimation.cullingType = (AnimationCullingType)0; AnimationState val = null; int num = int.MinValue; foreach (AnimationState item in _legacyAnimation) { AnimationState val2 = item; if (!((TrackedReference)(object)val2 == (TrackedReference)null)) { int num2 = ScoreOpenAnimationState(val2); if ((TrackedReference)(object)val == (TrackedReference)null || num2 > num) { val = val2; num = num2; } } } if ((TrackedReference)(object)val != (TrackedReference)null) { val.wrapMode = (WrapMode)1; val.time = 0f; val.speed = 1f; _legacyAnimation.clip = val.clip; _legacyAnimation.Play(val.name, (PlayMode)4); return true; } } if ((Object)(object)_animator != (Object)null && !IsKeypadDescendant(((Component)_animator).transform) && (Object)(object)_animator.runtimeAnimatorController != (Object)null) { if (AnimatorHasTrigger(_animator, "Open")) { ((Behaviour)_animator).enabled = true; _animator.SetTrigger("Open"); return true; } if (AnimatorHasBool(_animator, "Open")) { ((Behaviour)_animator).enabled = true; _animator.SetBool("Open", true); return true; } } return false; } private void MountKeypadToDoor() { //IL_0077: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) if (_keypadMounted) { return; } Transform val = (((Object)(object)_rightDoor != (Object)null) ? _rightDoor : _leftDoor); if ((Object)(object)val == (Object)null) { return; } if ((Object)(object)_keypadVisualRoot == (Object)null) { _keypadVisualRoot = FindKeypadVisualRoot(); } Transform keypadVisualRoot = _keypadVisualRoot; if (!((Object)(object)keypadVisualRoot == (Object)null) && !((Object)(object)keypadVisualRoot == (Object)(object)((Component)this).transform)) { keypadVisualRoot.SetParent(((Component)this).transform, false); keypadVisualRoot.localPosition = KeypadMountedRootLocalPosition; keypadVisualRoot.localRotation = Quaternion.Euler(0f, 180f, 0f); keypadVisualRoot.localScale = Vector3.one * 0.72f; keypadVisualRoot.SetParent(val, true); _keypadMounted = true; ManualLogSource log = CctvModuleConfig.Log; if (log != null) { log.LogInfo((object)("[MoonContracts] Company Stash '" + DisplayName + "' mounted keypad visual '" + ((Object)keypadVisualRoot).name + "' on door '" + ((Object)val).name + "'.")); } } } private T FindComponentOutsideKeypad() where T : Component { T[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); foreach (T val in componentsInChildren) { if ((Object)(object)val != (Object)null && !IsKeypadDescendant(((Component)val).transform)) { return val; } } return default(T); } private bool IsKeypadDescendant(Transform candidate) { Transform val = (((Object)(object)_keypadVisualRoot != (Object)null) ? _keypadVisualRoot : (((Object)(object)_keypad != (Object)null && (Object)(object)((Component)_keypad).transform != (Object)(object)((Component)this).transform) ? ((Component)_keypad).transform : null)); if ((Object)(object)val != (Object)null && (Object)(object)candidate != (Object)null) { if (!((Object)(object)candidate == (Object)(object)val)) { return candidate.IsChildOf(val); } return true; } return false; } private void CaptureDoorRotations() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) if (!_capturedDoorRotations) { if ((Object)(object)_leftDoor != (Object)null) { _leftClosedRotation = _leftDoor.localRotation; } if ((Object)(object)_rightDoor != (Object)null) { _rightClosedRotation = _rightDoor.localRotation; } _capturedDoorRotations = (Object)(object)_leftDoor != (Object)null || (Object)(object)_rightDoor != (Object)null; } } private void UpdateFallbackOpenAnimation() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_007a: 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_009f: 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_00b8: 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) if (_fallbackOpening) { _fallbackOpenProgress = Mathf.MoveTowards(_fallbackOpenProgress, 1f, Time.deltaTime / 1.1f); float num = Mathf.SmoothStep(0f, 1f, _fallbackOpenProgress); if ((Object)(object)_leftDoor != (Object)null) { _leftDoor.localRotation = Quaternion.Slerp(_leftClosedRotation, _leftClosedRotation * Quaternion.Euler(0f, 92f, 0f), num); } if ((Object)(object)_rightDoor != (Object)null) { _rightDoor.localRotation = Quaternion.Slerp(_rightClosedRotation, _rightClosedRotation * Quaternion.Euler(0f, -92f, 0f), num); } if (_fallbackOpenProgress >= 0.999f) { _fallbackOpening = false; } } } private bool IsSenderCloseEnough(ulong senderClientId) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = FindPlayer(senderClientId); if ((Object)(object)val == (Object)null) { return false; } return Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position) <= 4f; } private bool IsSenderWithinRemoteHackRange(ulong senderClientId) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = FindPlayer(senderClientId); if ((Object)(object)val == (Object)null) { return false; } return Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position) <= 20f; } private static PlayerControllerB FindPlayer(ulong senderClientId) { PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null) { return null; } foreach (PlayerControllerB val in array) { if ((Object)(object)val != (Object)null && val.actualClientId == senderClientId) { return val; } } return null; } private static int ScoreOpenAnimationState(AnimationState state) { string text = ((((state != null) ? state.name : null) ?? string.Empty) + " " + (((Object)(object)((state != null) ? state.clip : null) != (Object)null) ? ((Object)state.clip).name : string.Empty)).ToLowerInvariant(); int num = 0; if (text.Contains("open")) { num += 16; } if (text.Contains("door")) { num += 10; } if (text.Contains("cabinet") || text.Contains("stash") || text.Contains("loop")) { num += 3; } return num; } private static bool AnimatorHasTrigger(Animator animator, string name) { return AnimatorHasParameter(animator, name, (AnimatorControllerParameterType)9); } private static bool AnimatorHasBool(Animator animator, string name) { return AnimatorHasParameter(animator, name, (AnimatorControllerParameterType)4); } private static bool AnimatorHasParameter(Animator animator, string name, AnimatorControllerParameterType type) { //IL_0013: 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) try { AnimatorControllerParameter[] parameters = animator.parameters; foreach (AnimatorControllerParameter val in parameters) { if (val != null && val.type == type && string.Equals(val.name, name, StringComparison.Ordinal)) { return true; } } } catch { return false; } return false; } private static Transform FindChildByNameToken(Transform root, string token) { if ((Object)(object)root == (Object)null || string.IsNullOrWhiteSpace(token)) { return null; } if (((Object)root).name.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindChildByNameToken(root.GetChild(i), token); if ((Object)(object)val != (Object)null) { return val; } } return null; } private Transform FindDoorTransform(bool rightDoor) { //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) string[] exactNames = ((!rightDoor) ? new string[4] { "door-l", "door_l", "leftdoor", "doorleft" } : new string[4] { "door-r", "door_r", "rightdoor", "doorright" }); Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); Transform val = null; int num = int.MinValue; foreach (Transform val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || (Object)(object)val2 == (Object)(object)((Component)this).transform) { continue; } int num2 = ScoreDoorName(((Object)val2).name, exactNames); if (num2 > 0) { int num3 = num2; if (BuildTransformPath(val2).Replace('\\', '/').IndexOf("/skeleton/", StringComparison.OrdinalIgnoreCase) >= 0) { num3 += 80; } num3 = ((!((Object)(object)((Component)val2).GetComponent() == (Object)null)) ? (num3 - 30) : (num3 + 40)); Vector3 localScale = val2.localScale; num3 = ((!(((Vector3)(ref localScale)).sqrMagnitude < 10f)) ? (num3 - 20) : (num3 + 10)); if (val2.childCount > 0) { num3 += 5; } if ((Object)(object)val == (Object)null || num3 > num) { val = val2; num = num3; } } } return val; } private Transform FindKeypadVisualRoot() { Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); Transform val = null; int num = int.MinValue; foreach (Transform val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || (Object)(object)val2 == (Object)(object)((Component)this).transform) { continue; } string text = BuildTransformPath(val2); if (text.IndexOf("ScanNode", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Interact", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Trigger", StringComparison.OrdinalIgnoreCase) < 0) { int num2 = ScoreKeypadVisualRoot(val2); if (num2 > 0 && ((Object)(object)val == (Object)null || num2 > num)) { val = val2; num = num2; } } } return val; } private static int ScoreKeypadVisualRoot(Transform candidate) { string text = ((Object)candidate).name ?? string.Empty; int num = 0; if (string.Equals(text, "Keypad", StringComparison.OrdinalIgnoreCase)) { num += 100; } else if (text.IndexOf("keypad", StringComparison.OrdinalIgnoreCase) >= 0) { num += 40; } Renderer[] componentsInChildren = ((Component)candidate).GetComponentsInChildren(true); if (componentsInChildren != null && componentsInChildren.Length != 0) { num += 20; } if ((Object)(object)FindChildByExactName(candidate, "bttn9") != (Object)null) { num += 30; } if ((Object)(object)FindChildByExactName(candidate, "bttnEnter") != (Object)null) { num += 30; } if (BuildTransformPath(candidate).IndexOf("/door", StringComparison.OrdinalIgnoreCase) >= 0) { num += 10; } return num; } private static Transform FindChildByExactName(Transform root, string name) { if ((Object)(object)root == (Object)null || string.IsNullOrWhiteSpace(name)) { return null; } if (string.Equals(((Object)root).name, name, StringComparison.OrdinalIgnoreCase)) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindChildByExactName(root.GetChild(i), name); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static int ScoreDoorName(string name, string[] exactNames) { if (string.IsNullOrWhiteSpace(name)) { return 0; } for (int i = 0; i < exactNames.Length; i++) { if (string.Equals(name, exactNames[i], StringComparison.OrdinalIgnoreCase)) { return 100; } } string text = name.Replace("_", string.Empty).Replace("-", string.Empty); for (int j = 0; j < exactNames.Length; j++) { string value = exactNames[j].Replace("_", string.Empty).Replace("-", string.Empty); if (text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return 35; } } return 0; } private static string BuildTransformPath(Transform transform) { if ((Object)(object)transform == (Object)null) { return string.Empty; } string text = ((Object)transform).name; Transform parent = transform.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private static int ResolveLayer(string name, int fallback) { int num = LayerMask.NameToLayer(name); if (num < 0) { return fallback; } return num; } protected override void __initializeVariables() { if (_isUnlocked == null) { throw new Exception("CompanyStashController._isUnlocked cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_isUnlocked).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_isUnlocked, "_isUnlocked"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)_isUnlocked); ((NetworkBehaviour)this).__initializeVariables(); } protected override void __initializeRpcs() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown ((NetworkBehaviour)this).__registerRpc(251010402u, new RpcReceiveHandler(__rpc_handler_251010402), "SubmitCodeServerRpc"); ((NetworkBehaviour)this).__registerRpc(4141495960u, new RpcReceiveHandler(__rpc_handler_4141495960), "UnlockFromRemoteHackServerRpc"); ((NetworkBehaviour)this).__registerRpc(2540321899u, new RpcReceiveHandler(__rpc_handler_2540321899), "SendKeypadResultClientRpc"); ((NetworkBehaviour)this).__initializeRpcs(); } private static void __rpc_handler_251010402(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) //IL_0036: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int code = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref code); ServerRpcParams server = rpcParams.Server; target.__rpc_exec_stage = (__RpcExecStage)1; ((CompanyStashController)(object)target).SubmitCodeServerRpc(code, server); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_4141495960(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_003e: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ServerRpcParams server = rpcParams.Server; target.__rpc_exec_stage = (__RpcExecStage)1; ((CompanyStashController)(object)target).UnlockFromRemoteHackServerRpc(server); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2540321899(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002f: 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_004a: 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_0076: 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) //IL_0086: 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_00a8: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { bool granted = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref granted, default(ForPrimitives)); bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag, default(ForPrimitives)); string message = null; if (flag) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref message, false); } ClientRpcParams client = rpcParams.Client; target.__rpc_exec_stage = (__RpcExecStage)1; ((CompanyStashController)(object)target).SendKeypadResultClientRpc(granted, message, client); target.__rpc_exec_stage = (__RpcExecStage)0; } } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "CompanyStashController"; } } public sealed class MiniVault : NetworkBehaviour { public const int CodeDigits = 4; public const int MaxAttemptsPerPlayer = 4; private NetworkVariable _assignedCode = new NetworkVariable(-1, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private NetworkVariable _isUnlocked = new NetworkVariable(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private NetworkVariable _globalAttempts = new NetworkVariable(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private string _displayName = "VAULT"; public int AssignedCode => _assignedCode.Value; public bool IsUnlocked => _isUnlocked.Value; public int GlobalAttempts => _globalAttempts.Value; public string DisplayName { get { if (!string.IsNullOrWhiteSpace(_displayName)) { return _displayName; } return $"VAULT {((Object)this).GetInstanceID():X}"; } } public void InitializeAssignedCode(int code, string displayName) { if (code >= 0) { _assignedCode.Value = code; } if (!string.IsNullOrWhiteSpace(displayName)) { _displayName = displayName; } } public override void OnNetworkSpawn() { ((NetworkBehaviour)this).OnNetworkSpawn(); if (((NetworkBehaviour)this).IsServer && _assignedCode.Value < 0) { int[] hiddenVaultCodes = CctvSupportState.HiddenVaultCodes; if (hiddenVaultCodes != null && hiddenVaultCodes.Length != 0) { Random random = new Random(((Object)this).GetInstanceID() ^ Environment.TickCount); _assignedCode.Value = hiddenVaultCodes[random.Next(0, hiddenVaultCodes.Length)]; } } } public bool TrySubmitCodeLocally(int code, out string statusText) { if (!IsUnlocked && _assignedCode.Value == code) { statusText = "UNLOCKED"; return true; } statusText = "DENIED"; return false; } [ServerRpc(RequireOwnership = false)] public void SubmitCodeServerRpc(int code, ServerRpcParams rpcParams = default(ServerRpcParams)) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(3596717830u, rpcParams, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, code); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 3596717830u, rpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost)) { return; } base.__rpc_exec_stage = (__RpcExecStage)0; if (((NetworkBehaviour)this).IsServer && !_isUnlocked.Value) { NetworkVariable globalAttempts = _globalAttempts; int value = globalAttempts.Value; globalAttempts.Value = value + 1; if (_assignedCode.Value == code) { _isUnlocked.Value = true; OpenVault(); } } } private void OpenVault() { ManualLogSource log = CctvModuleConfig.Log; if (log != null) { log.LogInfo((object)$"[MoonContracts] Vault '{DisplayName}' unlocked with code {_assignedCode.Value:D4} after {_globalAttempts.Value} attempts."); } Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } } protected override void __initializeVariables() { if (_assignedCode == null) { throw new Exception("MiniVault._assignedCode cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_assignedCode).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_assignedCode, "_assignedCode"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)_assignedCode); if (_isUnlocked == null) { throw new Exception("MiniVault._isUnlocked cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_isUnlocked).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_isUnlocked, "_isUnlocked"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)_isUnlocked); if (_globalAttempts == null) { throw new Exception("MiniVault._globalAttempts cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_globalAttempts).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_globalAttempts, "_globalAttempts"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)_globalAttempts); ((NetworkBehaviour)this).__initializeVariables(); } protected override void __initializeRpcs() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ((NetworkBehaviour)this).__registerRpc(3596717830u, new RpcReceiveHandler(__rpc_handler_3596717830), "SubmitCodeServerRpc"); ((NetworkBehaviour)this).__initializeRpcs(); } private static void __rpc_handler_3596717830(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) //IL_0036: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int code = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref code); ServerRpcParams server = rpcParams.Server; target.__rpc_exec_stage = (__RpcExecStage)1; ((MiniVault)(object)target).SubmitCodeServerRpc(code, server); target.__rpc_exec_stage = (__RpcExecStage)0; } } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "MiniVault"; } } public sealed class VaultInteractor : MonoBehaviour { public MiniVault Vault; public string DisplayName = "VAULT"; public float InteractRadius = 2.4f; private Transform _localPlayerTransform; private bool _isPlayerInRange; private bool _promptApplied; private string _capturedControlTip = string.Empty; private void Update() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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) if ((Object)(object)Vault == (Object)null) { SetControlPromptVisible(visible: false); return; } if ((Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null) { SetControlPromptVisible(visible: false); return; } Transform transform = ((Component)GameNetworkManager.Instance.localPlayerController).transform; if (!((Object)(object)transform == (Object)null)) { _localPlayerTransform = transform; Vector3 val = transform.position - ((Component)this).transform.position; bool flag = ((Vector3)(ref val)).sqrMagnitude <= InteractRadius * InteractRadius; if (flag != _isPlayerInRange) { _isPlayerInRange = flag; SetControlPromptVisible(_isPlayerInRange && !Vault.IsUnlocked); } else if (_isPlayerInRange) { SetControlPromptVisible(!Vault.IsUnlocked); } if (_isPlayerInRange && Keyboard.current != null && ((ButtonControl)Keyboard.current.eKey).wasPressedThisFrame) { OpenKeypadForLocalPlayer(); } } } public void OnLocalInteract() { OpenKeypadForLocalPlayer(); } private void OnDisable() { SetControlPromptVisible(visible: false); _isPlayerInRange = false; } private void SetControlPromptVisible(bool visible) { HUDManager instance = HUDManager.Instance; if ((Object)(object)instance == (Object)null || instance.controlTipLines == null || instance.controlTipLines.Length == 0 || (Object)(object)instance.controlTipLines[0] == (Object)null) { return; } if (visible) { if (!_promptApplied) { _capturedControlTip = ((TMP_Text)instance.controlTipLines[0]).text ?? string.Empty; _promptApplied = true; } ((TMP_Text)instance.controlTipLines[0]).text = "Open keypad : [E]"; } else if (_promptApplied) { ((TMP_Text)instance.controlTipLines[0]).text = _capturedControlTip; _capturedControlTip = string.Empty; _promptApplied = false; } } private void OpenKeypadForLocalPlayer() { if (!((Object)(object)Vault == (Object)null) && !Vault.IsUnlocked) { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if (!((Object)(object)val == (Object)null)) { SetControlPromptVisible(visible: false); VaultKeypadOverlay.EnsureInstance(((Component)val).transform).Open((NetworkBehaviour)(object)Vault, DisplayName); } } } } public sealed class VaultKeypadOverlay { public const int CodeDigits = 4; private static VaultKeypadOverlay _instance; private readonly Transform _parent; private GameObject _root; private TextMeshProUGUI _titleText; private TextMeshProUGUI _displayText; private TextMeshProUGUI _feedbackText; private TextMeshProUGUI _helpText; private readonly Button[] _digitButtons = (Button[])(object)new Button[10]; private Button _clearButton; private Button _submitButton; private Button _closeButton; private NetworkBehaviour _activeVault; private readonly int[] _entered = new int[4]; private int _enteredCount; public static VaultKeypadOverlay Instance => _instance; public bool IsOpen { get { if ((Object)(object)_root != (Object)null) { return _root.activeSelf; } return false; } } private VaultKeypadOverlay(Transform parent) { _parent = parent; } public static VaultKeypadOverlay EnsureInstance(Transform parent) { if (_instance != null) { return _instance; } _instance = new VaultKeypadOverlay(parent); _instance.EnsureBuilt(); return _instance; } public static void ResetInstance() { if (_instance != null && (Object)(object)_instance._root != (Object)null) { Object.Destroy((Object)(object)_instance._root); } _instance = null; } private void EnsureBuilt() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root != (Object)null)) { _root = new GameObject("LGU_VaultKeypadOverlay"); _root.transform.SetParent(_parent, false); Canvas obj = _root.AddComponent(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 110; CanvasScaler obj2 = _root.AddComponent(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.matchWidthOrHeight = 0.5f; Image obj3 = ((Component)NewRect(_root.transform, "Backdrop", Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f))).gameObject.AddComponent(); ((Graphic)obj3).color = new Color(0.01f, 0.02f, 0.03f, 0.78f); ((Graphic)obj3).raycastTarget = false; RectTransform val = NewRect(_root.transform, "Panel", Vector2.zero, Vector2.zero, new Vector2(0.5f, 0.5f)); val.sizeDelta = new Vector2(440f, 600f); val.anchoredPosition = Vector2.zero; Image obj4 = ((Component)val).gameObject.AddComponent(); ((Graphic)obj4).color = new Color(0.04f, 0.08f, 0.1f, 0.96f); ((Graphic)obj4).raycastTarget = true; _titleText = NewText((Transform)(object)val, "Title", "VAULT KEYPAD", 22f, (TextAlignmentOptions)514, new Color(0.2f, 1f, 0.4f, 1f), new Vector2(16f, -560f), new Vector2(-16f, -16f)); _displayText = NewText((Transform)(object)val, "Display", "_ _ _ _", 36f, (TextAlignmentOptions)514, Color.white, new Vector2(16f, -440f), new Vector2(-16f, -350f)); _feedbackText = NewText((Transform)(object)val, "Feedback", "ENTER 4 DIGITS", 16f, (TextAlignmentOptions)514, new Color(0.7f, 0.7f, 0.7f, 1f), new Vector2(16f, -350f), new Vector2(-16f, -300f)); BuildDigitGrid((Transform)(object)val); _helpText = NewText((Transform)(object)val, "Help", "1-9 / 0 ENTERS DIGIT CLEAR RESETS SUBMIT TRIES", 13f, (TextAlignmentOptions)514, new Color(0.6f, 0.6f, 0.6f, 1f), new Vector2(16f, 18f), new Vector2(-16f, 8f)); _root.SetActive(false); } } private void BuildDigitGrid(Transform parent) { //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0199: 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_01d3: 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_00bc: Unknown result type (might be due to invalid IL or missing references) float num = 70f; float num2 = 8f; float num3 = (0f - (num * 3f + num2 * 2f)) * 0.5f + num * 0.5f; float num4 = -300f; int digit; for (digit = 0; digit < 10; digit++) { int num5; int num6; if (digit == 0) { num5 = 3; num6 = 1; } else { int num7 = digit - 1; num5 = num7 / 3; num6 = num7 % 3; } float num8 = num3 + (float)num6 * (num + num2); float num9 = num4 - (float)num5 * (num + num2); _digitButtons[digit] = CreateButton(parent, $"Digit_{digit}", digit.ToString(), new Vector2(num, num), new Vector2(num8, num9), delegate { OnDigitPressed(digit); }); } float num10 = 120f; float num11 = 38f; float num12 = num4 - 4f * (num + num2) - 6f; float num13 = 0f - (num10 + num2) * 2.5f + num10 * 0.5f; _clearButton = CreateButton(parent, "Clear", "CLEAR", new Vector2(num10, num11), new Vector2(num13, num12), OnClearPressed); _submitButton = CreateButton(parent, "Submit", "SUBMIT", new Vector2(num10, num11), new Vector2(num13 + (num10 + num2) * 2f, num12), OnSubmitPressed); _closeButton = CreateButton(parent, "Close", "CLOSE", new Vector2(num10, num11), new Vector2(num13 + (num10 + num2), num12), OnClosePressed); } private Button CreateButton(Transform parent, string name, string label, Vector2 size, Vector2 anchoredPosition, Action onClick) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0033: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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_013c: Expected O, but got Unknown //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: 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_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016a: 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_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 1f); obj.anchorMax = new Vector2(0.5f, 1f); obj.pivot = new Vector2(0.5f, 1f); obj.sizeDelta = size; obj.anchoredPosition = anchoredPosition; Image val2 = val.AddComponent(); ((Graphic)val2).color = new Color(0.1f, 0.2f, 0.18f, 0.96f); Button obj2 = val.AddComponent