Decompiled source of Y4NGZCore v1.0.10

Y4NGZCore.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dawn;
using DunGen;
using DunGen.Graph;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Y4NGZCompany.Core;
using Y4NGZCompany.Facility.Cameras.Placement;
using Y4NGZCompany.Facility.Interior.Placement;
using Y4NGZCompany.Facility.Interior.Placement.Authored;
using Y4NGZCompany.ShipSystems.ShipTerminal;
using Y4NGZCore;
using Y4NGZCore.Lifecycle;
using Y4NGZCore.Modules;
using Y4NGZCore.Modules.Hud;
using Y4NGZCore.Modules.Layout;
using Y4NGZCore.Modules.Monitor;
using Y4NGZCore.Modules.Sales;
using Y4NGZCore.Modules.ShipSystems;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("Y4NGZCompany")]
[assembly: InternalsVisibleTo("Y4NGZShipSystems")]
[assembly: InternalsVisibleTo("Y4NGZMonitorTakeover")]
[assembly: InternalsVisibleTo("Y4NGZTerminalUpgrades")]
[assembly: InternalsVisibleTo("Y4NGZUI")]
[assembly: InternalsVisibleTo("LethalCCTV")]
[assembly: InternalsVisibleTo("Y4NGZBloodFX")]
[assembly: InternalsVisibleTo("Y4NGZAtmosphere")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")]
[assembly: IgnoresAccessChecksTo("Unity.XR.Management")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Y4NGZCore")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Shared Y4NGZ runtime services consumed by the other Y4NGZ plugin assemblies")]
[assembly: AssemblyFileVersion("1.0.10.0")]
[assembly: AssemblyInformationalVersion("1.0.10+8f6ba2850accc913d16ba0f59cfd17901883c643")]
[assembly: AssemblyProduct("Y4NGZCore")]
[assembly: AssemblyTitle("Y4NGZCore")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.10.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 Y4NGZCompany.ShipSystems
{
	internal static class MonitorPalette
	{
		internal static readonly Color UiAccent = new Color(0f, 1f, 0.05f, 1f);

		internal static readonly Color UiAccentDim = new Color(0f, 0.92f, 0.04f, 0.94f);

		internal static readonly Color UiAccentFaint = new Color(0f, 0.44f, 0.05f, 0.34f);

		internal static readonly Color MonitorLabel = new Color(0f, 0.84f, 0.9f, 1f);

		internal static readonly Color MonitorScanline = new Color(0f, 0f, 0f, 0.16f);

		internal static readonly Color MonitorScanBeam = new Color(0f, 1f, 0.18f, 0.075f);

		internal static readonly Color MonitorBackground = new Color(0.015f, 0.13f, 0.055f, 1f);

		internal static readonly Color MonitorBackplate = new Color(0.01f, 0.18f, 0.055f, 0.92f);
	}
	public static class ShipClock24h
	{
		public const string UnavailableText = "--:--";

		public static string GetShipTime24h()
		{
			TimeOfDay instance = TimeOfDay.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return "--:--";
			}
			StartOfRound instance2 = StartOfRound.Instance;
			if ((Object)(object)instance2 != (Object)null && instance2.inShipPhase)
			{
				return "--:--";
			}
			int num = (int)(instance.normalizedTimeOfDay * (60f * (float)instance.numberOfHours)) + 360;
			if (num < 0)
			{
				return "--:--";
			}
			int num2 = num / 60;
			int num3 = num % 60;
			if (num2 >= 24)
			{
				return "00:00";
			}
			return $"{num2:00}:{num3:00}";
		}
	}
}
namespace Y4NGZCompany.ShipSystems.Rendering
{
	internal sealed class CameraRenderLease : IDisposable
	{
		internal Camera Camera { get; }

		internal string Effect { get; }

		internal bool IsOverlay { get; }

		internal FrameSettingsField Field { get; }

		internal bool Enabled { get; }

		internal int StartFrame { get; }

		internal bool IsActive { get; private set; }

		internal bool IsRevoked { get; private set; }

		internal CameraRenderLease(Camera camera, string effect, bool isOverlay, FrameSettingsField field, bool enabled)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			Camera = camera;
			Effect = effect ?? string.Empty;
			IsOverlay = isOverlay;
			Field = field;
			Enabled = enabled;
			StartFrame = Time.frameCount;
			IsActive = true;
		}

		public void Dispose()
		{
			CameraRenderProfile.End(this);
		}

