Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CrewMonitors v1.0.33
CrewMonitors.dll
Decompiled 3 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using OpenBodyCams; using OpenBodyCams.API; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("CrewMonitors")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.33.0")] [assembly: AssemblyInformationalVersion("1.0.33+4c7fb8c0ca25ed457152595237a7b526820834c9")] [assembly: AssemblyProduct("CrewMonitors")] [assembly: AssemblyTitle("CrewMonitors")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.33.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 CrewMonitors { public sealed class CrewMonitorManager : MonoBehaviour { private struct WallPlacement { public int HorizontalAxis; public int VerticalAxis; public int DepthAxis; public float HSign; public float VSign; public float OutwardSign; public float FlushDepth; public Bounds LocalBounds; public bool MaxIsOutward; } private sealed class CrewSlot { public int Index; public GameObject Host; public MeshRenderer Renderer; public BodyCamComponent BodyCam; public Material? OriginalOffMaterial; public bool IsClone; public PlayerControllerB? AssignedPlayer; public int CycleIndex; public bool UserCycled; public bool ShowMapFeed; public Camera? MapFeedCamera; public RenderTexture? MapFeedTexture; public TextMeshPro? Nameplate; public GameObject? CycleButton; public GameObject? FocusTrigger; } private const int CycleOff = -2; private const int CycleExternal = -1; private const string MonitorWallPath = "Environment/HangarShip/ShipModels2b/MonitorWall"; private const string SingleScreenPath = "Environment/HangarShip/ShipModels2b/MonitorWall/SingleScreen"; private const string MainWallCubeName = "Cube.001"; private const string ClonePrefix = "CrewMonitor_Clone_"; private const string SlotRootName = "CrewMonitors_Root"; private const string QuadTemplateName = "CrewMonitors_QuadTemplate"; private const float SingleScreenScaleAtDefaultFactor = 2f; private const float DefaultCloneScaleFactor = 0.6f; private const float MapCameraYOffset = 3.636f; private const float MapCameraNearDefault = -2.47f; private const float MapCameraFarDefault = 7.52f; private static readonly string[] RejectNameTokens = new string[6] { "Button", "Overlay", "Switch", "OnButton", "CameraMonitorOn", "CameraMonitorSwitch" }; private static readonly string[] AxisNames = new string[3] { "X", "Y", "Z" }; private readonly List<CrewSlot> _slots = new List<CrewSlot>(); private Transform? _monitorWall; private Transform? _placementAnchor; private MeshRenderer? _anchorRenderer; private MeshRenderer? _cloneTemplate; private GameObject? _ownedQuadTemplate; private WallPlacement _wallPlacement; private bool _wallPlacementValid; private GameObject? _slotRoot; private bool _setupStarted; private bool _setupComplete; private bool _refreshRequested; private bool _setupSoonRequested; private float _refreshTimer; private float _setupWaitElapsed; private static readonly BindingFlags BodyCamFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static Material? _blackScreenMaterial; private static Sprite? _transparentHoverIcon; internal static CrewMonitorManager? Instance { get; private set; } private void Awake() { Instance = this; } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } TeardownSlots(); if ((Object)(object)_ownedQuadTemplate != (Object)null) { Object.Destroy((Object)(object)_ownedQuadTemplate); _ownedQuadTemplate = null; } } private void Start() { ((MonoBehaviour)this).StartCoroutine(SetupWhenReady()); } private void Update() { if (!Plugin.Enabled.Value) { if (_slots.Count > 0) { PowerDownAll(); } return; } if (_setupSoonRequested && !_setupComplete) { _setupSoonRequested = false; if (!_setupStarted) { ((MonoBehaviour)this).StartCoroutine(SetupWhenReady()); } } if (_setupComplete) { float num = Mathf.Max(0.25f, Plugin.RefreshSeconds.Value); _refreshTimer += Time.deltaTime; if (_refreshRequested || _refreshTimer >= num) { _refreshRequested = false; _refreshTimer = 0f; RefreshAssignments(); } } } private void LateUpdate() { if (!Plugin.Enabled.Value || !_setupComplete) { return; } foreach (CrewSlot slot in _slots) { if ((Object)(object)slot.BodyCam == (Object)null) { continue; } if (slot.ShowMapFeed && (Object)(object)slot.AssignedPlayer != (Object)null) { UpdateMapFeedFollow(slot); ApplyMapFeedTextureToMonitor(slot); continue; } PlayerControllerB val = (((Object)(object)slot.AssignedPlayer != (Object)null && IsLivingPlayer(slot.AssignedPlayer)) ? slot.AssignedPlayer : null); if (!((Object)(object)slot.BodyCam.CurrentPlayerTarget == (Object)(object)val)) { if ((Object)(object)val != (Object)null) { slot.BodyCam.SetTargetToPlayer(val); } else { slot.BodyCam.SetTargetToNone(); } } } } internal void RequestRefresh() { _refreshRequested = true; } internal void RequestSetupSoon() { _setupSoonRequested = true; } private IEnumerator SetupWhenReady() { if (_setupStarted) { yield break; } _setupStarted = true; _setupWaitElapsed = 0f; while (_setupWaitElapsed < 12f) { GameObject val = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall"); bool flag = (Object)(object)BodyCam.MainBodyCam != (Object)null || BodyCamComponent.GetAllBodyCams().Length != 0; if ((Object)(object)val != (Object)null && (flag || _setupWaitElapsed > 3f)) { _monitorWall = val.transform; break; } _setupWaitElapsed += 0.25f; yield return (object)new WaitForSeconds(0.25f); } if ((Object)(object)_monitorWall == (Object)null) { Plugin.Log.LogWarning((object)"MonitorWall not found; crew monitors will not set up."); yield break; } try { BuildSlots(); _setupComplete = true; RefreshAssignments(); Plugin.Log.LogInfo((object)$"Crew monitors ready with {_slots.Count} slot(s)."); } catch (Exception arg) { Plugin.Log.LogError((object)$"Crew monitor setup failed: {arg}"); } } private void BuildSlots() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //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_02e8: 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_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_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_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_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_01a4: 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) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0365: 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) TeardownSlots(); int num = Mathf.Clamp(Plugin.MaxMonitors.Value, 1, 8); _slotRoot = new GameObject("CrewMonitors_Root"); _slotRoot.transform.SetParent(_monitorWall, false); _slotRoot.transform.localPosition = Vector3.zero; _slotRoot.transform.localRotation = Quaternion.identity; _slotRoot.transform.localScale = Vector3.one; ResolvePlacementAnchor(); _wallPlacementValid = TryComputeWallPlacement(out _wallPlacement); List<MeshRenderer> list = CollectReusableRenderers(); EnsureCloneTemplate(list); int num2 = 0; for (int i = 0; i < num; i++) { MeshRenderer renderer = null; bool flag = false; GameObject val; if (i < list.Count) { renderer = list[i]; val = ((Component)renderer).gameObject; } else { if ((Object)(object)_cloneTemplate == (Object)null) { Plugin.Log.LogWarning((object)"No template MeshRenderer available to clone; stopping slot creation."); break; } val = CloneMonitor(num2, out renderer); num2++; flag = true; if ((Object)(object)renderer == (Object)null) { break; } } int num3 = PickMaterialIndex(renderer); IsolateScreenMaterial(renderer, num3); BodyCamComponent val2; try { val2 = BodyCam.CreateBodyCam(val, (Renderer)(object)renderer, num3, (ManualCameraRenderer)null); } catch (Exception ex) { Plugin.Log.LogError((object)$"CreateBodyCam failed for slot {i} on {((Object)val).name}: {ex.Message}"); if (flag) { Object.Destroy((Object)(object)val); } continue; } try { float num4 = 1.3333334f; Bounds localBounds = ((Renderer)renderer).localBounds; Vector3 size = ((Bounds)(ref localBounds)).size; float num5 = Mathf.Max(size.x, Mathf.Max(size.y, size.z)); float num6 = Mathf.Min(size.x, Mathf.Min(size.y, size.z)); if (num5 > 0.001f && num6 > 0.001f) { num4 = Mathf.Clamp(num5 / Mathf.Max(0.001f, num6), 0.5f, 3f); } int num7 = Mathf.Max(90, Mathf.RoundToInt(480f / num4)); val2.Resolution = new Vector2Int(480, num7); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("Set Resolution 480 failed: " + ex2.Message)); } val2.SetTargetToNone(); val2.SetScreenPowered(false); try { val2.UpdateScreenMaterial(); } catch { } ApplyScreenBrightness(val2); CrewSlot crewSlot = new CrewSlot { Index = i, Host = val, Renderer = renderer, BodyCam = val2, IsClone = flag, OriginalOffMaterial = GetMonitorOffMaterial(val2), CycleIndex = -2, UserCycled = false, Nameplate = (Plugin.ShowNameplates.Value ? CreateNameplate(val, renderer) : null) }; _slots.Add(crewSlot); SetupSlotInteractions(crewSlot); Vector3 localPosition = val.transform.localPosition; Vector3 position = val.transform.position; string text = (flag ? "clone" : "reuse"); ManualLogSource log = Plugin.Log; object[] obj2 = new object[4] { i, text, ((Object)val).name, null }; Transform parent = val.transform.parent; obj2[3] = ((parent != null) ? ((Object)parent).name : null) ?? "none"; log.LogInfo((object)(string.Format("Slot {0} ({1}): {2} parent={3} ", obj2) + $"local={localPosition} world={position} path={GetPath(val.transform)}")); } } private void ResolvePlacementAnchor() { //IL_005a: 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_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) _placementAnchor = null; _anchorRenderer = null; if (!((Object)(object)_monitorWall == (Object)null)) { Transform val = _monitorWall.Find("Cube.001"); if ((Object)(object)val != (Object)null) { _placementAnchor = val; _anchorRenderer = ((Component)val).GetComponent<MeshRenderer>(); ManualLogSource log = Plugin.Log; string text = string.Format("Clone placement anchor: {0} localPos={1} ", "Cube.001", val.localPosition); Quaternion localRotation = val.localRotation; log.LogInfo((object)(text + $"localRot={((Quaternion)(ref localRotation)).eulerAngles} localScale={val.localScale}")); } else { _placementAnchor = _monitorWall; _anchorRenderer = ((Component)_monitorWall).GetComponent<MeshRenderer>(); Plugin.Log.LogInfo((object)"Clone placement anchor: MonitorWall origin (no Cube.001 found)"); } } } private bool TryComputeWallPlacement(out WallPlacement wp) { //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_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_005e: 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_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_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_00ba: 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_00d1: 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_00dc: 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_00ed: 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_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_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_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_0148: 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_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_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_01c4: 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_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_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_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_021c: 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_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_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0249: 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_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_02e1: 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_030b: 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) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: 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) wp = default(WallPlacement); if ((Object)(object)_placementAnchor == (Object)null) { return false; } MeshRenderer val = _anchorRenderer ?? ((Component)_placementAnchor).GetComponent<MeshRenderer>(); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"Placement anchor has no MeshRenderer; cannot compute wall bounds/depth."); return false; } Bounds localBounds = ((Renderer)val).localBounds; Vector3 size = ((Bounds)(ref localBounds)).size; int num = 0; if (size.y <= size.x && size.y <= size.z) { num = 1; } else if (size.z <= size.x && size.z <= size.y) { num = 2; } int num2 = (num + 1) % 3; int num3 = (num + 2) % 3; Vector3 val2 = _placementAnchor.TransformDirection(AxisUnit(num2)); Vector3 normalized = ((Vector3)(ref val2)).normalized; val2 = _placementAnchor.TransformDirection(AxisUnit(num3)); Vector3 normalized2 = ((Vector3)(ref val2)).normalized; int num4; int num5; if (Mathf.Abs(Vector3.Dot(normalized, Vector3.up)) >= Mathf.Abs(Vector3.Dot(normalized2, Vector3.up))) { num4 = num2; num5 = num3; } else { num4 = num3; num5 = num2; } val2 = _placementAnchor.TransformDirection(AxisUnit(num5)); Vector3 normalized3 = ((Vector3)(ref val2)).normalized; val2 = _placementAnchor.TransformDirection(AxisUnit(num4)); Vector3 normalized4 = ((Vector3)(ref val2)).normalized; float num6 = ((Vector3.Dot(normalized3, Vector3.right) >= 0f) ? 1f : (-1f)); float num7 = ((Vector3.Dot(normalized4, Vector3.up) >= 0f) ? 1f : (-1f)); Vector3 val3 = _placementAnchor.TransformPoint(((Bounds)(ref localBounds)).center); Vector3 val4 = val3; GameObject val5 = GameObject.Find("Environment/HangarShip"); if ((Object)(object)val5 != (Object)null) { val4 = val5.transform.position; } Vector3 val6 = val4 - val3; if (((Vector3)(ref val6)).sqrMagnitude < 1E-06f) { val6 = (((Object)(object)_monitorWall != (Object)null) ? (-_monitorWall.forward) : Vector3.forward); } ((Vector3)(ref val6)).Normalize(); val2 = _placementAnchor.TransformDirection(AxisUnit(num)); bool flag = Vector3.Dot(((Vector3)(ref val2)).normalized, val6) > 0f; float num8 = (flag ? 1f : (-1f)); val2 = ((Bounds)(ref localBounds)).extents; float num9 = ((Vector3)(ref val2))[num]; val2 = ((Bounds)(ref localBounds)).center; float num10 = ((Vector3)(ref val2))[num] + num8 * num9; float num11 = Mathf.Clamp(Plugin.WallInset.Value, -1f, 1.5f); float num12 = num10 - num8 * num11; wp = new WallPlacement { HorizontalAxis = num5, VerticalAxis = num4, DepthAxis = num, HSign = num6, VSign = num7, OutwardSign = num8, FlushDepth = num12, LocalBounds = localBounds, MaxIsOutward = flag }; Plugin.Log.LogInfo((object)($"Wall placement bounds: center={((Bounds)(ref localBounds)).center} size={size} extents={((Bounds)(ref localBounds)).extents} " + $"depthAxis={AxisNames[num]} (thin) horizAxis={AxisNames[num5]} (sign={num6}) " + $"vertAxis={AxisNames[num4]} (sign={num7}) maxIsOutward={flag} " + $"outwardSign={num8} front={num10} flushDepth={num12} inset={num11} " + $"cabinHint={val4} wallCenterWorld={val3}")); return true; } private static Vector3 AxisUnit(int axis) { //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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) return (Vector3)(axis switch { 0 => Vector3.right, 1 => Vector3.up, _ => Vector3.forward, }); } private List<MeshRenderer> CollectReusableRenderers() { List<MeshRenderer> result = new List<MeshRenderer>(); HashSet<int> claimed = new HashSet<int>(); if (!Plugin.PreferReuseVanillaScreens.Value) { Plugin.Log.LogInfo((object)"PreferReuseVanillaScreens=false; building clone grid only (vanilla door/internal cams left alone)."); return result; } GameObject val = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/SingleScreen"); TryAdd(((Object)(object)val != (Object)null) ? val.GetComponent<MeshRenderer>() : null, "SingleScreen"); StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null) { MeshRenderer val2 = (((Object)(object)instance.insideCameraScreen != (Object)null) ? instance.insideCameraScreen.mesh : null); if ((Object)(object)val2 != (Object)null && ((Object)((Component)val2).gameObject).name != "Cube.001" && !((Object)((Component)val2).gameObject).name.Contains("Cube.001")) { TryAdd(val2, "insideCameraScreen.mesh"); } else if ((Object)(object)val2 != (Object)null) { Plugin.Log.LogDebug((object)("Skipping insideCameraScreen.mesh (" + ((Object)val2).name + "): Cube.001 / main wall.")); } MeshRenderer val3 = (((Object)(object)instance.securityCameraScreen != (Object)null) ? instance.securityCameraScreen.mesh : null); if ((Object)(object)val3 != (Object)null && (((Object)((Component)val3).gameObject).name == "Cube.001" || ((Object)((Component)val3).gameObject).name.Contains("Cube.001"))) { Plugin.Log.LogDebug((object)("Skipping securityCameraScreen.mesh (" + ((Object)val3).name + "): Cube.001 reserved for OBC.")); } else { Plugin.Log.LogDebug((object)"securityCameraScreen not reused (whitelist: SingleScreen + insideCameraScreen only)."); } } return result; void TryAdd(MeshRenderer? mr, string label) { if (!((Object)(object)mr == (Object)null)) { int instanceID = ((Object)mr).GetInstanceID(); if (!claimed.Contains(instanceID)) { if (!IsWhitelistedScreen(mr, out string rejectReason)) { Plugin.Log.LogDebug((object)("Skipping " + label + " (" + ((Object)mr).name + "): " + rejectReason)); } else { claimed.Add(instanceID); result.Add(mr); Plugin.Log.LogInfo((object)("Reusable screen (whitelist): " + label + " -> " + GetPath(((Component)mr).transform))); } } } } } private static bool IsWhitelistedScreen(MeshRenderer mr, out string rejectReason) { rejectReason = "ok"; if (BodyCamComponent.AnyBodyCamHasReference((Renderer)(object)mr)) { rejectReason = "already owned by OpenBodyCams body cam"; return false; } if (((Object)((Component)mr).gameObject).name == "Cube.001" || ((Object)((Component)mr).gameObject).name.Contains("Cube.001")) { rejectReason = "Cube.001 reserved for OBC main panel"; return false; } ManualCameraRenderer val = StartOfRound.Instance?.mapScreen; if ((Object)(object)val != (Object)null && (Object)(object)val.mesh == (Object)(object)mr) { rejectReason = "radar map screen"; return false; } string name = ((Object)((Component)mr).gameObject).name; string[] rejectNameTokens = RejectNameTokens; foreach (string text in rejectNameTokens) { if (name.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0) { rejectReason = "name contains '" + text + "'"; return false; } } if (IsUnderCube001Buttons(((Component)mr).transform)) { rejectReason = "child of Cube.001 button object"; return false; } if (name.IndexOf("Overlay", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("BodyCamOverlay", StringComparison.OrdinalIgnoreCase) >= 0) { rejectReason = "overlay mesh"; return false; } return true; } private static bool IsUnderCube001Buttons(Transform? t) { while ((Object)(object)t != (Object)null) { string name = ((Object)t).name; if (name.IndexOf("CameraMonitorOn", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("CameraMonitorSwitch", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("OnButton", StringComparison.OrdinalIgnoreCase) >= 0 || (name.IndexOf("Button", StringComparison.OrdinalIgnoreCase) >= 0 && (Object)(object)t.parent != (Object)null && (((Object)t.parent).name == "Cube.001" || ((Object)t.parent).name.Contains("Cube.001")))) { return true; } if ((Object)(object)t.parent != (Object)null && (((Object)t.parent).name == "Cube.001" || ((Object)t.parent).name.Contains("Cube.001")) && (name.StartsWith("Cube (", StringComparison.Ordinal) || name.IndexOf("Button", StringComparison.OrdinalIgnoreCase) >= 0)) { return true; } t = t.parent; } return false; } private void EnsureCloneTemplate(List<MeshRenderer> reusable) { //IL_0067: 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_007f: 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) GameObject val = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/SingleScreen"); if ((Object)(object)val != (Object)null) { MeshRenderer component = val.GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null) { _cloneTemplate = component; ManualLogSource log = Plugin.Log; string[] obj = new string[5] { "Clone template: SingleScreen (", GetPath(((Component)component).transform), ") ", null, null }; object arg = ((Component)component).transform.localPosition; Quaternion localRotation = ((Component)component).transform.localRotation; obj[3] = $"localPos={arg} localRot={((Quaternion)(ref localRotation)).eulerAngles} "; object arg2 = ((Component)component).transform.localScale; Material[] sharedMaterials = ((Renderer)component).sharedMaterials; obj[4] = $"localScale={arg2} mats={((sharedMaterials != null) ? sharedMaterials.Length : 0)}"; log.LogInfo((object)string.Concat(obj)); return; } } foreach (MeshRenderer item in reusable) { if (!((Object)(object)item == (Object)null) && !(((Object)((Component)item).gameObject).name == "Cube.001") && !((Object)((Component)item).gameObject).name.Contains("Cube.001")) { _cloneTemplate = item; Plugin.Log.LogInfo((object)("Clone template: reusable " + ((Object)item).name + " (" + GetPath(((Component)item).transform) + ")")); return; } } if ((Object)(object)_monitorWall != (Object)null) { MeshRenderer[] componentsInChildren = ((Component)_monitorWall).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren) { if (!(((Object)((Component)val2).gameObject).name == "Cube.001") && !((Object)((Component)val2).gameObject).name.Contains("Cube.001") && IsWhitelistedScreen(val2, out string _)) { _cloneTemplate = val2; Plugin.Log.LogInfo((object)("Clone template: MonitorWall screen " + ((Object)val2).name + " (" + GetPath(((Component)val2).transform) + ")")); return; } } } _cloneTemplate = CreateQuadTemplate(); if ((Object)(object)_cloneTemplate != (Object)null) { Plugin.Log.LogInfo((object)("Clone template: fallback Quad (" + GetPath(((Component)_cloneTemplate).transform) + ")")); } else { Plugin.Log.LogWarning((object)"No clone template MeshRenderer found (SingleScreen/Quad unavailable)."); } } private MeshRenderer? CreateQuadTemplate() { if ((Object)(object)_ownedQuadTemplate != (Object)null) { MeshRenderer component = _ownedQuadTemplate.GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null) { return component; } } GameObject val = GameObject.CreatePrimitive((PrimitiveType)5); ((Object)val).name = "CrewMonitors_QuadTemplate"; ((Object)val).hideFlags = (HideFlags)61; val.SetActive(false); Collider[] components = val.GetComponents<Collider>(); for (int i = 0; i < components.Length; i++) { Object.Destroy((Object)(object)components[i]); } if ((Object)(object)_monitorWall != (Object)null) { val.transform.SetParent(_monitorWall, false); } _ownedQuadTemplate = val; return val.GetComponent<MeshRenderer>(); } private GameObject CloneMonitor(int slotIndex, out MeshRenderer? renderer) { //IL_016a: 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_017e: 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_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_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_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_02ea: 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_0379: 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_041a: 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_0433: 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_0460: Unknown result type (might be due to invalid IL or missing references) renderer = null; if ((Object)(object)_cloneTemplate == (Object)null || (Object)(object)_monitorWall == (Object)null) { return null; } Transform val = (((Object)(object)_placementAnchor != (Object)null) ? _placementAnchor : _monitorWall); GameObject val2 = Object.Instantiate<GameObject>(((Component)_cloneTemplate).gameObject, val); ((Object)val2).name = string.Format("{0}{1}", "CrewMonitor_Clone_", slotIndex); ((Object)val2).hideFlags = (HideFlags)0; val2.SetActive(true); BodyCamComponent[] componentsInChildren = val2.GetComponentsInChildren<BodyCamComponent>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } SyncBodyCamToRadarMap[] componentsInChildren2 = val2.GetComponentsInChildren<SyncBodyCamToRadarMap>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } ManualCameraRenderer[] componentsInChildren3 = val2.GetComponentsInChildren<ManualCameraRenderer>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[i]); } Collider[] componentsInChildren4 = val2.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { componentsInChildren4[i].enabled = false; } float value = Plugin.CloneSpacing.Value; float num = Mathf.Clamp(Plugin.CloneScaleFactor.Value, 0.1f, 1f); int num2 = Mathf.Clamp(Plugin.GridColumns.Value, 1, 8); int num3 = slotIndex % num2; int num4 = slotIndex / num2; float num5 = num * 3.3333333f; Vector3 localScale = ((Component)_cloneTemplate).transform.localScale * num5; val2.transform.localScale = localScale; Vector3 center = default(Vector3); if (_wallPlacementValid) { WallPlacement wallPlacement = _wallPlacement; float value2 = Plugin.GridHorizontalOffset.Value; float value3 = Plugin.GridVerticalOffset.Value; float num6 = value2 + ((float)num3 - (float)(num2 - 1) * 0.5f) * value; float num7 = value3 + (float)num4 * value * 0.85f; center = ((Bounds)(ref wallPlacement.LocalBounds)).center; int horizontalAxis = wallPlacement.HorizontalAxis; Vector3 center2 = ((Bounds)(ref wallPlacement.LocalBounds)).center; ((Vector3)(ref center))[horizontalAxis] = ((Vector3)(ref center2))[wallPlacement.HorizontalAxis] + wallPlacement.HSign * num6; int verticalAxis = wallPlacement.VerticalAxis; center2 = ((Bounds)(ref wallPlacement.LocalBounds)).center; ((Vector3)(ref center))[verticalAxis] = ((Vector3)(ref center2))[wallPlacement.VerticalAxis] + wallPlacement.VSign * num7; ((Vector3)(ref center))[wallPlacement.DepthAxis] = wallPlacement.FlushDepth; } else { float value4 = Plugin.GridHorizontalOffset.Value; float value5 = Plugin.GridVerticalOffset.Value; int num8 = Mathf.Clamp(Plugin.GridColumns.Value, 1, 8); ((Vector3)(ref center))..ctor(value4 + ((float)num3 - (float)(num8 - 1) * 0.5f) * value, value5 + (float)num4 * value * 0.85f, 0f - Plugin.WallInset.Value); Plugin.Log.LogWarning((object)$"Clone {slotIndex}: wall placement bounds unavailable; using fallback localPos={center}"); } val2.transform.localPosition = center; val2.transform.localRotation = Quaternion.Euler(0f, 0f, Plugin.GridYawDegrees.Value); renderer = val2.GetComponent<MeshRenderer>(); if ((Object)(object)renderer == (Object)null) { renderer = val2.GetComponentInChildren<MeshRenderer>(); } string text = (_wallPlacementValid ? ($"depthAxis={AxisNames[_wallPlacement.DepthAxis]} flushDepth={_wallPlacement.FlushDepth} " + $"boundsCenter={((Bounds)(ref _wallPlacement.LocalBounds)).center} boundsSize={((Bounds)(ref _wallPlacement.LocalBounds)).size} " + $"maxIsOutward={_wallPlacement.MaxIsOutward}") : "depthAxis=n/a"); ManualLogSource log = Plugin.Log; string[] obj = new string[7] { $"Cloned monitor slot {slotIndex}: template={((Object)((Component)_cloneTemplate).gameObject).name} ", $"parent={((Object)val).name} col={num3} row={num4} ", null, null, null, null, null }; object arg = val2.transform.localPosition; Quaternion localRotation = val2.transform.localRotation; obj[2] = $"localPos={arg} localRot={((Quaternion)(ref localRotation)).eulerAngles} "; obj[3] = $"localScale={val2.transform.localScale} worldPos={val2.transform.position} "; obj[4] = $"inset={Plugin.WallInset.Value} scaleFactor={num} panelMul={num5} "; obj[5] = $"spacing={value} xBase={Plugin.GridHorizontalOffset.Value} yBase={Plugin.GridVerticalOffset.Value} yaw={Plugin.GridYawDegrees.Value} "; obj[6] = text; log.LogInfo((object)string.Concat(obj)); return val2; } private static void IsolateScreenMaterial(MeshRenderer renderer, int matIndex) { //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_004d: Expected O, but got Unknown Material[] sharedMaterials = ((Renderer)renderer).sharedMaterials; if (sharedMaterials != null && matIndex >= 0 && matIndex < sharedMaterials.Length && !((Object)(object)sharedMaterials[matIndex] == (Object)null)) { sharedMaterials = (Material[])sharedMaterials.Clone(); Material val = new Material(sharedMaterials[matIndex]) { name = ((Object)sharedMaterials[matIndex]).name + " (CrewSlot)" }; sharedMaterials[matIndex] = val; ((Renderer)renderer).sharedMaterials = sharedMaterials; } } private static int PickMaterialIndex(MeshRenderer renderer) { Material[] sharedMaterials = ((Renderer)renderer).sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { return 0; } string name = ((Object)((Component)renderer).gameObject).name; bool flag = name == "Cube.001" || name.Contains("Cube.001"); int num = ((flag && sharedMaterials.Length > 2) ? 2 : ((sharedMaterials.Length > 1) ? 1 : 0)); Plugin.Log.LogInfo((object)$"PickMaterialIndex({name}): index={num} (mats={sharedMaterials.Length}, isCube001={flag})"); return num; } private TextMeshPro? CreateNameplate(GameObject host, MeshRenderer renderer) { //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_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_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_004c: 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_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_0076: 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_00dd: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject("CrewMonitor_Nameplate"); val.transform.SetParent(host.transform, false); Bounds localBounds = ((Renderer)renderer).localBounds; val.transform.localPosition = new Vector3(0f, ((Bounds)(ref localBounds)).min.y - 0.05f, ((Bounds)(ref localBounds)).center.z); val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one * 0.02f; TextMeshPro val2 = val.AddComponent<TextMeshPro>(); ((TMP_Text)val2).text = ""; ((TMP_Text)val2).alignment = (TextAlignmentOptions)514; ((TMP_Text)val2).fontSize = 36f; ((Graphic)val2).color = new Color(1f, 0.55f, 0.15f, 1f); ((TMP_Text)val2).enableAutoSizing = false; ((TMP_Text)val2).rectTransform.sizeDelta = new Vector2(20f, 4f); StartOfRound instance = StartOfRound.Instance; object obj; if (instance == null) { obj = null; } else { TextMeshProUGUI mapScreenPlayerName = instance.mapScreenPlayerName; obj = ((mapScreenPlayerName != null) ? ((TMP_Text)mapScreenPlayerName).font : null); } TMP_FontAsset val3 = (TMP_FontAsset)obj; if ((Object)(object)val3 != (Object)null) { ((TMP_Text)val2).font = val3; } return val2; } catch (Exception ex) { Plugin.Log.LogWarning((object)("Nameplate create failed: " + ex.Message)); return null; } } private void RefreshAssignments() { if (!_setupComplete || _slots.Count == 0) { return; } List<PlayerControllerB> livingPlayers = GetLivingPlayers(); bool value = Plugin.AlwaysShowMonitors.Value; int num = Mathf.Min(livingPlayers.Count, _slots.Count); for (int i = 0; i < _slots.Count; i++) { CrewSlot crewSlot = _slots[i]; if ((Object)(object)crewSlot.BodyCam == (Object)null) { continue; } if (crewSlot.UserCycled) { if (crewSlot.CycleIndex <= -2) { ApplyManualOff(crewSlot, value); UpdateInteractionTips(crewSlot); continue; } if (crewSlot.CycleIndex == -1) { ApplyExternalCam(crewSlot, value); UpdateInteractionTips(crewSlot); continue; } PlayerControllerB val = null; if ((Object)(object)crewSlot.AssignedPlayer != (Object)null && IsLivingPlayer(crewSlot.AssignedPlayer)) { val = crewSlot.AssignedPlayer; } else if (crewSlot.CycleIndex >= 0 && crewSlot.CycleIndex < livingPlayers.Count) { val = livingPlayers[crewSlot.CycleIndex]; } if ((Object)(object)val != (Object)null) { int num2 = livingPlayers.IndexOf(val); if (num2 >= 0) { crewSlot.CycleIndex = num2; } if (crewSlot.ShowMapFeed) { ApplyMapFeed(crewSlot, val, value); } else { ApplySlotAssignment(crewSlot, val, value, $"Slot {i + 1}"); } } else { crewSlot.CycleIndex = -2; crewSlot.ShowMapFeed = false; ApplyManualOff(crewSlot, value); } UpdateInteractionTips(crewSlot); } else { if (i < num) { crewSlot.CycleIndex = i; crewSlot.ShowMapFeed = false; ApplySlotAssignment(crewSlot, livingPlayers[i], value, $"Slot {i + 1}"); } else { crewSlot.CycleIndex = -2; crewSlot.ShowMapFeed = false; ApplyManualOff(crewSlot, value); } UpdateInteractionTips(crewSlot); } } } private static void ApplyManualOff(CrewSlot slot, bool alwaysShow) { slot.AssignedPlayer = null; slot.ShowMapFeed = false; StopMapFeedCamera(slot); slot.BodyCam.SetTargetToNone(); SetMonitorOffMaterial(slot.BodyCam, GetBlackScreenMaterial()); if (slot.BodyCam.IsScreenPowered()) { slot.BodyCam.SetScreenPowered(false); } else { slot.BodyCam.UpdateScreenMaterial(); } if (slot.IsClone && (Object)(object)slot.Host != (Object)null) { if (alwaysShow && !slot.Host.activeSelf) { slot.Host.SetActive(true); } else if (!alwaysShow && slot.Host.activeSelf) { slot.Host.SetActive(false); } } if ((Object)(object)slot.Nameplate != (Object)null) { if (alwaysShow) { ((TMP_Text)slot.Nameplate).text = "Off"; ((Component)slot.Nameplate).gameObject.SetActive(true); } else { ((TMP_Text)slot.Nameplate).text = ""; ((Component)slot.Nameplate).gameObject.SetActive(false); } } } private static void ApplyExternalCam(CrewSlot slot, bool alwaysShow) { slot.AssignedPlayer = null; slot.ShowMapFeed = false; StopMapFeedCamera(slot); slot.BodyCam.SetTargetToNone(); if ((Object)(object)slot.OriginalOffMaterial != (Object)null) { SetMonitorOffMaterial(slot.BodyCam, slot.OriginalOffMaterial); } if (slot.BodyCam.IsScreenPowered()) { slot.BodyCam.SetScreenPowered(false); } else { slot.BodyCam.UpdateScreenMaterial(); } if (slot.IsClone && (Object)(object)slot.Host != (Object)null) { if (alwaysShow && !slot.Host.activeSelf) { slot.Host.SetActive(true); } else if (!alwaysShow && slot.Host.activeSelf) { slot.Host.SetActive(false); } } if ((Object)(object)slot.Nameplate != (Object)null) { if (alwaysShow) { ((TMP_Text)slot.Nameplate).text = "External"; ((Component)slot.Nameplate).gameObject.SetActive(true); } else { ((TMP_Text)slot.Nameplate).text = ""; ((Component)slot.Nameplate).gameObject.SetActive(false); } } } private void ApplyMapFeed(CrewSlot slot, PlayerControllerB player, bool alwaysShow) { slot.AssignedPlayer = player; slot.ShowMapFeed = true; slot.BodyCam.SetTargetToNone(); if (slot.IsClone && (Object)(object)slot.Host != (Object)null) { if (alwaysShow && !slot.Host.activeSelf) { slot.Host.SetActive(true); } else if (!alwaysShow && slot.Host.activeSelf) { slot.Host.SetActive(false); } } slot.BodyCam.SetScreenPowered(true); ApplyScreenBrightness(slot.BodyCam); EnsureMapFeedCamera(slot); UpdateMapFeedFollow(slot); ApplyMapFeedTextureToMonitor(slot); if ((Object)(object)slot.Nameplate != (Object)null) { string text = (string.IsNullOrEmpty(player.playerUsername) ? $"Player {player.playerClientId}" : player.playerUsername); ((TMP_Text)slot.Nameplate).text = text + " Map"; ((Component)slot.Nameplate).gameObject.SetActive(true); } } private void EnsureMapFeedCamera(CrewSlot slot) { //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_01c9: 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_01d9: Expected O, but got Unknown //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_00e2: 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_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_0109: Unknown result type (might be due to invalid IL or missing references) Camera val = (StartOfRound.Instance?.mapScreen)?.mapCamera; if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)$"Slot {slot.Index}: mapCamera unavailable for map feed."); return; } if ((Object)(object)slot.MapFeedCamera != (Object)null && (Object)(object)slot.MapFeedTexture != (Object)null) { if (!((Component)slot.MapFeedCamera).gameObject.activeSelf) { ((Component)slot.MapFeedCamera).gameObject.SetActive(true); } ((Behaviour)slot.MapFeedCamera).enabled = true; return; } DestroyMapFeedResources(slot); Transform val2 = (((Object)(object)_slotRoot != (Object)null) ? _slotRoot.transform : ((Component)this).transform); GameObject val3 = new GameObject($"CrewMapFeedCam_{slot.Index}"); val3.transform.SetParent(val2, false); val3.transform.SetPositionAndRotation(((Component)val).transform.position, ((Component)val).transform.rotation); val3.transform.localScale = Vector3.one; Camera val4 = val3.AddComponent<Camera>(); CopyMapCameraSettings(val4, val); int num = 480; int num2 = 360; try { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; object? obj = typeof(BodyCamComponent).GetField("Camera", bindingAttr)?.GetValue(slot.BodyCam); Camera val5 = (Camera)((obj is Camera) ? obj : null); if ((Object)(object)((val5 != null) ? val5.targetTexture : null) != (Object)null) { num = Mathf.Max(16, ((Texture)val5.targetTexture).width); num2 = Mathf.Max(16, ((Texture)val5.targetTexture).height); } } catch { } RenderTexture val6 = new RenderTexture(num, num2, 24) { name = $"CrewMapFeedRT_{slot.Index}", filterMode = (FilterMode)1, antiAliasing = 1 }; val6.Create(); val4.targetTexture = val6; ((Behaviour)val4).enabled = true; TryConfigureHdrpMapCamera(val4, val); slot.MapFeedCamera = val4; slot.MapFeedTexture = val6; Plugin.Log.LogInfo((object)$"Slot {slot.Index}: dedicated map feed camera ready ({num}x{num2})."); } private static void CopyMapCameraSettings(Camera dest, Camera src) { //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_0098: Unknown result type (might be due to invalid IL or missing references) dest.orthographic = src.orthographic; dest.orthographicSize = src.orthographicSize; dest.fieldOfView = src.fieldOfView; dest.nearClipPlane = src.nearClipPlane; dest.farClipPlane = src.farClipPlane; dest.cullingMask = src.cullingMask; dest.clearFlags = src.clearFlags; dest.backgroundColor = src.backgroundColor; dest.depth = src.depth - 1f; dest.allowHDR = src.allowHDR; dest.allowMSAA = src.allowMSAA; dest.useOcclusionCulling = src.useOcclusionCulling; dest.renderingPath = src.renderingPath; dest.aspect = src.aspect; } private static void TryConfigureHdrpMapCamera(Camera dest, Camera src) { try { Component component = ((Component)src).GetComponent("HDAdditionalCameraData"); if ((Object)(object)component == (Object)null) { return; } Type type = ((object)component).GetType(); Component obj = ((Component)dest).GetComponent(type) ?? ((Component)dest).gameObject.AddComponent(type); string[] array = new string[6] { "volumeLayerMask", "probeLayerMask", "clearColorMode", "backgroundColorHDR", "customRenderingSettings", "volumeAnchorOverride" }; foreach (string name in array) { FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null) && !field.IsInitOnly && !field.IsLiteral) { try { field.SetValue(obj, field.GetValue(component)); } catch { } } } type.GetField("hasPersistentHistory", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(obj, true); } catch (Exception ex) { Plugin.Log.LogDebug((object)("HDRP map cam configure skipped: " + ex.Message)); } } private void UpdateMapFeedFollow(CrewSlot slot) { //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_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_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_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_00d4: 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_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_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_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_01a4: 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_01b6: 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_01eb: Unknown result type (might be due to invalid IL or missing references) Camera mapFeedCamera = slot.MapFeedCamera; PlayerControllerB assignedPlayer = slot.AssignedPlayer; if ((Object)(object)mapFeedCamera == (Object)null || (Object)(object)assignedPlayer == (Object)null) { return; } Vector3 val; if (assignedPlayer.isPlayerDead) { val = (((Object)(object)assignedPlayer.redirectToEnemy != (Object)null) ? ((Component)assignedPlayer.redirectToEnemy).transform.position : ((!((Object)(object)assignedPlayer.deadBody != (Object)null) || !((Component)assignedPlayer.deadBody).gameObject.activeSelf) ? assignedPlayer.placeOfDeath : ((Component)assignedPlayer.deadBody).transform.position)); } else { val = ((Component)assignedPlayer).transform.position; int num = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.collidersAndRoomMask : (-5)); RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(((Component)assignedPlayer).transform.position + Vector3.up * 0.1f, Vector3.down, ref val2, 5f, num, (QueryTriggerInteraction)1)) { val = ((RaycastHit)(ref val2)).point + Vector3.up * 0.06f; } } ManualCameraRenderer val3 = StartOfRound.Instance?.mapScreen; float num2 = (((Object)(object)val3 != (Object)null) ? val3.cameraNearPlane : (-2.47f)); float num3 = (((Object)(object)val3 != (Object)null) ? val3.cameraFarPlane : 7.52f); if (assignedPlayer.isInHangarShipRoom) { mapFeedCamera.nearClipPlane = -0.96f; mapFeedCamera.farClipPlane = 7.52f; } else if (!assignedPlayer.isInsideFactory) { mapFeedCamera.nearClipPlane = num2 - 18f; mapFeedCamera.farClipPlane = num3 + 18f; } else { mapFeedCamera.nearClipPlane = num2; mapFeedCamera.farClipPlane = num3; } ((Component)mapFeedCamera).transform.position = new Vector3(val.x, val.y + 3.636f, val.z); Camera val4 = val3?.mapCamera; if ((Object)(object)val4 != (Object)null) { ((Component)mapFeedCamera).transform.rotation = ((Component)val4).transform.rotation; } } private void ApplyMapFeedTextureToMonitor(CrewSlot slot) { if ((Object)(object)slot.MapFeedTexture == (Object)null || (Object)(object)slot.BodyCam == (Object)null) { return; } try { Material monitorOnMaterial = GetMonitorOnMaterial(slot.BodyCam); if (!((Object)(object)monitorOnMaterial == (Object)null)) { monitorOnMaterial = UnshareMonitorOnMaterial(slot, monitorOnMaterial); monitorOnMaterial.mainTexture = (Texture)(object)slot.MapFeedTexture; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("ApplyMapFeedTextureToMonitor failed: " + ex.Message)); } } private static void StopMapFeedCamera(CrewSlot slot) { if (!((Object)(object)slot.MapFeedCamera == (Object)null)) { ((Behaviour)slot.MapFeedCamera).enabled = false; if (((Component)slot.MapFeedCamera).gameObject.activeSelf) { ((Component)slot.MapFeedCamera).gameObject.SetActive(false); } } } private static void DestroyMapFeedResources(CrewSlot slot) { if ((Object)(object)slot.MapFeedCamera != (Object)null) { Object.Destroy((Object)(object)((Component)slot.MapFeedCamera).gameObject); slot.MapFeedCamera = null; } if ((Object)(object)slot.MapFeedTexture != (Object)null) { if (slot.MapFeedTexture.IsCreated()) { slot.MapFeedTexture.Release(); } Object.Destroy((Object)(object)slot.MapFeedTexture); slot.MapFeedTexture = null; } } private static Material? GetMonitorOnMaterial(BodyCamComponent bodyCam) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; object? obj = typeof(BodyCamComponent).GetField("MonitorOnMaterial", bindingAttr)?.GetValue(bodyCam); return (Material?)((obj is Material) ? obj : null); } private Material UnshareMonitorOnMaterial(CrewSlot slot, Material mat) { //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_0087: Expected O, but got Unknown bool flag = false; foreach (CrewSlot slot2 in _slots) { if (slot2 != slot && !((Object)(object)slot2.BodyCam == (Object)null) && (Object)(object)GetMonitorOnMaterial(slot2.BodyCam) == (Object)(object)mat) { flag = true; break; } } if (!flag) { return mat; } Material val = new Material(mat) { name = ((Object)mat).name + " Slot" + slot.Index }; typeof(BodyCamComponent).GetField("MonitorOnMaterial", BodyCamFlags)?.SetValue(slot.BodyCam, val); try { slot.BodyCam.UpdateScreenMaterial(); } catch { } return val; } private static void RestoreBodyCamTexture(BodyCamComponent bodyCam) { if ((Object)(object)bodyCam == (Object)null) { return; } try { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; object? obj = typeof(BodyCamComponent).GetField("Camera", bindingAttr)?.GetValue(bodyCam); Camera val = (Camera)((obj is Camera) ? obj : null); Material monitorOnMaterial = GetMonitorOnMaterial(bodyCam); if (!((Object)(object)monitorOnMaterial == (Object)null)) { if ((Object)(object)val != (Object)null && (Object)(object)val.targetTexture != (Object)null) { monitorOnMaterial.mainTexture = (Texture)(object)val.targetTexture; } try { bodyCam.UpdateScreenMaterial(); } catch { } if ((Object)(object)val != (Object)null && (Object)(object)val.targetTexture != (Object)null) { monitorOnMaterial.mainTexture = (Texture)(object)val.targetTexture; } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("RestoreBodyCamTexture failed: " + ex.Message)); } } private void ApplySlotAssignment(CrewSlot slot, PlayerControllerB? player, bool alwaysShow, string blankLabel) { if ((Object)(object)player != (Object)null) { bool showMapFeed = slot.ShowMapFeed; slot.ShowMapFeed = false; if (showMapFeed) { StopMapFeedCamera(slot); } slot.BodyCam.SetTargetToPlayer(player); slot.AssignedPlayer = player; slot.BodyCam.SetScreenPowered(true); ApplyScreenBrightness(slot.BodyCam); RestoreBodyCamTexture(slot.BodyCam); if (showMapFeed) { Plugin.Log.LogInfo((object)"Slot restored body-cam RT after map feed."); } if (slot.IsClone && (Object)(object)slot.Host != (Object)null && !slot.Host.activeSelf) { slot.Host.SetActive(true); } UpdateNameplate(slot, player); } else if (alwaysShow) { slot.AssignedPlayer = null; slot.BodyCam.SetTargetToNone(); slot.BodyCam.SetScreenPowered(true); ApplyScreenBrightness(slot.BodyCam); if (slot.IsClone && (Object)(object)slot.Host != (Object)null && !slot.Host.activeSelf) { slot.Host.SetActive(true); } if ((Object)(object)slot.Nameplate != (Object)null) { ((TMP_Text)slot.Nameplate).text = blankLabel; ((Component)slot.Nameplate).gameObject.SetActive(true); } } else { slot.AssignedPlayer = null; slot.BodyCam.SetTargetToNone(); slot.BodyCam.SetScreenPowered(false); if (slot.IsClone && (Object)(object)slot.Host != (Object)null && slot.Host.activeSelf) { slot.Host.SetActive(false); } if ((Object)(object)slot.Nameplate != (Object)null) { ((TMP_Text)slot.Nameplate).text = ""; ((Component)slot.Nameplate).gameObject.SetActive(false); } } } private static void UpdateNameplate(CrewSlot slot, PlayerControllerB player) { if (!((Object)(object)slot.Nameplate == (Object)null)) { ((Component)slot.Nameplate).gameObject.SetActive(true); ((TMP_Text)slot.Nameplate).text = (string.IsNullOrEmpty(player.playerUsername) ? $"Player {player.playerClientId}" : player.playerUsername); } } private static bool IsLivingPlayer(PlayerControllerB p) { if ((Object)(object)p != (Object)null && p.isPlayerControlled) { return !p.isPlayerDead; } return false; } private static List<PlayerControllerB> GetLivingPlayers() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || instance.allPlayerScripts == null) { return new List<PlayerControllerB>(); } IEnumerable<PlayerControllerB> source = instance.allPlayerScripts.Where((PlayerControllerB p) => (Object)(object)p != (Object)null && p.isPlayerControlled && !p.isPlayerDead); if (!Plugin.IncludeLocalPlayer.Value) { PlayerControllerB local = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)local != (Object)null) { source = source.Where((PlayerControllerB p) => (Object)(object)p != (Object)(object)local); } } return source.OrderBy((PlayerControllerB p) => p.playerClientId).ToList(); } private void SetupSlotInteractions(CrewSlot slot) { if ((Object)(object)slot.Host == (Object)null || (Object)(object)slot.Renderer == (Object)null) { return; } try { slot.FocusTrigger = CreateFocusTrigger(slot); slot.CycleButton = CreateCycleButton(slot); UpdateInteractionTips(slot); } catch (Exception ex) { Plugin.Log.LogWarning((object)$"Slot {slot.Index} interaction setup failed: {ex.Message}"); } } private GameObject CreateFocusTrigger(CrewSlot slot) { //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_0021: 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_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_00a2: 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_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_010b: 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_0154: 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_017a: 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_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_019b: 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_01ea: 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_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Expected O, but got Unknown //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Expected O, but got Unknown GameObject val = new GameObject("CrewMonitor_FocusTrigger"); val.transform.SetParent(slot.Host.transform, false); val.tag = "InteractTrigger"; GameObject val2 = FindVanillaSwitchButton(); int num = val.layer; if ((Object)(object)val2 != (Object)null) { InteractTrigger componentInChildren = val2.GetComponentInChildren<InteractTrigger>(true); num = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).gameObject.layer : val2.layer); } if (num <= 0 || num == 8 || num == 30) { int num2 = LayerMask.NameToLayer("InteractableObject"); num = ((num2 >= 0) ? num2 : 9); } val.layer = num; Bounds localBounds = ((Renderer)slot.Renderer).localBounds; GetScreenFaceAxes(localBounds, ((Component)slot.Renderer).transform, out var horiz, out var vert, out var depth); float outwardLocalOnAxis = GetOutwardLocalOnAxis(slot.Renderer, depth); float num3 = AxisComponent(((Bounds)(ref localBounds)).center, depth); float num4 = Mathf.Sign(outwardLocalOnAxis - num3); if (num4 == 0f) { num4 = 1f; } float num5 = outwardLocalOnAxis + num4 * 0.04f; Vector3 v = ((Bounds)(ref localBounds)).center; SetAxisComponent(ref v, depth, (AxisComponent(((Bounds)(ref localBounds)).center, depth) + num5) * 0.5f); SetAxisComponent(ref v, horiz, AxisComponent(((Bounds)(ref localBounds)).center, horiz) - AxisComponent(((Bounds)(ref localBounds)).extents, horiz) * 0.08f); SetAxisComponent(ref v, vert, AxisComponent(((Bounds)(ref localBounds)).center, vert) + AxisComponent(((Bounds)(ref localBounds)).extents, vert) * 0.06f); BoxCollider obj = val.AddComponent<BoxCollider>(); obj.center = v; Vector3 v2 = ((Bounds)(ref localBounds)).size; SetAxisComponent(ref v2, horiz, Mathf.Max(0.05f, AxisComponent(((Bounds)(ref localBounds)).size, horiz) * 0.72f)); SetAxisComponent(ref v2, vert, Mathf.Max(0.05f, AxisComponent(((Bounds)(ref localBounds)).size, vert) * 0.68f)); SetAxisComponent(ref v2, depth, Mathf.Max(0.02f, Mathf.Abs(num5 - AxisComponent(((Bounds)(ref localBounds)).center, depth)) * 0.7f)); obj.size = v2; ((Collider)obj).isTrigger = false; InteractTrigger val3 = ConfigureInteractTrigger(val, "Focus"); val3.hoverIcon = GetTransparentHoverIcon(); val3.disabledHoverIcon = GetTransparentHoverIcon(); CrewSlotInteractBridge crewSlotInteractBridge = val.AddComponent<CrewSlotInteractBridge>(); crewSlotInteractBridge.Init(this, slot.Index, isCycleButton: false); ((UnityEvent<PlayerControllerB>)(object)val3.onInteract).AddListener((UnityAction<PlayerControllerB>)crewSlotInteractBridge.OnInteract); return val; } private static void ApplyScreenBrightness(BodyCamComponent bodyCam) { //IL_005b: 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 ((Object)(object)bodyCam == (Object)null) { return; } float num = Mathf.Clamp(Plugin.ScreenBrightness.Value, 0f, 1f); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; Type typeFromHandle = typeof(BodyCamComponent); try { object? obj = typeFromHandle.GetField("MonitorOnMaterial", bindingAttr)?.GetValue(bodyCam); Material val = (Material)((obj is Material) ? obj : null); if ((Object)(object)val != (Object)null) { val.color = Color.white; if (val.HasProperty("_EmissiveColor")) { val.SetColor("_EmissiveColor", GetBodyCamEmissiveColor()); } if (val.HasProperty("_AlbedoAffectEmissive")) { val.SetFloat("_AlbedoAffectEmissive", 1f); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Screen material emissive tune failed: " + ex.Message)); } try { object? obj2 = typeFromHandle.GetField("nightVisionLight", bindingAttr)?.GetValue(bodyCam); Light val2 = (Light)((obj2 is Light) ? obj2 : null); if ((Object)(object)val2 != (Object)null) { val2.intensity = 367f * num; val2.range = 12f * num; ((Behaviour)val2).enabled = num > 0.001f; } } catch (Exception ex2) { Plugin.Log.LogWarning((object)("ScreenBrightness nightVision tune failed: " + ex2.Message)); } } private static Color GetBodyCamEmissiveColor() { //IL_006b: 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_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_0071: Unknown result type (might be due to invalid IL or missing references) try { MethodInfo methodInfo = typeof(BodyCamComponent).Assembly.GetType("OpenBodyCams.Plugin")?.GetMethod("GetBodyCamEmissiveColor", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (methodInfo != null) { object obj = methodInfo.Invoke(null, null); if (obj is Color) { return (Color)obj; } } } catch { } return new Color(0.05f, 0.13f, 0.05f, 0f); } private GameObject CreateCycleButton(CrewSlot slot) { //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_000e: 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_002f: 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_0068: 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_00b7: 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_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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_016b: 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_0193: 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_01c2: 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_01f0: 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_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_028f: 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_02c0: 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_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_0302: 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_0392: 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_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_041b: 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_042b: 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_043b: Unknown result type (might be due to invalid IL or missing references) //IL_0441: 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_0455: Unknown result type (might be due to invalid IL or missing references) //IL_0462: 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) //IL_0487: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Expected O, but got Unknown //IL_049e: 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_0551: 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) MeshRenderer renderer = slot.Renderer; Bounds localBounds = ((Renderer)renderer).localBounds; GetScreenFaceAxes(localBounds, ((Component)renderer).transform, out var horiz, out var vert, out var depth); float num = AxisComponent(((Bounds)(ref localBounds)).size, horiz); float num2 = AxisComponent(((Bounds)(ref localBounds)).size, vert); float num3 = Mathf.Clamp(Mathf.Min(num, num2) * 0.15f, 0.06f, 0.22f); Vector3 v = ((Bounds)(ref localBounds)).center; SetAxisComponent(ref v, horiz, AxisComponent(((Bounds)(ref localBounds)).max, horiz) - num3 * 0.65f - 0.07f); SetAxisComponent(ref v, vert, AxisComponent(((Bounds)(ref localBounds)).min, vert) + num3 * 0.65f + 0.3f); float outwardLocalOnAxis = GetOutwardLocalOnAxis(renderer, depth); float num4 = AxisComponent(((Bounds)(ref localBounds)).center, depth); float num5 = Mathf.Sign(outwardLocalOnAxis - num4); if (num5 == 0f) { num5 = 1f; } SetAxisComponent(ref v, depth, outwardLocalOnAxis + num5 * 0.02f); Vector3 val = ((Component)renderer).transform.TransformPoint(v); Vector3 localPosition = slot.Host.transform.InverseTransformPoint(val); Vector3 val2 = AxisUnit(depth) * num5; Vector3 val3 = ((Component)renderer).transform.TransformDirection(val2); Vector3 normalized = ((Vector3)(ref val3)).normalized; GameObject val4 = new GameObject("CrewMonitor_CycleButton"); val4.transform.SetParent(slot.Host.transform, false); val4.transform.localPosition = localPosition; val4.transform.localRotation = Quaternion.identity; Vector3 lossyScale = slot.Host.transform.lossyScale; val4.transform.localScale = new Vector3(0.065f / Mathf.Max(0.001f, Mathf.Abs(lossyScale.x)), 0.065f / Mathf.Max(0.001f, Mathf.Abs(lossyScale.y)), 0.065f / Mathf.Max(0.001f, Mathf.Abs(lossyScale.z))); GameObject val5 = FindVanillaSwitchButton(); int num6 = -1; if ((Object)(object)val5 != (Object)null) { InteractTrigger componentInChildren = val5.GetComponentInChildren<InteractTrigger>(true); if ((Object)(object)componentInChildren != (Object)null) { num6 = ((Component)componentInChildren).gameObject.layer; } if (num6 <= 0) { num6 = val5.layer; } } if (num6 <= 0 || num6 == 8 || num6 == 30) { int num7 = LayerMask.NameToLayer("InteractableObject"); num6 = ((num7 >= 0) ? num7 : 9); } val4.layer = num6; val4.tag = "InteractTrigger"; Quaternion val6 = Quaternion.FromToRotation(Vector3.up, val4.transform.InverseTransformDirection(normalized)); GameObject obj = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)obj).name = "CyclePadBody"; obj.transform.SetParent(val4.transform, false); obj.transform.localRotation = val6; obj.transform.localPosition = val6 * new Vector3(0f, -0.15f, 0f); obj.transform.localScale = new Vector3(0.85f, 0.35f, 0.85f); Object.Destroy((Object)(object)obj.GetComponent<Collider>()); ApplyBezelGreyMaterial(obj); MeshRenderer[] componentsInChildren = obj.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer obj2 in componentsInChildren) { ((Renderer)obj2).enabled = true; ((Renderer)obj2).forceRenderingOff = false; } GameObject obj3 = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)obj3).name = "CyclePadFace"; obj3.transform.SetParent(val4.transform, false); obj3.transform.localRotation = val6; obj3.transform.localPosition = val6 * new Vector3(0f, 0.22f, 0f); obj3.transform.localScale = new Vector3(1f, 0.06f, 1f); Object.Destroy((Object)(object)obj3.GetComponent<Collider>()); ApplyWhiteButtonMaterial(obj3); componentsInChildren = obj3.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer obj4 in componentsInChildren) { ((Renderer)obj4).enabled = true; ((Renderer)obj4).forceRenderingOff = false; } GameObject val7 = new GameObject("CycleHitbox"); val7.transform.SetParent(val4.transform, false); val7.transform.localPosition = Vector3.zero; val7.transform.localRotation = Quaternion.identity; val7.transform.localScale = Vector3.one * 2.5f; val7.layer = val4.layer; val7.tag = "InteractTrigger"; BoxCollider val8 = val7.AddComponent<BoxCollider>(); ((Collider)val8).enabled = true; ((Collider)val8).isTrigger = false; val8.size = Vector3.one; InteractTrigger val9 = ConfigureInteractTrigger(val7, "Cycle crew cam : [E]"); CrewSlotInteractBridge crewSlotInteractBridge = val7.AddComponent<CrewSlotInteractBridge>(); crewSlotInteractBridge.Init(this, slot.Index, isCycleButton: true); ((UnityEvent<PlayerControllerB>)(object)val9.onInteract).AddListener((UnityAction<PlayerControllerB>)crewSlotInteractBridge.OnInteract); if (val9.onInteractEarly != null) { ((UnityEvent<PlayerControllerB>)(object)val9.onInteractEarly).AddListener((UnityAction<PlayerControllerB>)crewSlotInteractBridge.OnInteract); } val7.AddComponent<CrewButtonRaycastFallback>().Init(this, slot.Index, (Collider)(object)val8, val9); Plugin.Log.LogInfo((object)($"Slot {slot.Index} cycle button: worldSize={0.065f:F3} " + $"localPos={val4.transform.localPosition} worldPos={val4.transform.position} " + $"towardCabin={normalized} layer={val4.layer}({LayerMask.LayerToName(val4.layer)}) " + "triggerOnHitbox=true host=" + ((Object)slot.Host).name)); return val4; } private static void GetScreenFaceAxes(Bounds localBounds, Transform t, out int horiz, out int vert, out int depth) { //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_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_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_001a: 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_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_006a: 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_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) //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_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_003c: 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) Vector3 size = ((Bounds)(ref localBounds)).size; depth = 0; if (size.y <= size.x && size.y <= size.z) { depth = 1; } else if (size.z <= size.x && size.z <= size.y) { depth = 2; } int num = (depth + 1) % 3; int num2 = (depth + 2) % 3; Vector3 val = t.TransformDirection(AxisUnit(num)); Vector3 normalized = ((Vector3)(ref val)).normalized; val = t.TransformDirection(AxisUnit(num2)); Vector3 normalized2 = ((Vector3)(ref val)).normalized; if (Mathf.Abs(Vector3.Dot(normalized, Vector3.up)) >= Mathf.Abs(Vector3.Dot(normalized2, Vector3.up))) { vert = num; horiz = num2; } else { vert = num2; horiz = num; } } private static float AxisComponent(Vector3 v, int axis) { //IL_0009: 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_001b: Unknown result type (might be due to invalid IL or missing references) return axis switch { 0 => v.x, 1 => v.y, _ => v.z, }; } private static void SetAxisComponent(ref Vector3 v, int axis, float value) { switch (axis) { case 0: v.x = value; break; case 1: v.y = value; break; default: v.z = value; break; } } private static float GetOutwardLocalOnAxis(MeshRenderer renderer, int depthAxis) { //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_0017: 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_002c: 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_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_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_0082: 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_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_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) Bounds localBounds = ((Renderer)renderer).localBounds; float num = AxisComponent(((Bounds)(ref localBounds)).min, depthAxis); float num2 = AxisComponent(((Bounds)(ref localBounds)).max, depthAxis); Vector3 v2; Vector3 v = (v2 = ((Bounds)(ref localBounds)).center); SetAxisComponent(ref v2, depthAxis, num); SetAxisComponent(ref v, depthAxis, num2); Vector3 val = ((Component)renderer).transform.TransformPoint(v2); Vector3 val2 = ((Component)renderer).transform.TransformPoint(v); Vector3 val3 = val; GameObject val4 = GameObject.Find("Environment/HangarShip"); if ((Object)(object)val4 != (Object)null) { val3 = val4.transform.position; } Vector3 val5 = val - val3; float sqrMagnitude = ((Vector3)(ref val5)).sqrMagnitude; val5 = val2 - val3; bool num3 = sqrMagnitude <= ((Vector3)(ref val5)).sqrMagnitude; float num4 = (num3 ? num : num2); float num5 = (num3 ? (-1f) : 1f); return num4 + num5 * 0.012f; } private static GameObject CreateWhiteCyclePadVisual(Transform parent) { //IL_0025: 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_0063: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)val).name = "CyclePad"; val.transform.SetParent(parent, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); val.transform.localScale = new Vector3(1f, 0.28f, 1f); Collider component = val.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } ApplyWhiteButtonMaterial(val); MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer obj in componentsInChildren) { ((Renderer)obj).enabled = true; ((Renderer)obj).forceRenderingOff = false; } Plugin.Log.LogInfo((object)"Cycle pad visual: Unlit off-white Cylinder (desk button stand-in)."); return val; } private static void NormalizePadLocalScale(GameObject pad) { //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_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_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_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_01bc: 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_01d4: 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_01ec: 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_021f: 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_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_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_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_0129: 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_0141: 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_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_017a: 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_0166: 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_007c: 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_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) MeshFilter[] componentsInChildren = pad.GetComponentsInChildren<MeshFilter>(true); Bounds? val = null; MeshFilter[] array = componentsInChildren; Bounds val3 = default(Bounds); Bounds val4 = default(Bounds); foreach (MeshFilter val2 in array) { if ((Object)(object)val2.sharedMesh == (Object)null) { continue; } Bounds bounds = val2.sharedMesh.bounds; Vector3[] array2 = (Vector3[])(object)new Vector3[8]; Vector3 center = ((Bounds)(ref bounds)).center; Vector3 extents = ((Bounds)(ref bounds)).extents; int num = 0; for (int j = -1; j <= 1; j += 2) { for (int k = -1; k <= 1; k += 2) { for (int l = -1; l <= 1; l += 2) { array2[num++] = ((Component)val2).transform.TransformPoint(center + Vector3.Scale(extents, new Vector3((float)j, (float)k, (float)l))); } } } ((Bounds)(ref val3))..ctor(array2[0], Vector3.zero); for (int m = 1; m < 8; m++) { ((Bounds)(ref val3)).Encapsulate(array2[m]); } ((Bounds)(ref val4))..ctor(pad.transform.InverseTransformPoint(((Bounds)(ref val3)).center), Vector3.zero); Vector3 val5 = pad.transform.InverseTransformVector(((Bounds)(ref val3)).size); ((Vector3)(ref val5))..ctor(Mathf.Abs(val5.x), Mathf.Abs(val5.y), Mathf.Abs(val5.z)); ((Bounds)(ref val4)).size = val5; if (!val.HasValue) { val = val4; continue; } Bounds value = val.Value; ((Bounds)(ref value)).Encapsulate(val4); val = value; } float num2 = 1f; if (val.HasValue) { float[] array3 = new float[3]; Bounds value2 = val.Value; array3[0] = ((Bounds)(ref value2)).size.x; value2 = val.Value; array3[1] = ((Bounds)(ref value2)).size.y; value2 = val.Value; array3[2] = ((Bounds)(ref value2)).size.z; num2 = Mathf.Max(array3); } if (num2 < 0.0001f) { num2 = 1f; } float num3 = 1f / num2; pad.transform.localScale = Vector3.one * num3; } private static GameObject? FindWhiteConsoleButton() { //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_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_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_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_01dc: 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_01f4: 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_0218: 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_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) string[] array = new string[7] { "Environment/HangarShip/StartMatchLever/Button", "Environment/HangarShip/ControlPanelWTexture/Button", "Environment/HangarShip/ControlDesk/Button", "Environment/HangarShip/ShipModels2b/Button", "WhiteButton", "ButtonWhite", "RoundButton" }; foreach (string text in array) { GameObject val = GameObject.Find(text); if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponentInChildren<MeshFilter>(true) != (Object)null) { Plugin.Log.LogInfo((object)("FindWhiteConsoleButton: name hit '" + text + "'.")); return PreferMeshObject(val); } } StartMatchLever val2 = null; try { val2 = Object.FindObjectOfType<StartMatchLever>(); } catch { } Vector3 val3 = Vector3.zero; bool flag = false; if ((Object)(object)val2 != (Object)null) { val3 = ((Component)val2).transform.position; flag = true; } else { GameObject val4 = GameObject.Find("Environment/HangarShip/ControlPanelWTexture") ?? GameObject.Find("Environment/HangarShip/ControlDesk"); if ((Object)(object)val4 != (Object)null) { val3 = val4.transform.position; flag = true; } } GameObject val5 = GameObject.Find("Environment/HangarShip"); if ((Object)(object)val5 != (Object)null) { GameObject val6 = null; float num = float.MaxValue; MeshRenderer[] componentsInChildren = val5.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val7 in componentsInChildren) { if ((Object)(object)val7 == (Object)null || (Object)(object)((Renderer)val7).sharedMaterial == (Object)null) { continue; } string name = ((Object)((Component)val7).gameObject).name; string path = GetPath(((Component)val7).transform); if (path.IndexOf("CrewMonitor", StringComparison.OrdinalIgnoreCase) >= 0 || path.IndexOf("ShipTeleporter", StringComparison.OrdinalIgnoreCase) >= 0 || (path.IndexOf("MonitorWall", StringComparison.OrdinalIgnoreCase) >= 0 && path.IndexOf("CameraMonitorSwitchButton", StringComparison.OrdinalIgnoreCase) < 0) || name.IndexOf("Screen", StringComparison.OrdinalIgnoreCase) >= 0) { continue; } Bounds bounds = ((Renderer)val7).bounds; float num2 = Mathf.Max(((Bounds)(ref bounds)).size.x, Mathf.Max(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z)); float num3 = Mathf.Min(((Bounds)(ref bounds)).size.x, Mathf.Min(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z)); if (!(num2 < 0.02f) && !(num2 > 0.28f) && !(num3 < num2 * 0.15f) && IsLightGreyOrWhiteMaterial(val7)) { float num4 = (flag ? Vector3.Distanc