		internal void MarkEnded(bool revoked)
		{
			IsActive = false;
			if (revoked)
			{
				IsRevoked = true;
			}
		}
	}
	internal static class CameraRenderProfile
	{
		internal sealed class CameraState
		{
			internal Camera Camera;

			internal HDAdditionalCameraData Data;

			internal CameraRenderProfileOwner Owner;

			internal CameraRenderRole Role;

			internal bool CustomHeld;

			internal bool OriginalCustomRendering;

			internal FrameSettings SavedSettings;

			internal FrameSettingsOverrideMask SavedMask;

			internal int ProfileEpoch;

			internal int OverlayGeneration;

			internal readonly List<FieldState> Fields = new List<FieldState>(4);

			internal readonly List<CameraRenderLease> Leases = new List<CameraRenderLease>(2);

			internal readonly List<string> SuppressedOverlays = new List<string>(1);
		}

		internal sealed class FieldState
		{
			internal FrameSettingsField Field;

			internal bool OriginalEnabled;

			internal bool OriginalOverridden;

			internal bool HasProfile;

			internal bool ProfileEnabled;

			internal int ProfileEpoch;

			internal int LeaseCount;

			internal bool LeaseEnabled;
		}

		private static readonly FrameSettingsField[] UnlitFields;

		private static readonly FrameSettingsField[] UiCompositorFields;

		private static readonly FrameSettingsField[] FeedStrippedFields;

		private static readonly Dictionary<Camera, CameraState> States;

		private static readonly List<Camera> PruneBuffer;

		private static int _overlaySerial;

		internal static bool ApplyProfile(Camera camera, CameraRenderRole role)
		{
			FrameSettingsField[] array;
			switch (role)
			{
			case CameraRenderRole.Unlit:
				array = UnlitFields;
				break;
			case CameraRenderRole.UiCompositor:
				array = UiCompositorFields;
				break;
			default:
				return false;
			}
			CameraState cameraState = ResolveWithData(camera);
			if (cameraState == null || cameraState.Role == CameraRenderRole.Feed)
			{
				return false;
			}
			BeginProfile(cameraState, role);
			for (int i = 0; i < array.Length; i++)
			{
				SetProfileField(cameraState, array[i], enabled: false);
			}
			EndProfile(cameraState);
			return true;
		}

		internal static bool ApplyFeedProfile(Camera camera, bool shadowMaps, bool ambientOcclusion)
		{
			CameraState cameraState = ResolveWithData(camera);
			if (cameraState == null)
			{
				return false;
			}
			BeginProfile(cameraState, CameraRenderRole.Feed);
			for (int num = cameraState.Leases.Count - 1; num >= 0; num--)
			{
				CameraRenderLease cameraRenderLease = cameraState.Leases[num];
				if (!cameraRenderLease.IsOverlay)
				{
					EndLease(cameraState, cameraRenderLease, revoked: true);
				}
			}
			for (int i = 0; i < FeedStrippedFields.Length; i++)
			{
				SetProfileField(cameraState, FeedStrippedFields[i], enabled: false);
			}
			SetProfileField(cameraState, (FrameSettingsField)20, shadowMaps);
			SetProfileField(cameraState, (FrameSettingsField)24, ambientOcclusion);
			EndProfile(cameraState);
			return true;
		}

		internal static void ReleaseProfile(Camera camera)
		{
			if (camera == null || !States.TryGetValue(camera, out var value))
			{
				return;
			}
			if (value.Role != CameraRenderRole.None)
			{
				value.ProfileEpoch++;
				value.Role = CameraRenderRole.None;
				for (int num = value.Fields.Count - 1; num >= 0; num--)
				{
					FieldState fieldState = value.Fields[num];
					if (fieldState.HasProfile)
					{
						fieldState.HasProfile = false;
						Write(value, fieldState);
					}
				}
				RelaxCustomRendering(value);
			}
			for (int num2 = value.Leases.Count - 1; num2 >= 0; num2--)
			{
				CameraRenderLease cameraRenderLease = value.Leases[num2];
				if (cameraRenderLease.IsOverlay)
				{
					EndLease(value, cameraRenderLease, revoked: false);
				}
			}
			value.SuppressedOverlays.Clear();
			RemoveIfIdle(value);
		}

		internal static CameraRenderRole RoleOf(Camera camera)
		{
			if (!((Object)(object)camera != (Object)null) || !States.TryGetValue(camera, out var value))
			{
				return CameraRenderRole.None;
			}
			return value.Role;
		}

		internal static bool IsFeed(Camera camera)
		{
			return RoleOf(camera) == CameraRenderRole.Feed;
		}

		internal static bool TryAcquireFrameSetting(Camera camera, FrameSettingsField field, bool enabled, string effect, out CameraRenderLease lease)
		{
			//IL_0024: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			lease = null;
			if ((Object)(object)camera == (Object)null || IsFeed(camera))
			{
				return false;
			}
			CameraState cameraState = ResolveWithData(camera);
			if (cameraState == null)
			{
				return false;
			}
			FieldState fieldState = FindField(cameraState, field);
			if (fieldState != null && fieldState.LeaseCount > 0 && fieldState.LeaseEnabled != enabled)
			{
				return false;
			}
			if (fieldState == null)
			{
				EnsureCustomRendering(cameraState);
				fieldState = AddField(cameraState, field);
			}
			fieldState.LeaseCount++;
			fieldState.LeaseEnabled = enabled;
			Write(cameraState, fieldState);
			lease = new CameraRenderLease(camera, effect, isOverlay: false, field, enabled);
			cameraState.Leases.Add(lease);
			return true;
		}

		internal static bool TryBeginOverlay(Camera camera, string effect, out CameraRenderLease lease)
		{
			lease = null;
			if ((Object)(object)camera == (Object)null)
			{
				return false;
			}
			CameraState value;
			CameraState cameraState = (States.TryGetValue(camera, out value) ? value : Resolve(camera, ((Component)camera).GetComponent<HDAdditionalCameraData>()));
			string text = effect ?? string.Empty;
			if (cameraState.SuppressedOverlays.Contains(text))
			{
				RemoveIfIdle(cameraState);
				return false;
			}
			lease = new CameraRenderLease(camera, text, isOverlay: true, (FrameSettingsField)0, enabled: false);
			cameraState.Leases.Add(lease);
			cameraState.OverlayGeneration = ++_overlaySerial;
			return true;
		}

		internal static int OverlayGeneration(Camera camera)
		{
			if (!((Object)(object)camera != (Object)null) || !States.TryGetValue(camera, out var value))
			{
				return 0;
			}
			return value.OverlayGeneration;
		}

		internal static CameraRenderLease NewestOverlay(Camera camera)
		{
			if ((Object)(object)camera == (Object)null || !States.TryGetValue(camera, out var value))
			{
				return null;
			}
			for (int num = value.Leases.Count - 1; num >= 0; num--)
			{
				CameraRenderLease cameraRenderLease = value.Leases[num];
				if (cameraRenderLease.IsOverlay && cameraRenderLease.IsActive)
				{
					return cameraRenderLease;
				}
			}
			return null;
		}

		internal static bool Revoke(CameraRenderLease lease)
		{
			if (lease == null || !lease.IsActive)
			{
				return false;
			}
			if (lease.Camera != null && States.TryGetValue(lease.Camera, out var value))
			{
				if (lease.IsOverlay && !value.SuppressedOverlays.Contains(lease.Effect))
				{
					value.SuppressedOverlays.Add(lease.Effect);
				}
				EndLease(value, lease, revoked: true);
				return true;
			}
			lease.MarkEnded(revoked: true);
			return true;
		}

		internal static void End(CameraRenderLease lease)
		{
			if (lease != null && lease.IsActive)
			{
				if (lease.Camera != null && States.TryGetValue(lease.Camera, out var value))
				{
					EndLease(value, lease, revoked: false);
				}
				else
				{
					lease.MarkEnded(revoked: false);
				}
			}
		}

		internal static void Forget(CameraRenderProfileOwner owner)
		{
			CameraState state = owner.State;
			owner.State = null;
			if (state != null)
			{
				for (int i = 0; i < state.Leases.Count; i++)
				{
					state.Leases[i].MarkEnded(revoked: false);
				}
				state.Leases.Clear();
				state.Fields.Clear();
				state.Data = null;
				if (States.TryGetValue(state.Camera, out var value) && value == state)
				{
					States.Remove(state.Camera);
				}
			}
		}

		private static CameraState ResolveWithData(Camera camera)
		{
			if ((Object)(object)camera == (Object)null)
			{
				return null;
			}
			CameraState value;
			HDAdditionalCameraData val = ((States.TryGetValue(camera, out value) && (Object)(object)value.Data != (Object)null) ? value.Data : ((Component)camera).GetComponent<HDAdditionalCameraData>());
			if (!((Object)(object)val == (Object)null))
			{
				return Resolve(camera, val);
			}
			return null;
		}

		private static CameraState Resolve(Camera camera, HDAdditionalCameraData data)
		{
			if (States.TryGetValue(camera, out var value))
			{
				if ((Object)(object)value.Data == (Object)null && (Object)(object)data != (Object)null)
				{
					value.Data = data;
				}
				return value;
			}
			Prune();
			value = new CameraState
			{
				Camera = camera,
				Data = data
			};
			CameraRenderProfileOwner cameraRenderProfileOwner = ((Component)camera).GetComponent<CameraRenderProfileOwner>();
			if ((Object)(object)cameraRenderProfileOwner == (Object)null)
			{
				cameraRenderProfileOwner = ((Component)camera).gameObject.AddComponent<CameraRenderProfileOwner>();
				((Object)cameraRenderProfileOwner).hideFlags = (HideFlags)2;
			}
			cameraRenderProfileOwner.State = value;
			value.Owner = cameraRenderProfileOwner;
			States[camera] = value;
			return value;
		}

		private static void Prune()
		{
			PruneBuffer.Clear();
			foreach (KeyValuePair<Camera, CameraState> state in States)
			{
				if ((Object)(object)state.Key == (Object)null)
				{
					PruneBuffer.Add(state.Key);
				}
			}
			for (int i = 0; i < PruneBuffer.Count; i++)
			{
				if (States.TryGetValue(PruneBuffer[i], out var value))
				{
					for (int j = 0; j < value.Leases.Count; j++)
					{
						value.Leases[j].MarkEnded(revoked: false);
					}
					States.Remove(PruneBuffer[i]);
				}
			}
			PruneBuffer.Clear();
		}

		private static void BeginProfile(CameraState state, CameraRenderRole role)
		{
			EnsureCustomRendering(state);
			state.Role = role;
			state.ProfileEpoch++;
		}

		private static void EnsureCustomRendering(CameraState state)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			HDAdditionalCameraData data = state.Data;
			if (!state.CustomHeld && !((Object)(object)data == (Object)null))
			{
				state.CustomHeld = true;
				state.OriginalCustomRendering = data.customRenderingSettings;
				if (!state.OriginalCustomRendering)
				{
					state.SavedSettings = data.renderingPathCustomFrameSettings;
					state.SavedMask = data.renderingPathCustomFrameSettingsOverrideMask;
					data.renderingPathCustomFrameSettingsOverrideMask = default(FrameSettingsOverrideMask);
					data.customRenderingSettings = true;
				}
			}
		}

		private static void RelaxCustomRendering(CameraState state)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (state.CustomHeld && state.Role == CameraRenderRole.None && state.Fields.Count <= 0)
			{
				state.CustomHeld = false;
				HDAdditionalCameraData data = state.Data;
				if (!((Object)(object)data == (Object)null) && !state.OriginalCustomRendering)
				{
					data.renderingPathCustomFrameSettings = state.SavedSettings;
					data.renderingPathCustomFrameSettingsOverrideMask = state.SavedMask;
					data.customRenderingSettings = false;
				}
			}
		}

		private static void SetProfileField(CameraState state, FrameSettingsField field, bool enabled)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			FieldState fieldState = FindField(state, field) ?? AddField(state, field);
			fieldState.HasProfile = true;
			fieldState.ProfileEnabled = enabled;
			fieldState.ProfileEpoch = state.ProfileEpoch;
			Write(state, fieldState);
		}

		private static void EndProfile(CameraState state)
		{
			for (int num = state.Fields.Count - 1; num >= 0; num--)
			{
				FieldState fieldState = state.Fields[num];
				if (fieldState.HasProfile && fieldState.ProfileEpoch != state.ProfileEpoch)
				{
					fieldState.HasProfile = false;
					Write(state, fieldState);
				}
			}
		}

		private static void EndLease(CameraState state, CameraRenderLease lease, bool revoked)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			lease.MarkEnded(revoked);
			state.Leases.Remove(lease);
			if (!lease.IsOverlay)
			{
				FieldState fieldState = FindField(state, lease.Field);
				if (fieldState != null && fieldState.LeaseCount > 0)
				{
					fieldState.LeaseCount--;
					Write(state, fieldState);
				}
			}
			RelaxCustomRendering(state);
			RemoveIfIdle(state);
		}

		private static void RemoveIfIdle(CameraState state)
		{
			if (state.Role == CameraRenderRole.None && state.Fields.Count <= 0 && state.Leases.Count <= 0 && state.SuppressedOverlays.Count <= 0)
			{
				if (States.TryGetValue(state.Camera, out var value) && value == state)
				{
					States.Remove(state.Camera);
				}
				if ((Object)(object)state.Owner != (Object)null && state.Owner.State == state)
				{
					state.Owner.State = null;
				}
			}
		}

		private static FieldState FindField(CameraState state, FrameSettingsField field)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < state.Fields.Count; i++)
			{
				if (state.Fields[i].Field == field)
				{
					return state.Fields[i];
				}
			}
			return null;
		}

		private static FieldState AddField(CameraState state, FrameSettingsField field)
		{
			//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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected I4, but got Unknown
			HDAdditionalCameraData data = state.Data;
			FieldState fieldState = new FieldState
			{
				Field = field,
				OriginalEnabled = ((Object)(object)data != (Object)null && ((FrameSettings)(ref data.renderingPathCustomFrameSettings)).IsEnabled(field)),
				OriginalOverridden = ((Object)(object)data != (Object)null && ((BitArray128)(ref data.renderingPathCustomFrameSettingsOverrideMask.mask))[(uint)(int)field])
			};
			state.Fields.Add(fieldState);
			return fieldState;
		}

		private static void Write(CameraState state, FieldState field)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected I4, but got Unknown
			bool flag;
			bool flag2;
			if (field.LeaseCount > 0)
			{
				flag = field.LeaseEnabled;
				flag2 = true;
			}
			else if (field.HasProfile)
			{
				flag = field.ProfileEnabled;
				flag2 = true;
			}
			else
			{
				flag = field.OriginalEnabled;
				flag2 = field.OriginalOverridden;
				state.Fields.Remove(field);
			}
			HDAdditionalCameraData data = state.Data;
			if (!((Object)(object)data == (Object)null))
			{
				((FrameSettings)(ref data.renderingPathCustomFrameSettings)).SetEnabled(field.Field, flag);
				((BitArray128)(ref data.renderingPathCustomFrameSettingsOverrideMask.mask))[(uint)(int)field.Field] = flag2;
			}
		}

		static CameraRenderProfile()
		{
			FrameSettingsField[] array = new FrameSettingsField[5];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			UnlitFields = (FrameSettingsField[])(object)array;
			FrameSettingsField[] array2 = new FrameSettingsField[19];
			RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			UiCompositorFields = (FrameSettingsField[])(object)array2;
			FrameSettingsField[] array3 = new FrameSettingsField[17];
			RuntimeHelpers.InitializeArray(array3, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			FeedStrippedFields = (FrameSettingsField[])(object)array3;
			States = new Dictionary<Camera, CameraState>();
			PruneBuffer = new List<Camera>();
		}
	}
	[DisallowMultipleComponent]
	internal sealed class CameraRenderProfileOwner : MonoBehaviour
	{
		internal CameraRenderProfile.CameraState State;

		private void OnDestroy()
		{
			CameraRenderProfile.Forget(this);
		}
	}
	internal enum CameraRenderRole
	{
		None,
		Unlit,
		UiCompositor,
		Feed
	}
	internal enum OffscreenRigSlot
	{
		PowerFuel,
		MonitorRowCard,
		QuotaAnnouncement,
		ProfitQuotaPanel,
		DeadlinePanel,
		CctvVanillaMonitor,
		BatteryWarning,
		FuelChuteThruster
	}
	internal readonly struct OffscreenRigPlacement
	{
		internal string Name { get; }

		internal float CenterX { get; }

		internal float CenterY { get; }

		internal float HalfWidth { get; }

		internal float HalfHeight { get; }

		internal OffscreenRigPlacement(string name, float centerX, float centerY, float halfWidth, float halfHeight)
		{
			Name = name;
			CenterX = centerX;
			CenterY = centerY;
			HalfWidth = halfWidth;
			HalfHeight = halfHeight;
		}
	}
	internal static class OffscreenRigParking
	{
		internal const float ParkingHeight = -10000f;

		internal const float SlotOrigin = 8192f;

		internal const float SlotPitch = 4096f;

		internal const float MinimumClearance = 1024f;

		internal const float MaxHalfExtent = 1536f;

		internal static float SlotX(OffscreenRigSlot slot)
		{
			return 8192f + (float)slot * 4096f;
		}

		internal static bool Fits(float extentFromRootX, float extentFromRootY)
		{
			if (extentFromRootX > 0f && extentFromRootY > 0f && extentFromRootX <= 1536f)
			{
				return extentFromRootY <= 1536f;
			}
			return false;
		}

		internal static OffscreenRigPlacement[] CurrentPlacements()
		{
			return new OffscreenRigPlacement[8]
			{
				Place(OffscreenRigSlot.PowerFuel, 256f, 192f),
				Place(OffscreenRigSlot.MonitorRowCard, 416f, 96f),
				Place(OffscreenRigSlot.QuotaAnnouncement, 384f, 216f),
				Place(OffscreenRigSlot.ProfitQuotaPanel, 256f, 192f),
				Place(OffscreenRigSlot.DeadlinePanel, 256f, 192f),
				Place(OffscreenRigSlot.CctvVanillaMonitor, 1408f, 216f),
				Place(OffscreenRigSlot.BatteryWarning, 256f, 128f),
				Place(OffscreenRigSlot.FuelChuteThruster, 2f, 2f)
			};
		}

		private static OffscreenRigPlacement Place(OffscreenRigSlot slot, float halfWidth, float halfHeight)
		{
			return new OffscreenRigPlacement(slot.ToString(), SlotX(slot), -10000f, halfWidth, halfHeight);
		}

		internal static bool TryFindConflict(IReadOnlyList<OffscreenRigPlacement> placements, float minimumClearance, out string detail)
		{
			detail = null;
			if (placements == null)
			{
				return false;
			}
			for (int i = 0; i < placements.Count; i++)
			{
				for (int j = i + 1; j < placements.Count; j++)
				{
					OffscreenRigPlacement offscreenRigPlacement = placements[i];
					OffscreenRigPlacement offscreenRigPlacement2 = placements[j];
					float num = offscreenRigPlacement.HalfWidth + offscreenRigPlacement2.HalfWidth + minimumClearance;
					float num2 = offscreenRigPlacement.HalfHeight + offscreenRigPlacement2.HalfHeight + minimumClearance;
					float num3 = Math.Abs(offscreenRigPlacement.CenterX - offscreenRigPlacement2.CenterX);
					float num4 = Math.Abs(offscreenRigPlacement.CenterY - offscreenRigPlacement2.CenterY);
					if (!(num3 >= num) && !(num4 >= num2))
					{
						detail = "'" + offscreenRigPlacement.Name + "' and '" + offscreenRigPlacement2.Name + "' are not separated: " + $"x gap {num3:0.###} needs {num:0.###}, " + $"y gap {num4:0.###} needs {num2:0.###}";
						return true;
					}
				}
			}
			return false;
		}
	}
}
namespace Y4NGZCompany.ShipSystems.MonitorRow
{
	internal readonly struct MonitorRowTypewriterStep
	{
		internal int LineIndex { get; }

		internal int VisibleChars { get; }

		internal float DelaySeconds { get; }

		internal bool LineCompleted { get; }

		internal MonitorRowTypewriterStep(int lineIndex, int visibleChars, float delaySeconds, bool lineCompleted)
		{
			LineIndex = lineIndex;
			VisibleChars = visibleChars;
			DelaySeconds = delaySeconds;
			LineCompleted = lineCompleted;
		}
	}
	internal static class MonitorRowCeremonyMath
	{
		internal const float MinRenderStepSeconds = 1f / 15f;

		internal const float MaxTypingSecondsDefault = 20f;

		internal static MonitorRowTypewriterStep[] BuildTypewriterSchedule(string[] lines, float secondsPerChar, float minRenderStepSeconds, float maxTypingSeconds)
		{
			if (lines == null || lines.Length == 0)
			{
				return Array.Empty<MonitorRowTypewriterStep>();
			}
			secondsPerChar = Clamp(secondsPerChar, 0.001f, 1f);
			minRenderStepSeconds = Clamp(minRenderStepSeconds, 0.01f, 1f);
			if (maxTypingSeconds <= 0f)
			{
				maxTypingSeconds = 20f;
			}
			int num = 0;
			for (int i = 0; i < lines.Length; i++)
			{
				num += CountTypedCharacters(lines[i]);
			}
			float num2 = (float)num * secondsPerChar;
			float num3 = ((num2 > maxTypingSeconds) ? (secondsPerChar * (maxTypingSeconds / num2)) : secondsPerChar);
			int num4 = Math.Max(1, (int)Math.Ceiling(minRenderStepSeconds / num3));
			List<MonitorRowTypewriterStep> list = new List<MonitorRowTypewriterStep>();
			for (int j = 0; j < lines.Length; j++)
			{
				string text = lines[j] ?? string.Empty;
				if (text.Length == 0)
				{
					list.Add(new MonitorRowTypewriterStep(j, 0, 0f, lineCompleted: true));
					continue;
				}
				int k = 0;
				while (k < text.Length)
				{
					int num5 = 0;
					for (; k < text.Length; k++)
					{
						if (num5 >= num4)
						{
							break;
						}
						if (!char.IsWhiteSpace(text[k]))
						{
							num5++;
						}
					}
					for (; k < text.Length && char.IsWhiteSpace(text[k]); k++)
					{
					}
					bool lineCompleted = k >= text.Length;
					list.Add(new MonitorRowTypewriterStep(j, k, (float)num5 * num3, lineCompleted));
				}
			}
			return list.ToArray();
		}

		internal static float ScheduleDuration(MonitorRowTypewriterStep[] schedule)
		{
			if (schedule == null)
			{
				return 0f;
			}
			float num = 0f;
			for (int i = 0; i < schedule.Length; i++)
			{
				num += schedule[i].DelaySeconds;
			}
			return num;
		}

		private static int CountTypedCharacters(string line)
		{
			if (string.IsNullOrEmpty(line))
			{
				return 0;
			}
			int num = 0;
			for (int i = 0; i < line.Length; i++)
			{
				if (!char.IsWhiteSpace(line[i]))
				{
					num++;
				}
			}
			return num;
		}

		internal static float ComputeRibbonPeriodWorldLength(float arcSpan, int visibleWidthPixels, int tileWidthPixels)
		{
			arcSpan = Math.Max(0.001f, arcSpan);
			visibleWidthPixels = Math.Max(1, visibleWidthPixels);
			tileWidthPixels = Math.Max(1, tileWidthPixels);
			return arcSpan * (float)tileWidthPixels / (float)visibleWidthPixels;
		}

		internal static float ComputeBannerRibbonScale(float virtualLength, float arcSpan, int visibleWidthPixels, int tileWidthPixels)
		{
			float num = ComputeRibbonPeriodWorldLength(arcSpan, visibleWidthPixels, tileWidthPixels);
			return Math.Max(0.001f, virtualLength) / num;
		}

		internal static void ComputeRibbonFaceTransform(float faceArcMin, float faceArcWidth, float periodWorldLength, float uOffset, out float scaleX, out float offsetX)
		{
			periodWorldLength = Math.Max(0.001f, periodWorldLength);
			scaleX = Math.Max(0.0001f, faceArcWidth) / periodWorldLength;
			offsetX = Repeat(faceArcMin / periodWorldLength + uOffset);
		}

		internal static float AdvanceRibbonOffset(float uOffset, float deltaSeconds, float pixelsPerSecond, int tileWidthPixels, int travelSign)
		{
			tileWidthPixels = Math.Max(1, tileWidthPixels);
			float num = deltaSeconds * Math.Abs(pixelsPerSecond) / (float)tileWidthPixels;
			return Repeat(uOffset + ((travelSign < 0) ? (0f - num) : num));
		}

		internal static string SanitizeRibbonText(string text, Func<char, bool> supportsCharacter, string fallback)
		{
			if (supportsCharacter == null)
			{
				if (!string.IsNullOrEmpty(text))
				{
					return text;
				}
				return fallback ?? string.Empty;
			}
			text = text ?? string.Empty;
			char[] array = new char[text.Length];
			int length = 0;
			bool flag = false;
			for (int i = 0; i < text.Length; i++)
			{
				char c = text[i];
				if (!supportsCharacter(c))
				{
					c = Degrade(c);
					if (c == '\0' || !supportsCharacter(c))
					{
						continue;
					}
				}
				array[length++] = c;
				if (!char.IsWhiteSpace(c))
				{
					flag = true;
				}
			}
			if (!flag)
			{
				return fallback ?? string.Empty;
			}
			return new string(array, 0, length).Trim();
		}

		private static char Degrade(char c)
		{
			switch (c)
			{
			case '•':
			case '★':
			case '☆':
			case '✦':
				return '*';
			case '·':
			case '–':
			case '—':
				return '-';
			default:
				return '\0';
			}
		}

		private static float Clamp(float value, float min, float max)
		{
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}

		private static float Repeat(float value)
		{
			value -= (float)Math.Floor(value);
			if (!(value < 0f))
			{
				return value;
			}
			return value + 1f;
		}
	}
}
namespace Y4NGZCompany.ShipSystems.ShipTerminal
{
	internal static class TerminalSalesCapacity
	{
		private sealed class Provider : ISalesCapacityService
		{
			private Terminal _terminal;

			public int CurrentCapacity
			{
				get
				{
					Terminal val = Resolve();
					if (val?.itemSalesPercentages != null)
					{
						return val.itemSalesPercentages.Length;
					}
					return -1;
				}
			}

			public bool EnsureCapacity(int itemCount, int vehicleCount)
			{
				Terminal val = Resolve();
				if ((Object)(object)val != (Object)null)
				{
					return Ensure(val);
				}
				return false;
			}

			public bool EnsureCapacityForAppendedItem(int newItemIndex, int vehicleCount)
			{
				Terminal val = Resolve();
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				EnsureForAppendedItem(val, newItemIndex);
				return true;
			}

			private Terminal Resolve()
			{
				if ((Object)(object)_terminal != (Object)null)
				{
					return _terminal;
				}
				_terminal = Object.FindObjectOfType<Terminal>();
				return _terminal;
			}
		}

		private static Harmony _harmony;

		private static Provider _provider;

		internal static void Initialize()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			if (_harmony == null)
			{
				Harmony val = new Harmony("com.y4ngz.core.sales");
				val.PatchAll(typeof(TerminalSetItemSalesCapacityPatch));
				EnsureProviderRegistered();
				_harmony = val;
				ManualLogSource log = CorePlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"[Sales] Core sales-capacity provider and SetItemSales guard active (independent of TerminalUpgrades).");
				}
			}
		}

		internal static bool Ensure(Terminal terminal)
		{
			if ((Object)(object)terminal == (Object)null || terminal.buyableItemsList == null)
			{
				return false;
			}
			int[] array = TerminalSalesMath.BuildExpanded(terminal.itemSalesPercentages, terminal.buyableItemsList.Length, (terminal.buyableVehicles != null) ? terminal.buyableVehicles.Length : 0);
			if (array == null)
			{
				return false;
			}
			terminal.itemSalesPercentages = array;
			return true;
		}

		internal static void EnsureForAppendedItem(Terminal terminal, int newItemIndex)
		{
			if (!((Object)(object)terminal == (Object)null))
			{
				terminal.itemSalesPercentages = TerminalSalesMath.BuildWithAppendedItem(terminal.itemSalesPercentages, newItemIndex, (terminal.buyableVehicles != null) ? terminal.buyableVehicles.Length : 0);
			}
		}

		internal static void EnsureProviderRegistered()
		{
			if (_provider == null)
			{
				_provider = new Provider();
				ModuleCapabilityRegistry.Register("y4ngz.sales.capacity", _provider);
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "SetItemSales")]
	internal static class TerminalSetItemSalesCapacityPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void Prefix(Terminal __instance)
		{
			try
			{
				if (TerminalSalesCapacity.Ensure(__instance))
				{
					int num = ((__instance.buyableVehicles != null) ? __instance.buyableVehicles.Length : 0);
					ManualLogSource log = CorePlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)("[Terminal] Grew itemSalesPercentages before SetItemSales to " + $"{__instance.itemSalesPercentages.Length} slots " + $"(items={__instance.buyableItemsList.Length}, vehicles={num})."));
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = CorePlugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("[Terminal] SetItemSales capacity guard failed: " + ex.Message));
				}
			}
		}
	}
	internal static class TerminalSalesMath
	{
		internal const int DefaultSalePercentage = 100;

		internal static int[] BuildExpanded(int[] existing, int itemCount, int vehicleCount)
		{
			int[] array = existing ?? Array.Empty<int>();
			int num = Math.Max(0, itemCount) + Math.Max(0, vehicleCount);
			if (array.Length >= num)
			{
				return null;
			}
			int[] array2 = new int[num];
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i] = ((i < array.Length) ? array[i] : 100);
			}
			return array2;
		}

		internal static int[] BuildWithAppendedItem(int[] existing, int newItemIndex, int vehicleCount)
		{
			int[] array = existing ?? Array.Empty<int>();
			int num = Math.Max(0, newItemIndex);
			int num2 = Math.Max(0, vehicleCount);
			int[] array2 = new int[Math.Max(num + 1 + num2, array.Length + 1)];
			for (int i = 0; i < array2.Length; i++)
			{
				if (i < num)
				{
					array2[i] = ((i < array.Length) ? array[i] : 100);
				}
				else if (i == num)
				{
					array2[i] = 100;
				}
				else
				{
					array2[i] = ((i - 1 < array.Length) ? array[i - 1] : 100);
				}
			}
			return array2;
		}
	}
}
namespace Y4NGZCompany.Facility.Stash
{
	public enum CompanyStashKeypadDisplayState
	{
		Normal,
		Denied,
		Granted
	}
	public sealed class CompanyStashKeypadInteractor : MonoBehaviour
	{
		public const int EnterButton = -1;

		private const int InteractLayer = 9;

		private const float RefreshInterval = 0.2f;

		private const float ButtonPressDistance = 0.0025f;

		private const float ButtonPressDuration = 0.1f;

		private const float ButtonReturnDuration = 0.1f;

		public static Func<string[], AudioClip> BundledAudioClipProvider;

		private readonly List<CompanyStashKeypadButton> _buttons = new List<CompanyStashKeypadButton>(11);

		private readonly Dictionary<Transform, Coroutine> _buttonAnimations = new Dictionary<Transform, Coroutine>();

		private TMP_Text _displayText;

		private Renderer _displayRenderer;

		private AudioSource _audioSource;

		private AudioClip _clickClip;

		private AudioClip _deniedClip;

		private AudioClip _grantedClip;

		private bool _built;

		private float _nextRefreshAt;

		private bool _warnedMissingButtonVisuals;

		private static readonly Color NormalColor = new Color(0.98f, 0.5f, 0.032f, 1f);

		private static readonly Color DeniedColor = new Color(1f, 0.04f, 0.02f, 1f);

		private static readonly Color GrantedColor = new Color(0.08f, 0.72f, 0.14f, 1f);

		public ICompanyStashKeypadClient Client { get; private set; }

		internal int BuiltButtonCount => _buttons.Count;

		private void Awake()
		{
			ResolveOwner();
			EnsureBuilt();
		}

		private void Start()
		{
			ResolveOwner();
			EnsureBuilt();
			RefreshButtons();
		}

		private void Update()
		{
			ResolveOwner();
			EnsureBuilt();
			HandleKeyboardEnterSubmit();
			if (!(Time.time < _nextRefreshAt))
			{
				_nextRefreshAt = Time.time + 0.2f;
				RefreshButtons();
			}
		}

		internal void EnsureBuilt()
		{
			if (!_built)
			{
				DisableDemoKeypadBehaviours();
				ResolveDisplay();
				ResolveAudio();
				BuildButtonInteractions();
				_built = true;
			}
		}

		internal void RefreshButtons()
		{
			for (int i = 0; i < _buttons.Count; i++)
			{
				_buttons[i]?.RefreshState();
			}
		}

		internal void RequestButtonPress(int button, PlayerControllerB player, Transform visual)
		{
			ResolveOwner();
			ICompanyStashKeypadClient client = Client;
			if (client != null)
			{
				if (!client.IsKeypadInteractable())
				{
					SetDisplayText(client.GetKeypadLockedDisplayText(), client.GetKeypadLockedDisplayState());
					RefreshButtons();
					return;
				}
				PlayClick();
				AnimateButton(visual);
				client.PressKeypadButtonLocally(button, player);
				RefreshButtons();
			}
		}

		internal string GetButtonTip(int button)
		{
			ResolveOwner();
			if (Client == null)
			{
				return ButtonLabel(button);
			}
			return Client.GetKeypadButtonTip(button);
		}

		internal string GetDisabledTip()
		{
			ResolveOwner();
			if (Client == null)
			{
				return "[ Keypad unavailable ]";
			}
			return Client.GetKeypadDisabledTip();
		}

		internal bool IsButtonInteractable()
		{
			ResolveOwner();
			if (Client != null)
			{
				return Client.IsKeypadInteractable();
			}
			return false;
		}

		internal void SetDisplayText(string text, CompanyStashKeypadDisplayState state)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			ResolveDisplay();
			if ((Object)(object)_displayText != (Object)null)
			{
				_displayText.text = text ?? string.Empty;
			}
			Color displayColor = GetDisplayColor(state);
			if ((Object)(object)_displayText != (Object)null)
			{
				((Graphic)_displayText).color = displayColor;
			}
			if ((Object)(object)_displayRenderer != (Object)null)
			{
				Material material = _displayRenderer.material;
				if ((Object)(object)material != (Object)null)
				{
					if (material.HasProperty("_EmissionColor"))
					{
						material.SetColor("_EmissionColor", displayColor * 2.4f);
					}
					if (material.HasProperty("_EmissiveColor"))
					{
						material.SetColor("_EmissiveColor", displayColor * 2.4f);
					}
					if (material.HasProperty("_BaseColor"))
					{
						material.SetColor("_BaseColor", displayColor);
					}
					if (material.HasProperty("_Color"))
					{
						material.SetColor("_Color", displayColor);
					}
				}
			}
			switch (state)
			{
			case CompanyStashKeypadDisplayState.Denied:
				PlayDenied();
				break;
			case CompanyStashKeypadDisplayState.Granted:
				PlayGranted();
				break;
			}
		}

		private void ResolveOwner()
		{
			if (Client == null)
			{
				Client = ((Component)this).GetComponentInParent<ICompanyStashKeypadClient>() ?? ((Component)this).GetComponent<ICompanyStashKeypadClient>();
			}
		}

		private void ResolveDisplay()
		{
			if ((Object)(object)_displayText == (Object)null)
			{
				_displayText = ((Component)this).GetComponentInChildren<TMP_Text>(true);
			}
			if ((Object)(object)_displayRenderer == (Object)null)
			{
				Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val in componentsInChildren)
				{
					if (!((Object)(object)val == (Object)null))
					{
						string transformPath = GetTransformPath(((Component)val).transform);
						if (transformPath.IndexOf("display", StringComparison.OrdinalIgnoreCase) >= 0 || transformPath.IndexOf("screen", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							_displayRenderer = val;
							break;
						}
					}
				}
			}
			if ((Object)(object)_displayText == (Object)null && Client != null && Client.AllowsFallbackDisplayText)
			{
				_displayText = CreateFallbackDisplayText();
			}
		}

		private void ResolveAudio()
		{
			if ((Object)(object)_audioSource == (Object)null)
			{
				_audioSource = ((Component)this).GetComponentInChildren<AudioSource>(true);
				if ((Object)(object)_audioSource == (Object)null)
				{
					_audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
				}
				_audioSource.playOnAwake = false;
				_audioSource.spatialBlend = 1f;
				_audioSource.rolloffMode = (AudioRolloffMode)1;
				_audioSource.volume = 0.72f;
				_audioSource.minDistance = 1.5f;
				_audioSource.maxDistance = 14f;
			}
			_clickClip = _clickClip ?? LoadKeypadClip("sfx_keypadClick", "sfx_keypadClick.wav");
			_deniedClip = _deniedClip ?? LoadKeypadClip("sfx_keypadDeniedd", "sfx_keypadDeniedd.wav");
			_grantedClip = _grantedClip ?? LoadKeypadClip("sfx_keypadGranted", "sfx_keypadGranted.wav");
		}

		private static AudioClip LoadKeypadClip(params string[] names)
		{
			Func<string[], AudioClip> bundledAudioClipProvider = BundledAudioClipProvider;
			if (bundledAudioClipProvider == null)
			{
				return null;
			}
			try
			{
				return bundledAudioClipProvider(names);
			}
			catch (Exception ex)
			{
				ManualLogSource log = CoreDiagnostics.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Keypad] Audio clip provider failed for '" + string.Join("/", names) + "': " + ex.Message));
				}
				return null;
			}
		}

		private void BuildButtonInteractions()
		{
			_buttons.Clear();
			for (int i = 0; i <= 9; i++)
			{
				BuildButtonInteraction(i);
			}
			BuildButtonInteraction(-1);
		}

		private void BuildButtonInteraction(int button)
		{
			Transform val = FindButtonVisual(button);
			if ((Object)(object)val == (Object)null && Client != null && !Client.AllowsFallbackButtonVisuals)
			{
				if (_warnedMissingButtonVisuals)
				{
					return;
				}
				_warnedMissingButtonVisuals = true;
				string missingButtonVisualsWarning = Client.MissingButtonVisualsWarning;
				if (!string.IsNullOrEmpty(missingButtonVisualsWarning))
				{
					ManualLogSource log = CoreDiagnostics.Log;
					if (log != null)
					{
						log.LogWarning((object)missingButtonVisualsWarning);
					}
				}
				return;
			}
			if ((Object)(object)val == (Object)null)
			{
				val = CreateFallbackButtonVisual(button);
			}
			GameObject val2 = FindOrCreateTriggerChild(val, "CompanyStash_KeypadButton_" + ButtonObjectName(button) + "_Interact");
			ConfigureTriggerCollider(val2, val, button);
			CompanyStashKeypadButton companyStashKeypadButton = val2.GetComponent<CompanyStashKeypadButton>();
			if ((Object)(object)companyStashKeypadButton == (Object)null)
			{
				companyStashKeypadButton = val2.AddComponent<CompanyStashKeypadButton>();
			}
			companyStashKeypadButton.Owner = this;
			companyStashKeypadButton.Button = button;
			companyStashKeypadButton.Visual = val;
			companyStashKeypadButton.ConfigureTrigger();
			_buttons.Add(companyStashKeypadButton);
		}

		private Transform FindButtonVisual(int button)
		{
			Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
			string[] array = ((button != -1) ? new string[4]
			{
				$"bttn{button}",
				$"button{button}",
				$"key{button}",
				button.ToString()
			} : new string[11]
			{
				"bttnEnter", "bttn10", "buttonEnter", "button10", "keyEnter", "key10", "Enter", "Submit", "Confirm", "Return",
				"OK"
			});
			foreach (Transform val in componentsInChildren)
			{
				if (!IsUsableButtonVisual(val))
				{
					continue;
				}
				string name = ((Object)val).name ?? string.Empty;
				for (int j = 0; j < array.Length; j++)
				{
					if (IsExactOrPrefixedButtonName(name, array[j]))
					{
						return val;
					}
				}
			}
			foreach (Transform val2 in componentsInChildren)
			{
				if (!IsUsableButtonVisual(val2))
				{
					continue;
				}
				string name2 = ((Object)val2).name ?? string.Empty;
				if (button == -1)
				{
					if (IsEnterButtonName(name2))
					{
						return val2;
					}
				}
				else if (IsDigitButtonName(name2, button))
				{
					return val2;
				}
			}
			return null;
		}

		private static bool IsUsableButtonVisual(Transform candidate)
		{
			if ((Object)(object)candidate == (Object)null)
			{
				return false;
			}
			string transformPath = GetTransformPath(candidate);
			if (transformPath.IndexOf("Interact", StringComparison.OrdinalIgnoreCase) >= 0 || transformPath.IndexOf("Trigger", StringComparison.OrdinalIgnoreCase) >= 0 || transformPath.IndexOf("Fallback", StringComparison.OrdinalIgnoreCase) >= 0 || transformPath.IndexOf("DD_Wire", StringComparison.OrdinalIgnoreCase) >= 0 || transformPath.IndexOf("DD_KeypadTerminal", StringComparison.OrdinalIgnoreCase) >= 0 || transformPath.IndexOf("DD_Detonator", StringComparison.OrdinalIgnoreCase) >= 0 || transformPath.IndexOf("DD_Display", StringComparison.OrdinalIgnoreCase) >= 0 || transformPath.IndexOf("DD_Marking", StringComparison.OrdinalIgnoreCase) >= 0 || transformPath.IndexOf("Socket", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return false;
			}
			if (!((Object)(object)((Component)candidate).GetComponent<Renderer>() != (Object)null))
			{
				return ((Component)candidate).GetComponentsInChildren<Renderer>(true).Length != 0;
			}
			return true;
		}

		private static bool IsExactOrPrefixedButtonName(string name, string exactName)
		{
			if (string.IsNullOrWhiteSpace(name) || string.IsNullOrWhiteSpace(exactName))
			{
				return false;
			}
			if (string.Equals(name, exactName, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			if (!name.EndsWith("_" + exactName, StringComparison.OrdinalIgnoreCase) && !name.EndsWith("-" + exactName, StringComparison.OrdinalIgnoreCase))
			{
				return name.EndsWith("." + exactName, StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private void HandleKeyboardEnterSubmit()
		{
			Keyboard current = Keyboard.current;
			if (current == null || (!((ButtonControl)current.enterKey).wasPressedThisFrame && !((ButtonControl)current.numpadEnterKey).wasPressedThisFrame))
			{
				return;
			}
			ResolveOwner();
			ICompanyStashKeypadClient client = Client;
			bool num = client?.HasLocalKeypadInput ?? false;
			bool flag = client?.IsKeypadInteractable() ?? false;
			if (num && flag)
			{
				PlayerControllerB player = GameNetworkManager.Instance?.localPlayerController ?? StartOfRound.Instance?.localPlayerController;
				if (CanLocalPlayerSubmitKeyboardEnter(player))
				{
					RequestButtonPress(-1, player, FindButtonVisual(-1));
				}
			}
		}

		private TMP_Text CreateFallbackDisplayText()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			Renderer val = _displayRenderer ?? FindPanelRenderer();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject val2 = new GameObject("DisplayCanvas");
			val2.transform.SetParent(((Component)val).transform, false);
			Bounds val3 = CalculateRendererLocalBounds(((Component)val).transform, val);
			int num = SmallestAxis(((Bounds)(ref val3)).size);
			Vector3 val4 = AxisVector(num);
			Vector3 extents = ((Bounds)(ref val3)).extents;
			float num2 = num switch
			{
				1 => extents.y, 
				0 => extents.x, 
				_ => extents.z, 
			};
			val2.transform.localPosition = ((Bounds)(ref val3)).center + val4 * (num2 + 0.001f);
			val2.transform.localRotation = Quaternion.FromToRotation(Vector3.forward, val4);
			val2.transform.localScale = Vector3.one * 0.018f;
			GameObject val5 = new GameObject("DisplayText");
			val5.transform.SetParent(val2.transform, false);
			val5.transform.localPosition = Vector3.zero;
			val5.transform.localRotation = Quaternion.identity;
			val5.transform.localScale = Vector3.one;
			TextMeshPro obj = val5.AddComponent<TextMeshPro>();
			((TMP_Text)obj).text = "_ _ _ _";
			((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
			((TMP_Text)obj).enableWordWrapping = false;
			((TMP_Text)obj).enableAutoSizing = true;
			((TMP_Text)obj).fontSizeMin = 0.18f;
			((TMP_Text)obj).fontSizeMax = 0.85f;
			((Graphic)obj).color = NormalColor;
			((TMP_Text)obj).rectTransform.sizeDelta = new Vector2(5.4f, 1.3f);
			return (TMP_Text)(object)obj;
		}

		private Renderer FindPanelRenderer()
		{
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string transformPath = GetTransformPath(((Component)val).transform);
					if (transformPath.IndexOf("panel", StringComparison.OrdinalIgnoreCase) >= 0 || transformPath.IndexOf("keypad", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return val;
					}
				}
			}
			return null;
		}

		private bool CanLocalPlayerSubmitKeyboardEnter(PlayerControllerB player)
		{
			//IL_0062: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if (player.inTerminalMenu)
			{
				return false;
			}
			if ((Object)(object)player.quickMenuManager != (Object)null && player.quickMenuManager.isMenuOpen)
			{
				return false;
			}
			if (player.isTypingChat)
			{
				return false;
			}
			return Vector3.Distance(((Object)(object)player.gameplayCamera != (Object)null) ? ((Component)player.gameplayCamera).transform.position : ((Component)player).transform.position, ((Component)this).transform.position) <= 4f;
		}

		private static bool IsEnterButtonName(string name)
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				return false;
			}
			string text = name.ToLowerInvariant();
			if (text.Contains("enter") || text.Contains("submit") || text.Contains("confirm") || text.Contains("return"))
			{
				return true;
			}
			if (text == "ok" || text.EndsWith("_ok") || text.EndsWith("-ok"))
			{
				return true;
			}
			if (text.Contains("10"))
			{
				if (!text.Contains("bttn") && !text.Contains("button"))
				{
					return text.Contains("key");
				}
				return true;
			}
			return false;
		}

		private static bool IsDigitButtonName(string name, int digit)
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				return false;
			}
			string value = Mathf.Clamp(digit, 0, 9).ToString();
			string text = name.ToLowerInvariant();
			if (text.Contains(value))
			{
				if (!text.Contains("bttn") && !text.Contains("button"))
				{
					return text.Contains("key");
				}
				return true;
			}
			return false;
		}

		private Transform CreateFallbackButtonVisual(int button)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)obj).name = ((button == -1) ? "bttnEnter" : $"bttn{button}");
			obj.transform.SetParent(((Component)this).transform, false);
			obj.transform.localPosition = EstimateFallbackButtonPosition(button);
			obj.transform.localRotation = Quaternion.identity;
			obj.transform.localScale = ((button == -1) ? new Vector3(0.13f, 0.035f, 0.045f) : new Vector3(0.045f, 0.035f, 0.045f));
			Collider component = obj.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			return obj.transform;
		}

		private static Vector3 EstimateFallbackButtonPosition(int button)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			int num;
			switch (button)
			{
			case -1:
				return new Vector3(0.055f, 0.73f, 0.435f);
			default:
				num = button - 1;
				break;
			case 0:
				num = 10;
				break;
			}
			int num2 = num / 3;
			return new Vector3((float)(num % 3 - 1) * 0.055f, 0.92f - (float)num2 * 0.06f, 0.435f);
		}

		private static GameObject FindOrCreateTriggerChild(Transform visual, string name)
		{
			//IL_001e: 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_0058: 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)
			Transform val = (((Object)(object)visual != (Object)null) ? visual.Find(name) : null);
			GameObject val2 = (GameObject)(((Object)(object)val != (Object)null) ? ((object)((Component)val).gameObject) : ((object)new GameObject(name)));
			if ((Object)(object)visual != (Object)null)
			{
				val2.transform.SetParent(visual, false);
			}
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = Vector3.one;
			return val2;
		}

		private static void ConfigureTriggerCollider(GameObject triggerObject, Transform visual, int button)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			triggerObject.layer = ResolveLayer("InteractableObject", 9);
			SetTagSafe(triggerObject, "InteractTrigger");
			BoxCollider val = triggerObject.GetComponent<BoxCollider>();
			if ((Object)(object)val == (Object)null)
			{
				val = triggerObject.AddComponent<BoxCollider>();
			}
			((Collider)val).isTrigger = true;
			Bounds val2 = CalculateButtonColliderBounds(visual);
			if (button == -1)
			{
				((Bounds)(ref val2)).size = new Vector3(ExpandLocalColliderAxis(((Bounds)(ref val2)).size.x, 2f, 0.002f), ExpandLocalColliderAxis(((Bounds)(ref val2)).size.y, 2f, 0.002f), ExpandLocalColliderAxis(((Bounds)(ref val2)).size.z, 2.5f, 0.002f));
			}
			val.center = ((Bounds)(ref val2)).center;
			val.size = ((Bounds)(ref val2)).size;
		}

		private static Bounds CalculateButtonColliderBounds(Transform visual)
		{
			//IL_0009: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: 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_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)visual == (Object)null)
			{
				return new Bounds(Vector3.zero, new Vector3(0.006f, 0.006f, 0.004f));
			}
			Renderer[] componentsInChildren = ((Component)visual).GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren == null || componentsInChildren.Length == 0)
			{
				return new Bounds(Vector3.zero, new Vector3(0.006f, 0.006f, 0.004f));
			}
			bool flag = false;
			Bounds result = default(Bounds);
			foreach (Renderer val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Mesh rendererMesh = GetRendererMesh(val);
				if ((Object)(object)rendererMesh == (Object)null)
				{
					continue;
				}
				Bounds bounds = rendererMesh.bounds;
				Vector3 min = ((Bounds)(ref bounds)).min;
				Vector3 max = ((Bounds)(ref bounds)).max;
				Vector3[] array = (Vector3[])(object)new Vector3[8]
				{
					new Vector3(min.x, min.y, min.z),
					new Vector3(max.x, min.y, min.z),
					new Vector3(min.x, max.y, min.z),
					new Vector3(max.x, max.y, min.z),
					new Vector3(min.x, min.y, max.z),
					new Vector3(max.x, min.y, max.z),
					new Vector3(min.x, max.y, max.z),
					new Vector3(max.x, max.y, max.z)
				};
				for (int j = 0; j < array.Length; j++)
				{
					Vector3 val2 = visual.InverseTransformPoint(((Component)val).transform.TransformPoint(array[j]));
					if (!flag)
					{
						((Bounds)(ref result))..ctor(val2, Vector3.zero);
						flag = true;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val2);
					}
				}
			}
			if (!flag)
			{
				return new Bounds(Vector3.zero, new Vector3(0.006f, 0.006f, 0.004f));
			}
			((Bounds)(ref result)).size = new Vector3(ExpandLocalColliderAxis(((Bounds)(ref result)).size.x, 1.45f, 0.0005f), ExpandLocalColliderAxis(((Bounds)(ref result)).size.y, 1.45f, 0.0005f), ExpandLocalColliderAxis(((Bounds)(ref result)).size.z, 2.25f, 0.0015f));
			return result;
		}

		private static Bounds CalculateRendererLocalBounds(Transform localRoot, Renderer renderer)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: 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_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)localRoot == (Object)null || (Object)(object)renderer == (Object)null)
			{
				return new Bounds(Vector3.zero, Vector3.one * 0.01f);
			}
			Mesh rendererMesh = GetRendererMesh(renderer);
			if ((Object)(object)rendererMesh == (Object)null)
			{
				return new Bounds(Vector3.zero, Vector3.one * 0.01f);
			}
			Bounds bounds = rendererMesh.bounds;
			Vector3 min = ((Bounds)(ref bounds)).min;
			Vector3 max = ((Bounds)(ref bounds)).max;
			Vector3[] array = (Vector3[])(object)new Vector3[8]
			{
				new Vector3(min.x, min.y, min.z),
				new Vector3(max.x, min.y, min.z),
				new Vector3(min.x, max.y, min.z),
				new Vector3(max.x, max.y, min.z),
				new Vector3(min.x, min.y, max.z),
				new Vector3(max.x, min.y, max.z),
				new Vector3(min.x, max.y, max.z),
				new Vector3(max.x, max.y, max.z)
			};
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(localRoot.InverseTransformPoint(((Component)renderer).transform.TransformPoint(array[0])), Vector3.zero);
			for (int i = 1; i < array.Length; i++)
			{
				((Bounds)(ref result)).Encapsulate(localRoot.InverseTransformPoint(((Component)renderer).transform.TransformPoint(array[i])));
			}
			return result;
		}

		private static int SmallestAxis(Vector3 size)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (size.x <= size.y && size.x <= size.z)
			{
				return 0;
			}
			if (size.y <= size.x && size.y <= size.z)
			{
				return 1;
			}
			return 2;
		}

		private static Vector3 AxisVector(int axis)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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 static Mesh GetRendererMesh(Renderer renderer)
		{
			if ((Object)(object)renderer == (Object)null)
			{
				return null;
			}
			MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null)
			{
				return component.sharedMesh;
			}
			SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.sharedMesh;
		}

		private static float ExpandLocalColliderAxis(float size, float multiplier, float padding)
		{
			if (size <= 1E-05f)
			{
				return padding;
			}
			return Mathf.Max(size * multiplier, size + padding);
		}

		private void AnimateButton(Transform visual)
		{
			if (!((Object)(object)visual == (Object)null))
			{
				if (_buttonAnimations.TryGetValue(visual, out var value) && value != null)
				{
					((MonoBehaviour)this).StopCoroutine(value);
				}
				_buttonAnimations[visual] = ((MonoBehaviour)this).StartCoroutine(AnimateButtonRoutine(visual));
			}
		}

		private IEnumerator AnimateButtonRoutine(Transform visual)
		{
			Vector3 start = visual.localPosition;
			Vector3 pressed = start + new Vector3(0f, 0f, 0.0025f);
			float elapsed = 0f;
			while (elapsed < 0.1f)
			{
				elapsed += Time.deltaTime;
				visual.localPosition = Vector3.Lerp(start, pressed, Mathf.Clamp01(elapsed / 0.1f));
				yield return null;
			}
			visual.localPosition = pressed;
			elapsed = 0f;
			while (elapsed < 0.1f)
			{
				elapsed += Time.deltaTime;
				visual.localPosition = Vector3.Lerp(pressed, start, Mathf.Clamp01(elapsed / 0.1f));
				yield return null;
			}
			visual.localPosition = start;
			_buttonAnimations.Remove(visual);
		}

		private void DisableDemoKeypadBehaviours()
		{
			MonoBehaviour[] componentsInChildren = ((Component)this).GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string a = ((object)val).GetType().FullName ?? string.Empty;
					if (string.Equals(a, "NavKeypad.Keypad", StringComparison.Ordinal) || string.Equals(a, "NavKeypad.KeypadInteractionFPV", StringComparison.Ordinal))
					{
						((Behaviour)val).enabled = false;
					}
				}
			}
		}

		private void PlayClick()
		{
			PlayOneShot(_clickClip, 0.62f);
		}

		private void PlayDenied()
		{
			PlayOneShot(_deniedClip, 0.75f);
		}

		private void PlayGranted()
		{
			PlayOneShot(_grantedClip, 0.8f);
		}

		private void PlayOneShot(AudioClip clip, float volume)
		{
			ResolveAudio();
			if ((Object)(object)_audioSource != (Object)null && (Object)(object)clip != (Object)null)
			{
				_audioSource.PlayOneShot(clip, volume);
			}
		}

		private static Color GetDisplayColor(CompanyStashKeypadDisplayState state)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(state switch
			{
				CompanyStashKeypadDisplayState.Denied => DeniedColor, 
				CompanyStashKeypadDisplayState.Granted => GrantedColor, 
				_ => NormalColor, 
			});
		}

		private static string ButtonLabel(int button)
		{
			if (button != -1)
			{
				return $"Press [{Mathf.Clamp(button, 0, 9)}]";
			}
			return "Press [Enter]";
		}

		private static string ButtonObjectName(int button)
		{
			if (button != -1)
			{
				return button.ToString();
			}
			return "Enter";
		}

		private static Bounds Encapsulate(Bounds a, Bounds b)
		{
			//IL_0004: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			((Bounds)(ref a)).Encapsulate(((Bounds)(ref b)).min);
			((Bounds)(ref a)).Encapsulate(((Bounds)(ref b)).max);
			return a;
		}

		private static string GetTransformPath(Transform transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return string.Empty;
			}
			string text = ((Object)transform).name;
			Transform parent = transform.parent;
			while ((Object)(object)parent != (Object)null)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}

		private static int ResolveLayer(string name, int fallback)
		{
			int num = LayerMask.NameToLayer(name);
			if (num < 0)
			{
				return fallback;
			}
			return num;
		}

		private static void SetTagSafe(GameObject obj, string tag)
		{
			try
			{
				obj.tag = tag;
			}
			catch
			{
				obj.tag = "Untagged";
			}
		}
	}
	public sealed class CompanyStashKeypadButton : MonoBehaviour
	{
		public CompanyStashKeypadInteractor Owner;

		public int Button;

		public Transform Visual;

		private InteractTrigger _trigger;

		private Collider _collider;

		internal void ConfigureTrigger()
		{
			_collider = ((Component)this).GetComponent<Collider>();
			_trigger = ((Component)this).GetComponent<InteractTrigger>();
			if ((Object)(object)_trigger == (Object)null)
			{
				_trigger = ((Component)this).gameObject.AddComponent<InteractTrigger>();
			}
			ConfigureCommonTrigger(_trigger);
			((UnityEvent<PlayerControllerB>)(object)_trigger.onInteract).RemoveListener((UnityAction<PlayerControllerB>)OnInteract);
			((UnityEvent<PlayerControllerB>)(object)_trigger.onInteract).AddListener((UnityAction<PlayerControllerB>)OnInteract);
			RefreshState();
		}

		internal void RefreshState()
		{
			if (!((Object)(object)_trigger == (Object)null))
			{
				bool interactable = (Object)(object)Owner != (Object)null && Owner.IsButtonInteractable();
				_trigger.interactable = interactable;
				_trigger.hoverTip = (((Object)(object)Owner != (Object)null) ? Owner.GetButtonTip(Button) : "Press keypad");
				_trigger.disabledHoverTip = (((Object)(object)Owner != (Object)null) ? Owner.GetDisabledTip() : "[ Keypad unavailable ]");
				ApplyInteractionIcons(_trigger);
				if ((Object)(object)_collider != (Object)null)
				{
					_collider.enabled = true;
				}
			}
		}

		public void OnInteract(PlayerControllerB player)
		{
			Owner?.RequestButtonPress(Button, player, Visual);
			RefreshState();
		}

		private static void ApplyInteractionIcons(InteractTrigger trigger)
		{
			if (!((Object)(object)trigger == (Object)null) && !((Object)(object)trigger.hoverIcon != (Object)null))
			{
				PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController ?? StartOfRound.Instance?.localPlayerController;
				if (!((Object)(object)val?.grabItemIcon == (Object)null))
				{
					trigger.hoverIcon = val.grabItemIcon;
					trigger.disabledHoverIcon = val.grabItemIcon;
				}
			}
		}

		private static void ConfigureCommonTrigger(InteractTrigger trigger)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			trigger.oneHandedItemAllowed = true;
			trigger.twoHandedItemAllowed = true;
			trigger.holdInteraction = false;
			trigger.timeToHold = 0.1f;
			trigger.timeToHoldSpeedMultiplier = 1f;
			trigger.interactCooldown = true;
			trigger.cooldownTime = 0.08f;
			trigger.disableTriggerMesh = true;
			InteractTrigger val = trigger;
			if (val.hoverTip == null)
			{
				val.hoverTip = string.Empty;
			}
			val = trigger;
			if (val.disabledHoverTip == null)
			{
				val.disabledHoverTip = string.Empty;
			}
			ApplyInteractionIcons(trigger);
			if (trigger.onInteract == null)
			{
				trigger.onInteract = new InteractEvent();
			}
			if (trigger.onInteractEarly == null)
			{
				trigger.onInteractEarly = new InteractEvent();
			}
			if (trigger.onInteractEarlyOtherClients == null)
			{
				trigger.onInteractEarlyOtherClients = new InteractEvent();
			}
			if (trigger.onStopInteract == null)
			{
				trigger.onStopInteract = new InteractEvent();
			}
			if (trigger.onCancelAnimation == null)
			{
				trigger.onCancelAnimation = new InteractEvent();
			}
			if (trigger.holdingInteractEvent == null)
			{
				trigger.holdingInteractEvent = new InteractEventFloat();
			}
		}
	}
	public interface ICompanyStashKeypadClient
	{
		bool HasLocalKeypadInput { get; }

		bool AllowsFallbackDisplayText { get; }

		bool AllowsFallbackButtonVisuals { get; }

		string MissingButtonVisualsWarning { get; }

		bool IsKeypadInteractable();

		string GetKeypadButtonTip(int button);

		string GetKeypadDisabledTip();

		void PressKeypadButtonLocally(int button, PlayerControllerB player);

		string GetKeypadLockedDisplayText();

		CompanyStashKeypadDisplayState GetKeypadLockedDisplayState();
	}
}
namespace Y4NGZCompany.Facility.Shared
{
	public static class FacilityAudioClipLoader
	{
		private const string AudioDirectory = "Audio";

		private const string ContractAudioDirectory = "ContractAudio";

		private static readonly string[] PackageDirectoryNames = new string[6] { "Y4NGZCore", "y4ngz-Y4NGZCore", "Y4NGZCompany", "y4ngz-Y4NGZCompany", "LethalCCTV", "y4ngz-LethalCCTV" };

		private static readonly Dictionary<string, AudioClip> Clips = new Dictionary<string, AudioClip>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, List<Action<AudioClip>>> Pending = new Dictionary<string, List<Action<AudioClip>>>(StringComparer.OrdinalIgnoreCase);

		private static readonly HashSet<string> Failed = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		public static void Request(MonoBehaviour owner, string fileName, Action<AudioClip> completed)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)owner == (Object)null || string.IsNullOrWhiteSpace(fileName))
			{
				return;
			}
			if (Clips.TryGetValue(fileName, out var value) && (Object)(object)value != (Object)null)
			{
				completed?.Invoke(value);
			}
			else
			{
				if (Failed.Contains(fileName))
				{
					return;
				}
				if (Pending.TryGetValue(fileName, out var value2))
				{
					if (completed != null)
					{
						value2.Add(completed);
					}
					return;
				}
				string text = ResolvePath(fileName, ((object)owner).GetType().Assembly);
				if (string.IsNullOrEmpty(text))
				{
					Failed.Add(fileName);
					ManualLogSource log = CoreDiagnostics.Log;
					if (log != null)
					{
						log.LogWarning((object)("[LethalCCTV][Audio] Missing facility audio '" + fileName + "'."));
					}
					return;
				}
				AudioType val = ResolveAudioType(text);
				if ((int)val == 0)
				{
					Failed.Add(fileName);
					ManualLogSource log2 = CoreDiagnostics.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("[LethalCCTV][Audio] Unsupported facility audio extension '" + fileName + "'."));
					}
					return;
				}
				value2 = new List<Action<AudioClip>>();
				if (completed != null)
				{
					value2.Add(completed);
				}
				Pending[fileName] = value2;
				owner.StartCoroutine(Load(fileName, text, val));
			}
		}

		private static IEnumerator Load(string fileName, string path, AudioType audioType)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(new Uri(path).AbsoluteUri, audioType);
			try
			{
				yield return request.SendWebRequest();
				if ((int)request.result != 1)
				{
					Failed.Add(fileName);
					Pending.Remove(fileName);
					ManualLogSource log = CoreDiagnostics.Log;
					if (log != null)
					{
						log.LogWarning((object)("[LethalCCTV][Audio] Failed loading '" + fileName + "': " + request.error));
					}
					yield break;
				}
				AudioClip content = DownloadHandlerAudioClip.GetContent(request);
				if ((Object)(object)content == (Object)null)
				{
					Failed.Add(fileName);
					Pending.Remove(fileName);
					ManualLogSource log2 = CoreDiagnostics.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("[LethalCCTV][Audio] Decoded null clip '" + fileName + "'."));
					}
					yield break;
				}
				((Object)content).name = "Y4NGZ_" + Path.GetFileNameWithoutExtension(fileName);
				Clips[fileName] = content;
				if (Pending.TryGetValue(fileName, out var value))
				{
					Pending.Remove(fileName);
					for (int i = 0; i < value.Count; i++)
					{
						try
						{
							value[i]?.Invoke(content);
						}
						catch (Exception ex)
						{
							ManualLogSource log3 = CoreDiagnostics.Log;
							if (log3 != null)
							{
								log3.LogWarning((object)("[LethalCCTV][Audio] Clip callback failed for '" + fileName + "': " + ex.Message));
							}
						}
					}
				}
				ManualLogSource log4 = CoreDiagnostics.Log;
				if (log4 != null)
				{
					log4.LogInfo((object)$"[LethalCCTV][Audio] Loaded '{fileName}' as {audioType}.");
				}
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
		}

		private static string ResolvePath(string fileName, Assembly requester)
		{
			string text = fileName.Replace('/', Path.DirectorySeparatorChar);
			foreach (string item in EnumerateRoots(requester))
			{
				string text2 = Path.Combine(item, "Audio", text);
				if (File.Exists(text2))
				{
					return text2;
				}
				string text3 = Path.Combine(item, "ContractAudio", text);
				if (File.Exists(text3))
				{
					return text3;
				}
				string text4 = Path.Combine(item, text);
				if (File.Exists(text4))
				{
					return text4;
				}
			}
			return null;
		}

		private static IEnumerable<string> EnumerateRoots(Assembly requester)
		{
			HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			List<string> roots = new List<string>();
			Add(DirectoryOf(requester));
			Add(DirectoryOf(typeof(FacilityAudioClipLoader).Assembly));
			string text = null;
			try
			{
				text = Paths.PluginPath;
			}
			catch (Exception ex)
			{
				ManualLogSource log = CoreDiagnostics.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Y4NGZCore][Audio] Plugin root resolve failed: " + ex.Message));
				}
			}
			if (!string.IsNullOrEmpty(text))
			{
				for (int i = 0; i < PackageDirectoryNames.Length; i++)
				{
					string text2 = Path.Combine(text, PackageDirectoryNames[i]);
					if (Directory.Exists(text2))
					{
						Add(text2);
					}
				}
			}
			return roots;
			void Add(string candidate)
			{
				if (!string.IsNullOrEmpty(candidate) && seen.Add(candidate))
				{
					roots.Add(candidate);
				}
			}
		}

		private static string DirectoryOf(Assembly assembly)
		{
			if (assembly == null)
			{
				return null;
			}
			try
			{
				string location = assembly.Location;
				return string.IsNullOrEmpty(location) ? null : Path.GetDirectoryName(location);
			}
			catch (Exception ex)
			{
				ManualLogSource log = CoreDiagnostics.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Y4NGZCore][Audio] Assembly directory resolve failed: " + ex.Message));
				}
				return null;
			}
		}

		private static AudioType ResolveAudioType(string path)
		{
			string extension = Path.GetExtension(path);
			if (!string.Equals(extension, ".ogg", StringComparison.OrdinalIgnoreCase))
			{
				if (!string.Equals(extension, ".wav", StringComparison.OrdinalIgnoreCase))
				{
					if (!string.Equals(extension, ".mp3", StringComparison.OrdinalIgnoreCase))
					{
						return (AudioType)0;
					}
					return (AudioType)13;
				}
				return (AudioType)20;
			}
			return (AudioType)14;
		}
	}
	internal static class FacilitySmokeEffectBuilder
	{
		private static Material _smokeMaterial;

		private static Texture2D _softCircleTexture;

		internal static ParticleSystem BuildSmoke(Transform parent, string objectName, float scale = 1f)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: 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_0224: 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)
			float num = Mathf.Clamp(scale, 0.1f, 2f);
			GameObject val = new GameObject(string.IsNullOrWhiteSpace(objectName) ? "Smoke" : objectName);
			val.transform.SetParent(parent, false);
			ParticleSystem val2 = val.AddComponent<ParticleSystem>();
			MainModule main = val2.main;
			((MainModule)(ref main)).playOnAwake = false;
			((MainModule)(ref main)).loop = true;
			((MainModule)(ref main)).startLifetime = new MinMaxCurve(1.6f, 2.6f);
			((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.22f, 0.48f);
			((MainModule)(ref main)).startSize = new MinMaxCurve(0.18f * num, 0.4f * num);
			((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(0.2f, 0.2f, 0.22f, 0.35f), new Color(0.32f, 0.32f, 0.34f, 0.28f));
			((MainModule)(ref main)).gravityModifier = new MinMaxCurve(-0.015f);
			((MainModule)(ref main)).maxParticles = Mathf.CeilToInt(90f * num);
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
			EmissionModule emission = val2.emission;