Decompiled source of MisideItems v0.0.8

BepInEx/plugins/MisideItems.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dawn;
using Dawn.Internal;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MisideItems.NetcodePatcher;
using MisideItems.helperSlop;
using MisideItems.houseSlop;
using MisideItems.itemSlop;
using MisideItems.itemSlop.cartofingotsSlop;
using MisideItems.networkSlop;
using MisideItems.patchSlop;
using MisideItems.scriptSlop;
using OpenBodyCams;
using OpenBodyCams.API;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.VFX;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MisideItems")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.0.8.0")]
[assembly: AssemblyInformationalVersion("0.0.8")]
[assembly: AssemblyProduct("MisideItems")]
[assembly: AssemblyTitle("MisideItems")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.8.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 MisideItems
{
	internal sealed class ConfigManager
	{
		private readonly Dictionary<string, ConfigEntry<float>> volumeConfigs;

		private readonly Dictionary<string, ConfigEntry<int>> priceOverridesByCompositeKey;

		private readonly ConfigEntry<KitchenWallpapers> kitchenWallpapersDefault;

		private readonly ConfigEntry<MainWallpapers> mainWallpapersDefault;

		private readonly ConfigEntry<BedroomWallpapers> bedroomWallpapersDefault;

		private readonly ConfigEntry<BathroomWallpapers> bathroomWallpapersDefault;

		private readonly ConfigEntry<ParticleVariants> particleVariantsDefault;

		private readonly ConfigEntry<BackgroundMusic> backgroundMusicDefault;

		private readonly ConfigEntry<DoorTextures> doorTexturesDefault;

		private readonly ConfigEntry<KitchenFloorBoards> kitchenFloorBoardsDefault;

		private readonly ConfigEntry<MainFloorBoards> mainFloorBoardsDefault;

		private readonly ConfigEntry<BedroomFloorBoards> bedroomFloorBoardsDefault;

		internal static ConfigEntry<bool> DawnLibPatchToggle;

		internal static ConfigEntry<bool> BuildModePatchToggle;

		internal static ConfigEntry<bool> DisableWeatherEffectsCache;

		internal static ConfigEntry<bool> DisableMoonSceneEffectsCache;

		internal static ConfigEntry<bool> PerformanceModeLights;

		internal static ConfigEntry<bool> PerformanceModeParticles;

		internal static ConfigEntry<bool> HouseDebugLogs;

		internal static ConfigEntry<bool> DisableBloom;

		internal static ConfigEntry<bool> DisableBathroomCamera;

		internal static ConfigEntry<bool> DisableHouseAmbience;

		internal static ConfigEntry<bool> DisableCoreAmbience;

		internal static ConfigEntry<bool> HideMisideLogo;

		internal static ConfigEntry<bool> DisableTeleporterDuringGameplay;

		internal static ConfigEntry<string> TeleporterDisableIgnoredMoons;

		internal ConfigManager(ConfigFile config)
		{
			volumeConfigs = new Dictionary<string, ConfigEntry<float>>();
			priceOverridesByCompositeKey = new Dictionary<string, ConfigEntry<int>>();
			volumeConfigs["BackroomsLamp"] = config.Bind<float>("Volume Settings", "_MetalLamp Furniture Volume", 0.2f, "Controls the volume of the Metal Lamp ambient audio. E.g. 0.1 = 10% volume");
			volumeConfigs["CapsulaVentil"] = config.Bind<float>("Volume Settings", "_CapsulaVentil Furniture Volume", 0.8f, "Controls the volume of the Capsula Ventil ambient audio. E.g. 0.1 = 10% volume");
			volumeConfigs["BedsideClock"] = config.Bind<float>("Volume Settings", "BedsideClock Item Volume", 0.3f, "Controls the volume of the Bedside Clock ambient audio. E.g. 0.1 = 10% volume");
			volumeConfigs["GlitchedChair"] = config.Bind<float>("Volume Settings", "GlitchedChair Item Volume", 0.5f, "Controls the volume of the GlitchedChair ambient audio. E.g. 0.1 = 10% volume");
			volumeConfigs["FancyClock"] = config.Bind<float>("Volume Settings", "FancyClock Item Volume", 0.6f, "Controls the volume of the FancyClock ambient audio. E.g. 0.1 = 10% volume");
			volumeConfigs["PinkRecorder"] = config.Bind<float>("Volume Settings", "PinkRecorder Item Volume", 1f, "Controls the volume of the PinkRecorder audio. E.g. 0.1 = 10% volume");
			volumeConfigs["CursedClock"] = config.Bind<float>("Volume Settings", "CursedClock Item Static Volume", 0.35f, "Controls the volume of the CursedClock static audio. E.g. 0.1 = 10% volume");
			volumeConfigs["CursedClockTick"] = config.Bind<float>("Volume Settings", "CursedClock Item Tick Volume", 1f, "Controls the volume of the CursedClock ticking audio. Always set to 0.2 when collected. E.g. 0.1 = 10% volume");
			volumeConfigs["CursedClockCrack"] = config.Bind<float>("Volume Settings", "CursedClock Item Crack Volume", 1f, "Controls the volume of the CursedClock cracking audio. Always set to 0.2 when collected. E.g. 0.1 = 10% volume");
			volumeConfigs["HouseAudio"] = config.Bind<float>("Volume Settings", "House Music Volume", 0.5f, "Controls the volume of the house audio. E.g. 0.1 = 10% volume");
			kitchenWallpapersDefault = config.Bind<KitchenWallpapers>("Monitor Defaults", "KitchenWallpapers", KitchenWallpapers.Aged, "Set the default kitchen room wallpaper at start of game");
			mainWallpapersDefault = config.Bind<MainWallpapers>("Monitor Defaults", "MainWallpapers", MainWallpapers.Aged, "Set the default main room wallpaper at start of game");
			bedroomWallpapersDefault = config.Bind<BedroomWallpapers>("Monitor Defaults", "BedroomWallpapers", BedroomWallpapers.Aged, "Set the default bedroom wallpaper at start of game");
			bathroomWallpapersDefault = config.Bind<BathroomWallpapers>("Monitor Defaults", "BathroomWallpapers", BathroomWallpapers.Tiles, "Set the default bathroom wallpaper at start of game");
			particleVariantsDefault = config.Bind<ParticleVariants>("Monitor Defaults", "ParticleVariants", ParticleVariants.DustDaytime, "Set the default particle effects at start of game");
			backgroundMusicDefault = config.Bind<BackgroundMusic>("Monitor Defaults", "BackgroundMusic", BackgroundMusic.None, "Set the default music audio at start of game");
			doorTexturesDefault = config.Bind<DoorTextures>("Monitor Defaults", "DoorTextures", DoorTextures.Damaged, "Set the default door texture at start of game");
			kitchenFloorBoardsDefault = config.Bind<KitchenFloorBoards>("Monitor Defaults", "KitchenFloorBoards", KitchenFloorBoards.Damaged, "Set the default kitchen floor texture at start of game");
			mainFloorBoardsDefault = config.Bind<MainFloorBoards>("Monitor Defaults", "MainFloorBoards", MainFloorBoards.Damaged, "Set the default main floor texture at start of game");
			bedroomFloorBoardsDefault = config.Bind<BedroomFloorBoards>("Monitor Defaults", "BedroomFloorBoards", BedroomFloorBoards.Damaged, "Set the default bedroom floor texture at start of game");
			BindMonitorPrices(config);
			DawnLibPatchToggle = config.Bind<bool>("Mod Internal Settings", "Disable DawnLib item load patching", false, "This patch is used to allow items to load outside the ship bounds if left and saved outside the ship. Togglable incase issues arise.");
			BuildModePatchToggle = config.Bind<bool>("Mod Internal Settings", "Disable Build Mode patching", false, "This patch is used to allow building inside of the house. Togglable incase issues arise, but not recommended.");
			DisableWeatherEffectsCache = config.Bind<bool>("Mod Internal Settings", "Disable weather effects caching", false, "Caching is used to restore weather sounds and effects on entry and exit of the house. Disable if you feel the need to.");
			DisableMoonSceneEffectsCache = config.Bind<bool>("Mod Internal Settings", "Disable moon effects caching", false, "Caching is used to restore moon sounds and effects on entry and exit of the house. Disable if you feel the need to.");
			PerformanceModeLights = config.Bind<bool>("Mod Internal Settings", "Enable fast lights", false, "Lowers the quality of all lights in the house, disabling shadows, volumetrics, etc. Use for higher performance.");
			PerformanceModeParticles = config.Bind<bool>("Mod Internal Settings", "Disable particle renderers", false, "Disables all particles in the house, note that any purchases related to particles will not be visible. Use for higher performance.");
			HouseDebugLogs = config.Bind<bool>("Mod Internal Settings", "Enable debug logging", false, "Enables debug logging for the house specifically.");
			DisableBloom = config.Bind<bool>("House settings", "Disable bloom", false, "Disables bloom inside of the house.");
			DisableBathroomCamera = config.Bind<bool>("House settings", "Disable bathroom camera", false, "Disables the bathroom camera that emulates a mirror.");
			DisableHouseAmbience = config.Bind<bool>("House settings", "Disable ambience audio", false, "Disables ambience audio inside of the house.");
			DisableCoreAmbience = config.Bind<bool>("House settings", "Disable core ambience audio", false, "Disables ambience audio inside of the core rooms.");
			HideMisideLogo = config.Bind<bool>("House settings", "Hide Miside logo on monitor", false, "Hides the Miside logo on the monitor in the basement.");
			DisableTeleporterDuringGameplay = config.Bind<bool>("House settings", "Disable teleporter during moon landings", false, "For balancing purposes, this makes the house only accessible during ship phase or at the company.");
			TeleporterDisableIgnoredMoons = config.Bind<string>("House settings", "Disabled teleporter moon whitelist", "gordion", "A whitelist for the aforementioned setting, separated by commas. Uses DawnLib namespaces, e.g. 'titan,abaddon,experimentation'.");
		}

		internal bool TryGetVolume(string id, out ConfigEntry<float> entry)
		{
			return volumeConfigs.TryGetValue(id, out entry);
		}

		internal bool TryGetMonitorDefaultSelectableKey(MonitorGroupID groupId, out string defaultSelectableKey)
		{
			defaultSelectableKey = null;
			if (groupId == MonitorGroupID.ExtraRooms || groupId == MonitorGroupID.Nighttime || groupId == MonitorGroupID.MainCozyLights || groupId == MonitorGroupID.SunlightAlt)
			{
				return false;
			}
			switch (groupId)
			{
			case MonitorGroupID.KitchenWallpapers:
				defaultSelectableKey = kitchenWallpapersDefault.Value.ToString();
				if (HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)$"[Defaults] Group {groupId} -> Default key '{defaultSelectableKey}'");
				}
				return true;
			case MonitorGroupID.MainWallpapers:
				defaultSelectableKey = mainWallpapersDefault.Value.ToString();
				if (HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)$"[Defaults] Group {groupId} -> Default key '{defaultSelectableKey}'");
				}
				return true;
			case MonitorGroupID.BedroomWallpapers:
				defaultSelectableKey = bedroomWallpapersDefault.Value.ToString();
				if (HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)$"[Defaults] Group {groupId} -> Default key '{defaultSelectableKey}'");
				}
				return true;
			case MonitorGroupID.BathroomWallpapers:
				defaultSelectableKey = bathroomWallpapersDefault.Value.ToString();
				if (HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)$"[Defaults] Group {groupId} -> Default key '{defaultSelectableKey}'");
				}
				return true;
			case MonitorGroupID.ParticleVariants:
				defaultSelectableKey = particleVariantsDefault.Value.ToString();
				if (HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)$"[Defaults] Group {groupId} -> Default key '{defaultSelectableKey}'");
				}
				return true;
			case MonitorGroupID.BackgroundMusic:
				defaultSelectableKey = backgroundMusicDefault.Value.ToString();
				if (HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)$"[Defaults] Group {groupId} -> Default key '{defaultSelectableKey}'");
				}
				return true;
			case MonitorGroupID.DoorTextures:
				defaultSelectableKey = doorTexturesDefault.Value.ToString();
				if (HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)$"[Defaults] Group {groupId} -> Default key '{defaultSelectableKey}'");
				}
				return true;
			case MonitorGroupID.KitchenFloorBoards:
				defaultSelectableKey = kitchenFloorBoardsDefault.Value.ToString();
				if (HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)$"[Defaults] Group {groupId} -> Default key '{defaultSelectableKey}'");
				}
				return true;
			case MonitorGroupID.MainFloorBoards:
				defaultSelectableKey = mainFloorBoardsDefault.Value.ToString();
				if (HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)$"[Defaults] Group {groupId} -> Default key '{defaultSelectableKey}'");
				}
				return true;
			case MonitorGroupID.BedroomFloorBoards:
				defaultSelectableKey = bedroomFloorBoardsDefault.Value.ToString();
				if (HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)$"[Defaults] Group {groupId} -> Default key '{defaultSelectableKey}'");
				}
				return true;
			default:
				Plugin.mls.LogDebug((object)$"[Defaults] No config default for group {groupId}");
				return false;
			}
		}

		internal bool TryGetMonitorPriceEntry(MonitorGroupID groupId, string selectableKey, out ConfigEntry<int> entry)
		{
			entry = null;
			if (string.IsNullOrEmpty(selectableKey))
			{
				return false;
			}
			string key = MakeCompositeKey(groupId, selectableKey);
			return priceOverridesByCompositeKey.TryGetValue(key, out entry);
		}

		private static string MakeCompositeKey(MonitorGroupID groupId, string selectableKey)
		{
			return groupId.ToString() + "|" + selectableKey;
		}

		private void BindMonitorPrices(ConfigFile config)
		{
			BindPriceSection(config, MonitorGroupID.KitchenWallpapers, "Monitor Prices - KitchenWallpapers", typeof(KitchenWallpapers));
			BindPriceSection(config, MonitorGroupID.MainWallpapers, "Monitor Prices - MainWallpapers", typeof(MainWallpapers));
			BindPriceSection(config, MonitorGroupID.BedroomWallpapers, "Monitor Prices - BedroomWallpapers", typeof(BedroomWallpapers));
			BindPriceSection(config, MonitorGroupID.BathroomWallpapers, "Monitor Prices - BathroomWallpapers", typeof(BathroomWallpapers));
			BindPriceSection(config, MonitorGroupID.ParticleVariants, "Monitor Prices - ParticleVariants", typeof(ParticleVariants));
			BindPriceSection(config, MonitorGroupID.BackgroundMusic, "Monitor Prices - BackgroundMusic", typeof(BackgroundMusic));
			BindPriceSection(config, MonitorGroupID.ExtraRooms, "Monitor Prices - ExtraRooms", typeof(ExtraRooms));
			BindPriceSection(config, MonitorGroupID.Nighttime, "Monitor Prices - Nighttime", typeof(NightTime));
			BindPriceSection(config, MonitorGroupID.MainCozyLights, "Monitor Prices - MainCozyLights", typeof(MainCozyLights));
			BindPriceSection(config, MonitorGroupID.SunlightAlt, "Monitor Prices - Sunlight", typeof(SunlightAlt));
			BindPriceSection(config, MonitorGroupID.DoorTextures, "Monitor Prices - DoorTextures", typeof(DoorTextures));
			BindPriceSection(config, MonitorGroupID.KitchenFloorBoards, "Monitor Prices - KitchenFloorBoards", typeof(KitchenFloorBoards));
			BindPriceSection(config, MonitorGroupID.MainFloorBoards, "Monitor Prices - MainFloorBoards", typeof(MainFloorBoards));
			BindPriceSection(config, MonitorGroupID.BedroomFloorBoards, "Monitor Prices - BedroomFloorBoards", typeof(BedroomFloorBoards));
		}

		private void BindPriceSection(ConfigFile config, MonitorGroupID groupId, string section, Type enumType)
		{
			string[] names = Enum.GetNames(enumType);
			foreach (string text in names)
			{
				if (!string.Equals(text, "None", StringComparison.OrdinalIgnoreCase))
				{
					string key = MakeCompositeKey(groupId, text);
					priceOverridesByCompositeKey[key] = config.Bind<int>(section, text, -1, "Sets the price for " + text + ". -1 means uninitialised, initialises after purchasing the house teleporter.");
				}
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("MrHat.MisideItems", "MisideItems", "0.0.8")]
	public class Plugin : BaseUnityPlugin
	{
		internal const string modGUID = "MrHat.MisideItems";

		internal const string modName = "MisideItems";

		internal const string modVersion = "0.0.8";

		internal static Harmony _harmony;

		internal static ManualLogSource mls;

		private InputAction toggleConsolePowerAction;

		private InputAction ejectConsoleCartridgeAction;

		internal static Plugin Instance { get; private set; }

		internal static ConfigManager Configs { get; private set; }

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Instance = this;
			mls = Logger.CreateLogSource("MrHat.MisideItems");
			_harmony = new Harmony("MrHat.MisideItems");
			Configs = new ConfigManager(((BaseUnityPlugin)this).Config);
			if (AssetBundleGate.IsLoaded("glitchchairassets"))
			{
				_harmony.PatchAll(typeof(chairSlop));
			}
			if (AssetBundleGate.IsLoaded("cartofingotsassets"))
			{
				_harmony.PatchAll(typeof(CartCrouchBlock));
			}
			_harmony.PatchAll(typeof(PlaceableObjectsSurfacePatch));
			if (AssetBundleGate.IsLoaded("____tamagotchihouseassets"))
			{
				_harmony.PatchAll(typeof(StartOfRoundLateUpdateTranspiler));
				_harmony.PatchAll(typeof(StartOfRoundTeleportPlayerInShipBoundsTranspiler));
				_harmony.PatchAll(typeof(StartOfRoundOnDestroyPatch));
				_harmony.PatchAll(typeof(StartOfRoundStartGamePatch));
				_harmony.PatchAll(typeof(StartOfRoundShipHasLeftPatch));
				_harmony.PatchAll(typeof(ManualCameraRendererLateUpdatePatch));
			}
			if (!ConfigManager.BuildModePatchToggle.Value && AssetBundleGate.IsLoaded("____tamagotchihouseassets"))
			{
				_harmony.PatchAll(typeof(ShipBuildModeManagerUpdateTranspiler));
				_harmony.PatchAll(typeof(ShipBuildModeManagerPlayerMeetsConditionsPatch));
				_harmony.PatchAll(typeof(ShipBuildModeManagerEnterBuildModePatch));
			}
			if (!ConfigManager.DawnLibPatchToggle.Value && AssetBundleGate.IsLoaded("____tamagotchihouseassets"))
			{
				_harmony.PatchAll(typeof(LoadFromRootBoundsPatch));
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "MisideItems";

		public const string PLUGIN_NAME = "MisideItems";

		public const string PLUGIN_VERSION = "0.0.8";
	}
}
namespace MisideItems.scriptSlop
{
	public sealed class AnimatedItemMarker : MonoBehaviour
	{
		public bool armed;

		public bool baseCaptured;
	}
	[Serializable]
	internal class BooleanEvent : UnityEvent<bool>
	{
	}
	[Serializable]
	internal class AnimatedTriggerEntry
	{
		public Animator animator;

		public bool animatorIsBool = true;

		public string animationString;

		[Space(5f)]
		public AudioSource audioSource;

		public AudioClip[] boolFalseAudios;

		public AudioClip[] boolTrueAudios;

		[Space(4f)]
		public AudioClip playWhileTrue;

		public bool resetAudioWhenFalse;

		public bool makeAudibleNoise;

		public float noiseLoudness = 0.7f;

		[Space(3f)]
		public ParticleSystem playParticle;

		public int playParticleOnTimesTriggered;

		public BooleanEvent onTriggerBool;

		[Space(5f)]
		public bool playAudiosInSequence;

		public bool triggerByChance;

		public float chancePercent = 5f;

		[HideInInspector]
		public bool boolValue;

		[HideInInspector]
		public int timesTriggered;

		[HideInInspector]
		public float cachedAudioTime;

		[NonSerialized]
		public bool hasInitializedRandomSeed;

		[NonSerialized]
		public Random triggerRandom;
	}
	internal class AnimatedObjectTriggerExtended : NetworkBehaviour
	{
		[SerializeField]
		private AnimatedTriggerEntry[] AnimatedTriggers;

		public void Trigger(PlayerControllerB playerWhoTriggered)
		{
			if (!((Object)(object)playerWhoTriggered == (Object)null))
			{
				if (((NetworkBehaviour)this).IsServer)
				{
					RunOnServerAndBroadcast(playerWhoTriggered.playerClientId);
				}
				else
				{
					TriggerServerRpc(playerWhoTriggered.playerClientId);
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void TriggerServerRpc(ulong playerClientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3671878579u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerClientId);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3671878579u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					base.__rpc_exec_stage = (__RpcExecStage)0;
					RunOnServerAndBroadcast(playerClientId);
				}
			}
		}

		private void RunOnServerAndBroadcast(ulong playerClientId)
		{
			if (AnimatedTriggers == null || AnimatedTriggers.Length == 0)
			{
				return;
			}
			int num = AnimatedTriggers.Length;
			if (num <= 64)
			{
				ulong num2 = 0uL;
				ulong num3 = 0uL;
				for (int i = 0; i < num; i++)
				{
					AnimatedTriggerEntry animatedTriggerEntry = AnimatedTriggers[i];
					if (animatedTriggerEntry != null && EvaluateChance(animatedTriggerEntry))
					{
						num2 |= (ulong)(1L << i);
						if (animatedTriggerEntry.animatorIsBool)
						{
							animatedTriggerEntry.boolValue = !animatedTriggerEntry.boolValue;
						}
						if (animatedTriggerEntry.boolValue)
						{
							num3 |= (ulong)(1L << i);
						}
					}
				}
				TriggerMaskClientRpc(playerClientId, num2, num3);
				return;
			}
			bool[] array = new bool[num];
			bool[] array2 = new bool[num];
			for (int j = 0; j < num; j++)
			{
				AnimatedTriggerEntry animatedTriggerEntry2 = AnimatedTriggers[j];
				if (animatedTriggerEntry2 == null)
				{
					array[j] = false;
					array2[j] = false;
					continue;
				}
				if ((array[j] = EvaluateChance(animatedTriggerEntry2)) && animatedTriggerEntry2.animatorIsBool)
				{
					animatedTriggerEntry2.boolValue = !animatedTriggerEntry2.boolValue;
				}
				array2[j] = animatedTriggerEntry2.boolValue;
			}
			TriggerArraysClientRpc(playerClientId, array, array2);
		}

		private bool EvaluateChance(AnimatedTriggerEntry entry)
		{
			if (!entry.triggerByChance)
			{
				return true;
			}
			InitializeRandomSeed(entry);
			int num = entry.triggerRandom.Next(100);
			return (float)num < entry.chancePercent;
		}

		private void InitializeRandomSeed(AnimatedTriggerEntry entry)
		{
			if (!entry.hasInitializedRandomSeed)
			{
				entry.hasInitializedRandomSeed = true;
				int seed = 0;
				if ((Object)(object)StartOfRound.Instance != (Object)null)
				{
					seed = StartOfRound.Instance.randomMapSeed;
				}
				entry.triggerRandom = new Random(seed);
			}
		}

		[ClientRpc]
		private void TriggerMaskClientRpc(ulong playerClientId, ulong executedMask, ulong boolValueMask)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(675362802u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerClientId);
					BytePacker.WriteValueBitPacked(val2, executedMask);
					BytePacker.WriteValueBitPacked(val2, boolValueMask);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 675362802u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.__rpc_exec_stage = (__RpcExecStage)0;
					ApplyResults_Mask(executedMask, boolValueMask);
				}
			}
		}

		[ClientRpc]
		private void TriggerArraysClientRpc(ulong playerClientId, bool[] executed, bool[] boolValues)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3892061111u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, playerClientId);
				bool flag = executed != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(executed, default(ForPrimitives));
				}
				bool flag2 = boolValues != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives));
				if (flag2)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(boolValues, default(ForPrimitives));
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3892061111u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				base.__rpc_exec_stage = (__RpcExecStage)0;
				ApplyResults_Arrays(executed, boolValues);
			}
		}

		private void ApplyResults_Mask(ulong executedMask, ulong boolValueMask)
		{
			if (AnimatedTriggers == null)
			{
				return;
			}
			int num = AnimatedTriggers.Length;
			int num2 = Mathf.Min(num, 64);
			for (int i = 0; i < num2; i++)
			{
				if (((executedMask >> i) & 1) == 0)
				{
					continue;
				}
				AnimatedTriggerEntry animatedTriggerEntry = AnimatedTriggers[i];
				if (animatedTriggerEntry == null)
				{
					continue;
				}
				bool flag = false;
				if (animatedTriggerEntry.animatorIsBool)
				{
					flag = (animatedTriggerEntry.boolValue = ((boolValueMask >> i) & 1) != 0);
					Animator animator = animatedTriggerEntry.animator;
					if (animator != null)
					{
						animator.SetBool(animatedTriggerEntry.animationString, flag);
					}
				}
				else
				{
					Animator animator2 = animatedTriggerEntry.animator;
					if (animator2 != null)
					{
						animator2.SetTrigger(animatedTriggerEntry.animationString);
					}
				}
				((UnityEvent<bool>)animatedTriggerEntry.onTriggerBool)?.Invoke(animatedTriggerEntry.animatorIsBool && flag);
				SetParticle(animatedTriggerEntry, animatedTriggerEntry.animatorIsBool && flag);
				PlayAudio(animatedTriggerEntry, animatedTriggerEntry.animatorIsBool && flag);
			}
		}

		private void ApplyResults_Arrays(bool[] executed, bool[] boolValues)
		{
			if (AnimatedTriggers == null || executed == null || boolValues == null)
			{
				return;
			}
			int num = AnimatedTriggers.Length;
			int num2 = Mathf.Min(num, Mathf.Min(executed.Length, boolValues.Length));
			for (int i = 0; i < num2; i++)
			{
				if (!executed[i])
				{
					continue;
				}
				AnimatedTriggerEntry animatedTriggerEntry = AnimatedTriggers[i];
				if (animatedTriggerEntry == null)
				{
					continue;
				}
				bool flag = false;
				if (animatedTriggerEntry.animatorIsBool)
				{
					flag = boolValues[i];
					animatedTriggerEntry.boolValue = flag;
					Animator animator = animatedTriggerEntry.animator;
					if (animator != null)
					{
						animator.SetBool(animatedTriggerEntry.animationString, flag);
					}
				}
				else
				{
					Animator animator2 = animatedTriggerEntry.animator;
					if (animator2 != null)
					{
						animator2.SetTrigger(animatedTriggerEntry.animationString);
					}
				}
				((UnityEvent<bool>)animatedTriggerEntry.onTriggerBool)?.Invoke(animatedTriggerEntry.animatorIsBool && flag);
				SetParticle(animatedTriggerEntry, animatedTriggerEntry.animatorIsBool && flag);
				PlayAudio(animatedTriggerEntry, animatedTriggerEntry.animatorIsBool && flag);
			}
		}

		private void SetParticle(AnimatedTriggerEntry entry, bool boolVal)
		{
			if (!((Object)(object)entry.playParticle == (Object)null))
			{
				if (boolVal)
				{
					entry.playParticle.Play(true);
				}
				else
				{
					entry.playParticle.Stop(true, (ParticleSystemStopBehavior)1);
				}
			}
		}

		private void PlayAudio(AnimatedTriggerEntry entry, bool boolVal)
		{
			if ((Object)(object)entry.audioSource == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return;
			}
			if ((Object)(object)entry.playWhileTrue != (Object)null)
			{
				entry.audioSource.clip = entry.playWhileTrue;
				if (boolVal)
				{
					entry.audioSource.Play();
					if (!entry.resetAudioWhenFalse)
					{
						entry.audioSource.time = entry.cachedAudioTime;
					}
				}
				else
				{
					entry.cachedAudioTime = entry.audioSource.time;
					entry.audioSource.Stop();
				}
			}
			AudioClip val = null;
			if (boolVal)
			{
				if (entry.boolTrueAudios != null && entry.boolTrueAudios.Length != 0)
				{
					val = entry.boolTrueAudios[Random.Range(0, entry.boolTrueAudios.Length)];
				}
			}
			else if (entry.boolFalseAudios != null && entry.boolFalseAudios.Length != 0)
			{
				if (entry.playAudiosInSequence)
				{
					if (entry.timesTriggered >= entry.boolFalseAudios.Length)
					{
						return;
					}
					if (entry.timesTriggered == entry.playParticleOnTimesTriggered && (Object)(object)entry.playParticle != (Object)null)
					{
						entry.playParticle.Play(true);
					}
					val = entry.boolFalseAudios[entry.timesTriggered];
					entry.timesTriggered++;
				}
				else
				{
					val = entry.boolFalseAudios[Random.Range(0, entry.boolFalseAudios.Length)];
				}
			}
			if (!((Object)(object)val == (Object)null))
			{
			}
		}

		internal void ForceBoolByIndex(int index, bool value)
		{
			if (AnimatedTriggers != null && (uint)index < (uint)AnimatedTriggers.Length && AnimatedTriggers.Length <= 64)
			{
				ulong num = (ulong)(1L << index);
				ApplyResults_Mask(num, value ? num : 0);
			}
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(3671878579u, new RpcReceiveHandler(__rpc_handler_3671878579), "TriggerServerRpc");
			((NetworkBehaviour)this).__registerRpc(675362802u, new RpcReceiveHandler(__rpc_handler_675362802), "TriggerMaskClientRpc");
			((NetworkBehaviour)this).__registerRpc(3892061111u, new RpcReceiveHandler(__rpc_handler_3892061111), "TriggerArraysClientRpc");
			((NetworkBehaviour)this).__initializeRpcs();
		}

		private static void __rpc_handler_3671878579(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong playerClientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerClientId);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((AnimatedObjectTriggerExtended)(object)target).TriggerServerRpc(playerClientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_675362802(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong playerClientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerClientId);
				ulong executedMask = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref executedMask);
				ulong boolValueMask = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref boolValueMask);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((AnimatedObjectTriggerExtended)(object)target).TriggerMaskClientRpc(playerClientId, executedMask, boolValueMask);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3892061111(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong playerClientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerClientId);
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				bool[] executed = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref executed, default(ForPrimitives));
				}
				bool flag2 = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag2, default(ForPrimitives));
				bool[] boolValues = null;
				if (flag2)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref boolValues, default(ForPrimitives));
				}
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((AnimatedObjectTriggerExtended)(object)target).TriggerArraysClientRpc(playerClientId, executed, boolValues);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "AnimatedObjectTriggerExtended";
		}
	}
	public class AnimationEventOneShotSound : MonoBehaviour
	{
		[SerializeField]
		private AudioClip clip;

		[SerializeField]
		private float volume = 1f;

		[SerializeField]
		private bool randomPitch;

		[SerializeField]
		private float minPitch = 0.95f;

		[SerializeField]
		private float maxPitch = 1.05f;

		private AudioSource audioSource;

		private void Awake()
		{
			audioSource = ((Component)this).GetComponent<AudioSource>();
			if ((Object)(object)audioSource == (Object)null)
			{
				audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			}
			audioSource.playOnAwake = false;
			audioSource.loop = false;
		}

		public void Play()
		{
			if (!((Object)(object)clip == (Object)null))
			{
				if (randomPitch)
				{
					audioSource.pitch = Random.Range(minPitch, maxPitch);
				}
				else
				{
					audioSource.pitch = 1f;
				}
				audioSource.PlayOneShot(clip, volume);
			}
		}
	}
	public sealed class AudioBounds : MonoBehaviour
	{
		private readonly HashSet<AudioSource> trackedAudioSources = new HashSet<AudioSource>();

		private readonly Dictionary<AudioSource, float> originalVolumes = new Dictionary<AudioSource, float>();

		private void OnTriggerEnter(Collider other)
		{
			AudioSource componentInParent = ((Component)other).GetComponentInParent<AudioSource>();
			if (!((Object)(object)componentInParent == (Object)null))
			{
				if (!trackedAudioSources.Contains(componentInParent))
				{
					trackedAudioSources.Add(componentInParent);
					originalVolumes[componentInParent] = componentInParent.volume;
				}
				componentInParent.Play();
			}
		}

		private void OnTriggerExit(Collider other)
		{
			AudioSource componentInParent = ((Component)other).GetComponentInParent<AudioSource>();
			if (!((Object)(object)componentInParent == (Object)null) && trackedAudioSources.Contains(componentInParent))
			{
				componentInParent.Stop();
			}
		}

		private void OnDisable()
		{
			foreach (AudioSource trackedAudioSource in trackedAudioSources)
			{
				if (!((Object)(object)trackedAudioSource == (Object)null))
				{
					trackedAudioSource.Play();
					trackedAudioSource.volume = originalVolumes[trackedAudioSource];
				}
			}
			trackedAudioSources.Clear();
			originalVolumes.Clear();
		}
	}
	public sealed class CanvasTrigger : MonoBehaviour
	{
		private sealed class TriggerRelay : MonoBehaviour
		{
			private CanvasTrigger owner;

			internal void SetOwner(CanvasTrigger ownerInstance)
			{
				owner = ownerInstance;
			}

			private void OnTriggerEnter(Collider other)
			{
				owner?.HandleTriggerEnter(other);
			}

			private void OnTriggerExit(Collider other)
			{
				owner?.HandleTriggerExit(other);
			}
		}

		[CompilerGenerated]
		private sealed class <Start>d__6 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public CanvasTrigger <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Start>d__6(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSecondsRealtime(<>4__this.startDelaySeconds);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)<>4__this.targetObject != (Object)null && <>4__this.localPlayerOverlapCount == 0)
					{
						<>4__this.targetObject.SetActive(false);
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[SerializeField]
		private BoxCollider triggerCollider;

		[SerializeField]
		private GameObject targetObject;

		[SerializeField]
		private bool localPlayerOnly = true;

		[SerializeField]
		private float startDelaySeconds = 2f;

		private int localPlayerOverlapCount;

		private void Awake()
		{
			if ((Object)(object)triggerCollider == (Object)null)
			{
				triggerCollider = ((Component)this).GetComponent<BoxCollider>();
			}
			if ((Object)(object)triggerCollider != (Object)null)
			{
				((Collider)triggerCollider).isTrigger = true;
				TriggerRelay triggerRelay = ((Component)triggerCollider).GetComponent<TriggerRelay>();
				if ((Object)(object)triggerRelay == (Object)null)
				{
					triggerRelay = ((Component)triggerCollider).gameObject.AddComponent<TriggerRelay>();
				}
				triggerRelay.SetOwner(this);
			}
			localPlayerOverlapCount = 0;
		}

		[IteratorStateMachine(typeof(<Start>d__6))]
		private IEnumerator Start()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Start>d__6(0)
			{
				<>4__this = this
			};
		}

		internal void HandleTriggerEnter(Collider other)
		{
			if (!IsRelevantPlayer(other))
			{
				return;
			}
			localPlayerOverlapCount++;
			if (localPlayerOverlapCount == 1)
			{
				GameObject obj = targetObject;
				if (obj != null)
				{
					obj.SetActive(true);
				}
			}
		}

		internal void HandleTriggerExit(Collider other)
		{
			if (!IsRelevantPlayer(other))
			{
				return;
			}
			if (localPlayerOverlapCount > 0)
			{
				localPlayerOverlapCount--;
			}
			if (localPlayerOverlapCount == 0)
			{
				GameObject obj = targetObject;
				if (obj != null)
				{
					obj.SetActive(false);
				}
			}
		}

		private bool IsRelevantPlayer(Collider other)
		{
			PlayerControllerB componentInParent = ((Component)other).GetComponentInParent<PlayerControllerB>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return false;
			}
			if (!localPlayerOnly)
			{
				return true;
			}
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			return componentInParent.playerClientId == val.playerClientId;
		}
	}
	public class CartIngotVisualDropper : MonoBehaviour
	{
		[SerializeField]
		private GameObject[] ingotsInDropOrder;

		private int currentIndex;

		public bool HasIngotsRemaining()
		{
			return currentIndex < ingotsInDropOrder.Length;
		}

		public int GetRemainingCount()
		{
			return ingotsInDropOrder.Length - currentIndex;
		}

		public int GetTotalCount()
		{
			return ingotsInDropOrder.Length;
		}

		public void DropNextIngot()
		{
			if (currentIndex < ingotsInDropOrder.Length)
			{
				GameObject val = ingotsInDropOrder[currentIndex];
				currentIndex++;
				if ((Object)(object)val != (Object)null)
				{
					val.SetActive(false);
				}
			}
		}

		public void SetRemainingCount(int remaining)
		{
			int num = ingotsInDropOrder.Length;
			remaining = Mathf.Clamp(remaining, 0, num);
			currentIndex = num - remaining;
			for (int i = 0; i < num; i++)
			{
				GameObject obj = ingotsInDropOrder[i];
				if (obj != null)
				{
					obj.SetActive(i >= currentIndex);
				}
			}
		}
	}
	internal class Destroy : MonoBehaviour
	{
		[SerializeField]
		private DestroyCondition[] destroyConditions;

		private void Awake()
		{
			for (int i = 0; i < destroyConditions.Length; i++)
			{
				if (IsConditionActive(destroyConditions[i]))
				{
					((Component)this).gameObject.SetActive(false);
					break;
				}
			}
		}

		private bool IsConditionActive(DestroyCondition condition)
		{
			switch (condition)
			{
			case DestroyCondition.DisableBloom:
				if (ConfigManager.HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)"[Config] Bloom disabled");
				}
				return ConfigManager.DisableBloom.Value;
			case DestroyCondition.DisableBathroomCamera:
				if (ConfigManager.HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)"[Config] Bathroom camera/mirror disabled");
				}
				return ConfigManager.DisableBathroomCamera.Value;
			case DestroyCondition.DisableHouseAmbience:
				if (ConfigManager.HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)"[Config] House ambience audio disabled");
				}
				return ConfigManager.DisableHouseAmbience.Value;
			case DestroyCondition.DisableCoreAmbience:
				if (ConfigManager.HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)"[Config] Core ambience audio disabled");
				}
				return ConfigManager.DisableCoreAmbience.Value;
			case DestroyCondition.HideMisideLogo:
				if (ConfigManager.HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)"[Config] Miside logo on basement monitor hidden");
				}
				return ConfigManager.HideMisideLogo.Value;
			default:
				return false;
			}
		}
	}
	public class DigitalClockDisplay : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <Tick>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public DigitalClockDisplay <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Tick>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					<>4__this.UpdateTime();
					break;
				}
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 1;
				return true;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[SerializeField]
		private Sprite[] numberSprites;

		[SerializeField]
		private Image hourTens;

		[SerializeField]
		private Image hourOnes;

		[SerializeField]
		private Image minuteTens;

		[SerializeField]
		private Image minuteOnes;

		private Coroutine tickRoutine;

		private void OnEnable()
		{
			UpdateTime();
			tickRoutine = ((MonoBehaviour)this).StartCoroutine(Tick());
		}

		private void OnDisable()
		{
			if (tickRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(tickRoutine);
			}
		}

		[IteratorStateMachine(typeof(<Tick>d__8))]
		private IEnumerator Tick()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Tick>d__8(0)
			{
				<>4__this = this
			};
		}

		private void UpdateTime()
		{
			DateTime now = DateTime.Now;
			int hour = now.Hour;
			int minute = now.Minute;
			hourTens.sprite = numberSprites[hour / 10];
			hourOnes.sprite = numberSprites[hour % 10];
			minuteTens.sprite = numberSprites[minute / 10];
			minuteOnes.sprite = numberSprites[minute % 10];
		}
	}
	public class DoorTrigger : MonoBehaviour
	{
		[SerializeField]
		private AudioSource audioSource;

		[SerializeField]
		private AudioClip audioClip;

		[SerializeField]
		private ParticleSystem particleSystemA;

		[SerializeField]
		private ParticleSystem particleSystemB;

		[SerializeField]
		private BoxCollider triggerCollider;

		private bool fired;

		private int localPlayerOverlapCount;

		private void Awake()
		{
			if ((Object)(object)triggerCollider != (Object)null)
			{
				((Collider)triggerCollider).isTrigger = true;
			}
			if ((Object)(object)audioSource == (Object)null)
			{
				audioSource = ((Component)this).GetComponent<AudioSource>();
			}
		}

		private void OnTriggerEnter(Collider other)
		{
			PlayerControllerB componentInParent = ((Component)other).GetComponentInParent<PlayerControllerB>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return;
			}
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null || componentInParent.playerClientId != val.playerClientId)
			{
				return;
			}
			localPlayerOverlapCount++;
			if (!fired)
			{
				fired = true;
				if ((Object)(object)particleSystemA != (Object)null)
				{
					particleSystemA.Stop(true, (ParticleSystemStopBehavior)0);
					particleSystemA.Play(true);
				}
				if ((Object)(object)particleSystemB != (Object)null)
				{
					particleSystemB.Stop(true, (ParticleSystemStopBehavior)0);
					particleSystemB.Play(true);
				}
				if ((Object)(object)audioSource != (Object)null && (Object)(object)audioClip != (Object)null)
				{
					audioSource.PlayOneShot(audioClip);
				}
			}
		}

		private void OnTriggerExit(Collider other)
		{
			PlayerControllerB componentInParent = ((Component)other).GetComponentInParent<PlayerControllerB>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return;
			}
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if (!((Object)(object)val == (Object)null) && componentInParent.playerClientId == val.playerClientId)
			{
				if (localPlayerOverlapCount > 0)
				{
					localPlayerOverlapCount--;
				}
				if (localPlayerOverlapCount == 0)
				{
					fired = false;
				}
			}
		}
	}
	public class EjectSound : MonoBehaviour
	{
		private Animator animator;

		private AudioSource audioSource;

		public AudioClip ejectSound;

		private bool hasEjected;

		private void Awake()
		{
			animator = ((Component)this).GetComponent<Animator>();
			audioSource = ((Component)this).GetComponent<AudioSource>();
		}

		internal void PlayEject()
		{
			if (!hasEjected)
			{
				hasEjected = true;
				Animator obj = animator;
				if (obj != null)
				{
					obj.SetTrigger("Eject");
				}
				if ((Object)(object)audioSource != (Object)null && (Object)(object)ejectSound != (Object)null)
				{
					audioSource.clip = ejectSound;
					audioSource.Play();
				}
			}
		}

		public void OnEjectAnimationFinished()
		{
			((Component)this).gameObject.SetActive(false);
		}
	}
	public class FurnitureScrapAnimate : MonoBehaviour
	{
		[SerializeField]
		public Transform[] animatedTransforms;

		private readonly Dictionary<Transform, Dictionary<Transform, Vector3>> drawerLocalPositions = new Dictionary<Transform, Dictionary<Transform, Vector3>>();

		private readonly Dictionary<Transform, Vector3> lastAnimatedWorldPos = new Dictionary<Transform, Vector3>();

		private readonly HashSet<Transform> tracking = new HashSet<Transform>();

		private static readonly List<Transform> keyCache = new List<Transform>();

		private void Awake()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (animatedTransforms == null)
			{
				return;
			}
			for (int i = 0; i < animatedTransforms.Length; i++)
			{
				Transform val = animatedTransforms[i];
				if (!((Object)(object)val == (Object)null))
				{
					drawerLocalPositions[val] = new Dictionary<Transform, Vector3>();
					lastAnimatedWorldPos[val] = val.position;
				}
			}
		}

		private void LateUpdate()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			if (animatedTransforms == null)
			{
				return;
			}
			for (int i = 0; i < animatedTransforms.Length; i++)
			{
				Transform val = animatedTransforms[i];
				if ((Object)(object)val == (Object)null || !drawerLocalPositions.TryGetValue(val, out var value))
				{
					continue;
				}
				Vector3 position = val.position;
				Vector3 val2 = position - lastAnimatedWorldPos[val];
				if (!tracking.Contains(val) && ((Vector3)(ref val2)).sqrMagnitude > 1E-06f)
				{
					tracking.Add(val);
				}
				if (tracking.Contains(val))
				{
					keyCache.Clear();
					foreach (Transform key in value.Keys)
					{
						keyCache.Add(key);
					}
					for (int j = 0; j < keyCache.Count; j++)
					{
						Transform val3 = keyCache[j];
						if ((Object)(object)val3 == (Object)null)
						{
							value.Remove(val3);
						}
						else if (!val3.IsChildOf(((Component)this).transform))
						{
							value.Remove(val3);
						}
						else
						{
							val3.position = val.TransformPoint(value[val3]);
						}
					}
				}
				lastAnimatedWorldPos[val] = position;
			}
		}

		public void RegisterDrawerItem(Transform animatedTransform, Transform item)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)animatedTransform == (Object)null) && !((Object)(object)item == (Object)null) && drawerLocalPositions.TryGetValue(animatedTransform, out var value) && !value.ContainsKey(item))
			{
				value[item] = animatedTransform.InverseTransformPoint(item.position);
			}
		}

		public void UnregisterDrawerItem(Transform animatedTransform, Transform item)
		{
			if (!((Object)(object)animatedTransform == (Object)null) && !((Object)(object)item == (Object)null) && drawerLocalPositions.TryGetValue(animatedTransform, out var value))
			{
				value.Remove(item);
			}
		}
	}
	public class MonitorPreviewImage : MonoBehaviour
	{
		[Serializable]
		internal struct PreviewEntry
		{
			[SerializeField]
			internal MonitorSelectable selectable;

			[SerializeField]
			internal Sprite image;
		}

		[SerializeField]
		private RectTransform previewImageShadow;

		[SerializeField]
		private Image previewImage;

		[SerializeField]
		private PreviewEntry[] previews;

		private MonitorSelectable currentSelectable;

		private void Awake()
		{
			RectTransform obj = previewImageShadow;
			if (obj != null)
			{
				((Component)obj).gameObject.SetActive(false);
			}
		}

		public void OnSelectableHovered(MonitorSelectable selectable)
		{
			if ((Object)(object)selectable == (Object)(object)currentSelectable)
			{
				return;
			}
			currentSelectable = selectable;
			if ((Object)(object)selectable == (Object)null)
			{
				Hide();
				return;
			}
			for (int i = 0; i < previews.Length; i++)
			{
				if ((Object)(object)previews[i].selectable == (Object)(object)selectable)
				{
					Show(previews[i].image);
					return;
				}
			}
			Hide();
		}

		private void Show(Sprite sprite)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)previewImageShadow == (Object)null) && !((Object)(object)previewImage == (Object)null) && !((Object)(object)sprite == (Object)null))
			{
				previewImage.sprite = sprite;
				float num = Random.Range(-4f, 4f);
				((Transform)previewImageShadow).localRotation = Quaternion.Euler(0f, 0f, num);
				((Component)previewImageShadow).gameObject.SetActive(true);
			}
		}

		private void Hide()
		{
			RectTransform obj = previewImageShadow;
			if (obj != null)
			{
				((Component)obj).gameObject.SetActive(false);
			}
		}
	}
	public class MonitorPurchaseSave : MonoBehaviour
	{
		private static readonly NamespacedKey HouseKey = NamespacedKey.From("misideitems", "houseteleporter");

		private readonly Dictionary<MonitorGroupID, int> groupIndexById = new Dictionary<MonitorGroupID, int>();

		private readonly Dictionary<MonitorSelectableGroup, int> groupIndexByGroup = new Dictionary<MonitorSelectableGroup, int>();

		private PersistentDataContainer contract;

		private long[] dataByGroup;

		private bool loadedFromContract;

		public bool TryGetGroupIndex(MonitorSelectableGroup group, out int index)
		{
			return groupIndexByGroup.TryGetValue(group, out index);
		}

		private void Awake()
		{
			contract = DawnLib.GetCurrentContract();
			long[] array = default(long[]);
			if (contract != null && ((DataContainer)contract).TryGet<long[]>(HouseKey, ref array) && array != null)
			{
				dataByGroup = array;
				loadedFromContract = true;
			}
			else
			{
				dataByGroup = null;
				loadedFromContract = false;
			}
			MonitorSelectableGroup[] componentsInChildren = ((Component)this).GetComponentsInChildren<MonitorSelectableGroup>(true);
			groupIndexById.Clear();
			groupIndexByGroup.Clear();
			List<MonitorSelectableGroup> list = new List<MonitorSelectableGroup>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null)
				{
					list.Add(componentsInChildren[i]);
				}
			}
			list.Sort((MonitorSelectableGroup a, MonitorSelectableGroup b) => a.groupId.CompareTo(b.groupId));
			for (int j = 0; j < list.Count; j++)
			{
				MonitorSelectableGroup key = list[j];
				groupIndexByGroup[key] = j;
			}
		}

		public bool IsPurchased(MonitorSelectableGroup group, MonitorSelectable selectable, int selectableIndexInGroup)
		{
			if ((Object)(object)group == (Object)null || (Object)(object)selectable == (Object)null)
			{
				return false;
			}
			string text = group?.DefaultSelectableKey;
			if (!string.IsNullOrEmpty(text) && (Object)(object)selectable != (Object)null && selectable.selectableKey == text)
			{
				return true;
			}
			if (!groupIndexByGroup.TryGetValue(group, out var value))
			{
				return false;
			}
			if (selectableIndexInGroup < 0 || selectableIndexInGroup > 62)
			{
				return false;
			}
			EnsureDataSize(groupIndexByGroup.Count);
			long num = dataByGroup[value];
			long num2 = 1L << selectableIndexInGroup;
			return (num & num2) != 0;
		}

		public void MarkPurchased(MonitorSelectableGroup group, int selectableIndexInGroup)
		{
			if (!((Object)(object)group == (Object)null) && groupIndexByGroup.TryGetValue(group, out var value) && selectableIndexInGroup >= 0 && selectableIndexInGroup <= 62)
			{
				EnsureDataSize(groupIndexByGroup.Count);
				long num = 1L << selectableIndexInGroup;
				long num2 = dataByGroup[value];
				if ((num2 & num) == 0)
				{
					dataByGroup[value] = num2 | num;
					Write();
				}
			}
		}

		public void SaveSelection(MonitorSelectableGroup group, int selectableIndexInGroup)
		{
			if (!((Object)(object)group == (Object)null) && groupIndexByGroup.TryGetValue(group, out var value))
			{
				EnsureDataSize(groupIndexByGroup.Count);
				int count = groupIndexByGroup.Count;
				long num = ((selectableIndexInGroup < 0) ? 0 : ((long)selectableIndexInGroup + 1L));
				dataByGroup[count + value] = num;
				Write();
			}
		}

		public bool TryRestoreSelection(MonitorSelectableGroup group)
		{
			if ((Object)(object)group == (Object)null)
			{
				return false;
			}
			if (!groupIndexByGroup.TryGetValue(group, out var value))
			{
				return false;
			}
			EnsureDataSize(groupIndexByGroup.Count);
			int count = groupIndexByGroup.Count;
			long num = dataByGroup[count + value];
			if (num <= 0)
			{
				return false;
			}
			int num2 = (int)num - 1;
			if (group.groupedSelectables == null || num2 < 0 || num2 >= group.groupedSelectables.Length)
			{
				return false;
			}
			MonitorSelectable monitorSelectable = group.groupedSelectables[num2];
			if ((Object)(object)monitorSelectable == (Object)null)
			{
				return false;
			}
			MonitorSelectablePurchase component = ((Component)monitorSelectable).GetComponent<MonitorSelectablePurchase>();
			if ((Object)(object)component != (Object)null && !IsPurchased(group, monitorSelectable, num2))
			{
				return false;
			}
			group.ForceActivate(monitorSelectable);
			return true;
		}

		private void EnsureDataSize(int groupCount)
		{
			int num = groupCount * 2;
			if (dataByGroup != null && dataByGroup.Length == num)
			{
				return;
			}
			long[] array = new long[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = 0L;
			}
			if (dataByGroup != null)
			{
				if (dataByGroup.Length == groupCount)
				{
					for (int j = 0; j < groupCount; j++)
					{
						array[j] = dataByGroup[j];
					}
				}
				else
				{
					int num2 = Mathf.Min(dataByGroup.Length, array.Length);
					for (int k = 0; k < num2; k++)
					{
						array[k] = dataByGroup[k];
					}
				}
			}
			dataByGroup = array;
		}

		private void Write()
		{
			if (contract == null || ((Object)(object)NetworkManager.Singleton != (Object)null && !NetworkManager.Singleton.IsServer))
			{
				return;
			}
			using (((DataContainer)contract).CreateEditContext())
			{
				((DataContainer)contract).Set<long[]>(HouseKey, dataByGroup);
			}
		}

		private void EnsureLoaded()
		{
			if (contract == null)
			{
				contract = DawnLib.GetCurrentContract();
			}
			long[] array = default(long[]);
			if (dataByGroup == null && contract != null && ((DataContainer)contract).TryGet<long[]>(HouseKey, ref array) && array != null)
			{
				dataByGroup = array;
				loadedFromContract = true;
			}
		}
	}
	public class MonitorScreen : MonoBehaviour
	{
		[SerializeField]
		private float maxDistance = 5f;

		[SerializeField]
		private LayerMask cursorLayerMask;

		[SerializeField]
		private LayerMask interactableLayerMask;

		[SerializeField]
		private BoxCollider monitorSurfaceCollider;

		[SerializeField]
		private RectTransform cursorRect;

		[SerializeField]
		private TMP_Text creditsText;

		[SerializeField]
		private MonitorPreviewImage[] previewImages;

		private MonitorSelectable currentHovered;

		private Terminal vanillaTerminal;

		private InputAction selectAction;

		public bool TryGetDefaultSelectableKey(MonitorGroupID groupId, out string defaultSelectableKey)
		{
			defaultSelectableKey = null;
			if (Plugin.Configs != null && Plugin.Configs.TryGetMonitorDefaultSelectableKey(groupId, out var defaultSelectableKey2))
			{
				defaultSelectableKey = defaultSelectableKey2;
				return true;
			}
			return false;
		}

		private void OnEnable()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			selectAction = new InputAction("MonitorSelect", (InputActionType)1, "<Mouse>/leftButton", (string)null, (string)null, (string)null);
			selectAction.performed += delegate
			{
				TrySelectCurrent();
			};
			selectAction.Enable();
		}

		private void OnDisable()
		{
			if (selectAction != null)
			{
				selectAction.Disable();
				selectAction.Dispose();
				selectAction = null;
			}
		}

		private void TrySelectCurrent()
		{
			if ((Object)(object)currentHovered != (Object)null)
			{
				currentHovered.Select(this);
			}
		}

		private void Update()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if ((Object)(object)localPlayerController == (Object)null || (Object)(object)localPlayerController.playerEye == (Object)null)
			{
				return;
			}
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(localPlayerController.playerEye.position, localPlayerController.playerEye.forward);
			if (TryGetSurfaceHit(val, out var surfaceHit) && (Object)(object)cursorRect != (Object)null)
			{
				Vector3 val2 = ((Component)monitorSurfaceCollider).transform.InverseTransformPoint(((RaycastHit)(ref surfaceHit)).point);
				Vector3 center = monitorSurfaceCollider.center;
				Vector3 size = monitorSurfaceCollider.size;
				float num = (val2.x - center.x) / size.x + 0.5f;
				float num2 = (val2.y - center.y) / size.y + 0.5f;
				num = Mathf.Clamp01(num);
				num2 = Mathf.Clamp01(num2);
				Transform transform = ((Component)((Component)cursorRect).GetComponentInParent<Canvas>()).transform;
				RectTransform val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if ((Object)(object)val3 != (Object)null)
				{
					Rect rect = val3.rect;
					Vector2 val4 = ((Rect)(ref rect)).size * 0.5f;
					rect = cursorRect.rect;
					Vector2 val5 = ((Rect)(ref rect)).size * 0.5f;
					float num3 = num - 0.5f;
					rect = val3.rect;
					float num4 = num3 * ((Rect)(ref rect)).width;
					float num5 = num2 - 0.5f;
					rect = val3.rect;
					float num6 = num5 * ((Rect)(ref rect)).height;
					num4 = Mathf.Clamp(num4, 0f - val4.x + val5.x, val4.x - val5.x);
					num6 = Mathf.Clamp(num6, 0f - val4.y + val5.y, val4.y - val5.y);
					cursorRect.anchoredPosition = new Vector2(num4, num6);
				}
			}
			RaycastHit val6 = default(RaycastHit);
			if (!Physics.Raycast(val, ref val6, maxDistance, LayerMask.op_Implicit(interactableLayerMask)))
			{
				ClearHover();
			}
			else
			{
				MonitorSelectable componentInParent = ((Component)((RaycastHit)(ref val6)).collider).GetComponentInParent<MonitorSelectable>();
				if ((Object)(object)componentInParent == (Object)null)
				{
					ClearHover();
				}
				else if ((Object)(object)componentInParent != (Object)(object)currentHovered)
				{
					currentHovered?.SetHighlighted(highlighted: false);
					currentHovered = componentInParent;
					currentHovered.SetHighlighted(highlighted: true);
					for (int i = 0; i < previewImages.Length; i++)
					{
						previewImages[i]?.OnSelectableHovered(currentHovered);
					}
				}
			}
			if ((Object)(object)creditsText != (Object)null)
			{
				if ((Object)(object)vanillaTerminal == (Object)null)
				{
					vanillaTerminal = Object.FindObjectOfType<Terminal>();
				}
				if ((Object)(object)vanillaTerminal != (Object)null)
				{
					creditsText.text = vanillaTerminal.groupCredits + " credits";
				}
			}
		}

		private void ClearHover()
		{
			if ((Object)(object)currentHovered != (Object)null)
			{
				currentHovered.SetHighlighted(highlighted: false);
				currentHovered = null;
			}
			for (int i = 0; i < previewImages.Length; i++)
			{
				previewImages[i]?.OnSelectableHovered(null);
			}
		}

		private bool TryGetSurfaceHit(Ray ray, out RaycastHit surfaceHit)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			surfaceHit = default(RaycastHit);
			if ((Object)(object)monitorSurfaceCollider == (Object)null)
			{
				return false;
			}
			RaycastHit[] array = Physics.RaycastAll(ray, maxDistance, LayerMask.op_Implicit(cursorLayerMask), (QueryTriggerInteraction)1);
			bool result = false;
			float num = float.MaxValue;
			for (int i = 0; i < array.Length; i++)
			{
				if (!((Object)(object)((RaycastHit)(ref array[i])).collider != (Object)(object)monitorSurfaceCollider))
				{
					float distance = ((RaycastHit)(ref array[i])).distance;
					if (distance < num)
					{
						num = distance;
						surfaceHit = array[i];
						result = true;
					}
				}
			}
			return result;
		}
	}
	public class MonitorSelectable : MonoBehaviour
	{
		[Header("Identity")]
		[SerializeField]
		internal string selectableKey;

		[SerializeField]
		private BoxCollider hitCollider;

		[SerializeField]
		private Image background;

		[SerializeField]
		private Color highlightColor = Color.white;

		[SerializeField]
		private TextMeshProUGUI text;

		[SerializeField]
		private Color textHighlightColor = Color.black;

		[SerializeField]
		private TMP_FontAsset textHighlightFont;

		[SerializeField]
		private AudioSource audioSource;

		[SerializeField]
		private AudioClip hoverSfx;

		[SerializeField]
		private AudioClip selectSfx;

		[SerializeField]
		private Animator animator;

		[SerializeField]
		private string listBoolName;

		[SerializeField]
		private Animator mainMenuAnimator;

		[SerializeField]
		private string menuBoolName;

		[SerializeField]
		internal MonitorSelectableAction actionTarget;

		[SerializeField]
		private GameObject tickObject;

		private bool isHighlighted;

		private bool hoverSoundPlayed;

		private Color originalBackgroundColor;

		private Color originalTextColor;

		private TMP_FontAsset originalFont;

		private void Awake()
		{
			//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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(selectableKey))
			{
				selectableKey = ((Object)((Component)this).gameObject).name;
			}
			GameObject obj = tickObject;
			if (obj != null)
			{
				obj.SetActive(false);
			}
			if ((Object)(object)background != (Object)null)
			{
				originalBackgroundColor = ((Graphic)background).color;
			}
			if ((Object)(object)text != (Object)null)
			{
				originalTextColor = ((Graphic)text).color;
				originalFont = ((TMP_Text)text).font;
			}
		}

		public void SetTickVisible(bool visible)
		{
			GameObject obj = tickObject;
			if (obj != null)
			{
				obj.SetActive(visible);
			}
		}

		public void SetHighlighted(bool highlighted)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (isHighlighted == highlighted)
			{
				return;
			}
			isHighlighted = highlighted;
			if ((Object)(object)background != (Object)null)
			{
				((Graphic)background).color = (highlighted ? highlightColor : originalBackgroundColor);
			}
			if ((Object)(object)text != (Object)null)
			{
				((Graphic)text).color = (highlighted ? textHighlightColor : originalTextColor);
				((TMP_Text)text).font = ((highlighted && (Object)(object)textHighlightFont != (Object)null) ? textHighlightFont : originalFont);
			}
			if (highlighted)
			{
				if (!hoverSoundPlayed && (Object)(object)audioSource != (Object)null && (Object)(object)hoverSfx != (Object)null)
				{
					audioSource.PlayOneShot(hoverSfx);
				}
				hoverSoundPlayed = true;
			}
			else
			{
				hoverSoundPlayed = false;
			}
		}

		public void Select(MonitorScreen screen)
		{
			MonitorSelectablePurchase component = ((Component)this).GetComponent<MonitorSelectablePurchase>();
			if ((Object)(object)audioSource != (Object)null && (Object)(object)selectSfx != (Object)null)
			{
				audioSource.PlayOneShot(selectSfx);
			}
			if (!((Object)(object)component != (Object)null) || component.IsPurchased() || component.TryPurchase())
			{
				if ((Object)(object)mainMenuAnimator != (Object)null && !string.IsNullOrEmpty(menuBoolName))
				{
					bool @bool = mainMenuAnimator.GetBool(menuBoolName);
					mainMenuAnimator.SetBool(menuBoolName, !@bool);
				}
				if ((Object)(object)animator != (Object)null && !string.IsNullOrEmpty(listBoolName))
				{
					bool bool2 = animator.GetBool(listBoolName);
					animator.SetBool(listBoolName, !bool2);
				}
				actionTarget?.Activate(this);
			}
		}
	}
	public class MonitorSelectableAction : MonoBehaviour
	{
		[Serializable]
		public struct ParticleMaterialEntry
		{
			public ParticleSystemRenderer particleRenderer;

			public bool applyMaterial;
		}

		[Header("Group")]
		[SerializeField]
		internal MonitorSelectableGroup selectableGroup;

		[Header("Box Collider Toggle")]
		[SerializeField]
		private BoxCollider[] targetBoxColliders;

		[SerializeField]
		private bool boxColliderFlippable;

		[SerializeField]
		private bool boxColliderPersistOnlyWhileTrue;

		[Header("Mesh Renderer Toggle")]
		[SerializeField]
		private MeshRenderer[] toggleMeshRenderers;

		[SerializeField]
		private bool meshRendererFlippable;

		[SerializeField]
		private bool meshRendererPersistOnlyWhileTrue;

		[Header("Mesh Renderer Swapper")]
		[SerializeField]
		private MeshRenderer[] targetMeshRenderers;

		[SerializeField]
		private Material meshRendererMaterial;

		[SerializeField]
		private bool isForElement0;

		[SerializeField]
		private bool isForElement1;

		[SerializeField]
		private bool isForElement2;

		[SerializeField]
		private bool isForElement3;

		[Header("Mesh Filter Swapper")]
		[SerializeField]
		private MeshFilter[] targetMeshFilters;

		[SerializeField]
		private Mesh meshFilterMesh;

		[Header("Mesh Collider Swapper")]
		[SerializeField]
		private MeshCollider meshColliderSelection;

		[SerializeField]
		private MeshCollider meshColliderTarget;

		[SerializeField]
		private bool meshColliderFlippable;

		[SerializeField]
		private bool meshColliderPersistOnlyWhileTrue;

		[Header("Particle System Material Swapper")]
		[SerializeField]
		private ParticleMaterialEntry[] particleMaterialEntries;

		[SerializeField]
		private Material particleSystemMaterial;

		[Header("GameObject Toggle")]
		[SerializeField]
		private GameObject[] targetGameObjects;

		[SerializeField]
		private bool flippable;

		[SerializeField]
		private bool persistOnlyWhileTrue;

		[Header("Audio Swapper")]
		[SerializeField]
		private AudioSource audioSource;

		[SerializeField]
		private AudioClip audioClip;

		private bool isActive;

		private int groupIndexInSave = -1;

		private int selectableIndexInGroup = -1;

		private Mesh[] originalMeshes;

		private bool originalSelectionColliderState;

		private bool originalTargetColliderState;

		private bool meshColliderOriginalCaptured;

		private bool[] baselineGameObjectStates;

		private bool[] baselineBoxColliderStates;

		private bool[] baselineMeshRendererStates;

		public void ApplyForced()
		{
			SetInactive();
			SetActive();
		}

		private void Awake()
		{
			if (targetGameObjects != null && baselineGameObjectStates == null)
			{
				baselineGameObjectStates = new bool[targetGameObjects.Length];
				for (int i = 0; i < targetGameObjects.Length; i++)
				{
					baselineGameObjectStates[i] = (Object)(object)targetGameObjects[i] != (Object)null && targetGameObjects[i].activeSelf;
				}
			}
			if (targetBoxColliders != null && baselineBoxColliderStates == null)
			{
				baselineBoxColliderStates = new bool[targetBoxColliders.Length];
				for (int j = 0; j < targetBoxColliders.Length; j++)
				{
					baselineBoxColliderStates[j] = (Object)(object)targetBoxColliders[j] != (Object)null && ((Collider)targetBoxColliders[j]).enabled;
				}
			}
			if (toggleMeshRenderers != null && baselineMeshRendererStates == null)
			{
				baselineMeshRendererStates = new bool[toggleMeshRenderers.Length];
				for (int k = 0; k < toggleMeshRenderers.Length; k++)
				{
					baselineMeshRendererStates[k] = (Object)(object)toggleMeshRenderers[k] != (Object)null && ((Renderer)toggleMeshRenderers[k]).enabled;
				}
			}
		}

		private void Start()
		{
			if ((Object)(object)selectableGroup == (Object)null)
			{
				selectableGroup = ((Component)this).GetComponentInParent<MonitorSelectableGroup>();
			}
			EnsureSelectableGroup();
			MonitorPurchaseSave monitorPurchaseSave = ResolvePurchaseSave();
			if (!((Object)(object)monitorPurchaseSave == (Object)null) && !((Object)(object)selectableGroup == (Object)null))
			{
				monitorPurchaseSave.TryGetGroupIndex(selectableGroup, out groupIndexInSave);
			}
		}

		public void Activate(MonitorSelectable selectable)
		{
			if ((Object)(object)selectableGroup == (Object)null)
			{
				selectableGroup = ((Component)this).GetComponentInParent<MonitorSelectableGroup>();
			}
			EnsureSelectableGroup();
			if ((Object)(object)selectableGroup == (Object)null)
			{
				return;
			}
			int num = Array.IndexOf(selectableGroup.groupedSelectables, selectable);
			if (num < 0)
			{
				return;
			}
			bool flag = selectableGroup.IsCurrentActive(selectable);
			if ((flippable || meshColliderFlippable || boxColliderFlippable || meshRendererFlippable) && flag)
			{
				num = -1;
			}
			MonitorPurchaseSave monitorPurchaseSave = ResolvePurchaseSave();
			if (!((Object)(object)monitorPurchaseSave == (Object)null) && monitorPurchaseSave.TryGetGroupIndex(selectableGroup, out var index))
			{
				MonitorActionSync monitorActionSync = Object.FindObjectOfType<MonitorActionSync>();
				if (!((Object)(object)monitorActionSync == (Object)null))
				{
					monitorActionSync.RequestAction(index, num);
				}
			}
		}

		private void EnsureSelectableGroup()
		{
			if (!((Object)(object)selectableGroup != (Object)null))
			{
				selectableGroup = ((Component)this).GetComponentInParent<MonitorSelectableGroup>(true);
			}
		}

		private MonitorPurchaseSave ResolvePurchaseSave()
		{
			MonitorPurchaseSave componentInParent = ((Component)this).GetComponentInParent<MonitorPurchaseSave>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return componentInParent;
			}
			return Object.FindObjectOfType<MonitorPurchaseSave>(true);
		}

		private void SetInactive()
		{
			if (persistOnlyWhileTrue && targetGameObjects != null && baselineGameObjectStates != null)
			{
				int num = Mathf.Min(targetGameObjects.Length, baselineGameObjectStates.Length);
				for (int i = 0; i < num; i++)
				{
					GameObject obj = targetGameObjects[i];
					if (obj != null)
					{
						obj.SetActive(baselineGameObjectStates[i]);
					}
				}
			}
			if (boxColliderPersistOnlyWhileTrue && targetBoxColliders != null && baselineBoxColliderStates != null)
			{
				int num2 = Mathf.Min(targetBoxColliders.Length, baselineBoxColliderStates.Length);
				for (int j = 0; j < num2; j++)
				{
					BoxCollider val = targetBoxColliders[j];
					if ((Object)(object)val != (Object)null)
					{
						((Collider)val).enabled = baselineBoxColliderStates[j];
					}
				}
			}
			if (meshRendererPersistOnlyWhileTrue && toggleMeshRenderers != null && baselineMeshRendererStates != null)
			{
				int num3 = Mathf.Min(toggleMeshRenderers.Length, baselineMeshRendererStates.Length);
				for (int k = 0; k < num3; k++)
				{
					MeshRenderer val2 = toggleMeshRenderers[k];
					if ((Object)(object)val2 != (Object)null)
					{
						((Renderer)val2).enabled = baselineMeshRendererStates[k];
					}
				}
			}
			isActive = false;
			if ((Object)(object)audioSource != (Object)null && (audioSource.isPlaying || (Object)(object)audioSource.clip != (Object)null))
			{
				audioSource.Stop();
				audioSource.clip = null;
			}
			if (flippable && persistOnlyWhileTrue && originalMeshes != null && targetMeshFilters != null)
			{
				for (int l = 0; l < targetMeshFilters.Length; l++)
				{
					if ((Object)(object)targetMeshFilters[l] != (Object)null)
					{
						targetMeshFilters[l].mesh = originalMeshes[l];
					}
				}
				originalMeshes = null;
			}
			if (meshColliderPersistOnlyWhileTrue && meshColliderOriginalCaptured)
			{
				if ((Object)(object)meshColliderSelection != (Object)null)
				{
					((Collider)meshColliderSelection).enabled = originalSelectionColliderState;
				}
				if ((Object)(object)meshColliderTarget != (Object)null)
				{
					((Collider)meshColliderTarget).enabled = originalTargetColliderState;
				}
				meshColliderOriginalCaptured = false;
			}
		}

		public void OnDeactivated()
		{
			SetInactive();
		}

		private void SetActive()
		{
			if (flippable && persistOnlyWhileTrue && !isActive && targetMeshFilters != null && originalMeshes == null)
			{
				originalMeshes = (Mesh[])(object)new Mesh[targetMeshFilters.Length];
				for (int i = 0; i < targetMeshFilters.Length; i++)
				{
					if ((Object)(object)targetMeshFilters[i] != (Object)null)
					{
						originalMeshes[i] = targetMeshFilters[i].mesh;
					}
				}
			}
			if (meshColliderPersistOnlyWhileTrue && !meshColliderOriginalCaptured)
			{
				if ((Object)(object)meshColliderSelection != (Object)null)
				{
					originalSelectionColliderState = ((Collider)meshColliderSelection).enabled;
				}
				if ((Object)(object)meshColliderTarget != (Object)null)
				{
					originalTargetColliderState = ((Collider)meshColliderTarget).enabled;
				}
				meshColliderOriginalCaptured = true;
			}
			isActive = true;
			if (targetGameObjects != null && baselineGameObjectStates != null)
			{
				int num = Mathf.Min(targetGameObjects.Length, baselineGameObjectStates.Length);
				for (int j = 0; j < num; j++)
				{
					GameObject obj = targetGameObjects[j];
					if (obj != null)
					{
						obj.SetActive(!baselineGameObjectStates[j]);
					}
				}
			}
			if (targetBoxColliders != null && baselineBoxColliderStates != null)
			{
				int num2 = Mathf.Min(targetBoxColliders.Length, baselineBoxColliderStates.Length);
				for (int k = 0; k < num2; k++)
				{
					BoxCollider val = targetBoxColliders[k];
					if ((Object)(object)val != (Object)null)
					{
						((Collider)val).enabled = !baselineBoxColliderStates[k];
					}
				}
			}
			if (toggleMeshRenderers != null && baselineMeshRendererStates != null)
			{
				int num3 = Mathf.Min(toggleMeshRenderers.Length, baselineMeshRendererStates.Length);
				for (int l = 0; l < num3; l++)
				{
					MeshRenderer val2 = toggleMeshRenderers[l];
					if ((Object)(object)val2 != (Object)null)
					{
						((Renderer)val2).enabled = !baselineMeshRendererStates[l];
					}
				}
			}
			if ((Object)(object)meshRendererMaterial != (Object)null && targetMeshRenderers != null)
			{
				for (int m = 0; m < targetMeshRenderers.Length; m++)
				{
					MeshRenderer val3 = targetMeshRenderers[m];
					if (!((Object)(object)val3 == (Object)null))
					{
						Material[] materials = ((Renderer)val3).materials;
						if (isForElement0 && materials.Length != 0)
						{
							materials[0] = meshRendererMaterial;
						}
						if (isForElement1 && materials.Length > 1)
						{
							materials[1] = meshRendererMaterial;
						}
						if (isForElement2 && materials.Length > 2)
						{
							materials[2] = meshRendererMaterial;
						}
						if (isForElement3 && materials.Length > 3)
						{
							materials[3] = meshRendererMaterial;
						}
						((Renderer)val3).materials = materials;
					}
				}
			}
			if ((Object)(object)meshFilterMesh != (Object)null && targetMeshFilters != null)
			{
				for (int n = 0; n < targetMeshFilters.Length; n++)
				{
					if ((Object)(object)targetMeshFilters[n] != (Object)null)
					{
						targetMeshFilters[n].mesh = meshFilterMesh;
					}
				}
			}
			if ((Object)(object)meshColliderSelection != (Object)null)
			{
				((Collider)meshColliderSelection).enabled = false;
			}
			if ((Object)(object)meshColliderTarget != (Object)null)
			{
				((Collider)meshColliderTarget).enabled = true;
			}
			if (particleMaterialEntries != null && (Object)(object)particleSystemMaterial != (Object)null)
			{
				for (int num4 = 0; num4 < particleMaterialEntries.Length; num4++)
				{
					ParticleMaterialEntry particleMaterialEntry = particleMaterialEntries[num4];
					if (!((Object)(object)particleMaterialEntry.particleRenderer == (Object)null))
					{
						if (particleMaterialEntry.applyMaterial)
						{
							((Renderer)particleMaterialEntry.particleRenderer).material = particleSystemMaterial;
						}
						else
						{
							((Renderer)particleMaterialEntry.particleRenderer).enabled = false;
						}
					}
				}
			}
			if ((Object)(object)audioSource != (Object)null)
			{
				if (audioSource.isPlaying)
				{
					audioSource.Stop();
				}
				if ((Object)(object)audioClip == (Object)null)
				{
					audioSource.clip = null;
					return;
				}
				audioSource.clip = audioClip;
				audioSource.Play();
			}
		}
	}
	public class MonitorSelectableGroup : MonoBehaviour
	{
		[Header("Group ID")]
		[SerializeField]
		internal MonitorGroupID groupId;

		[Header("Selectables")]
		[SerializeField]
		internal MonitorSelectable[] groupedSelectables;

		private MonitorSelectable currentActive;

		public string DefaultSelectableKey
		{
			get
			{
				if (Plugin.Configs != null && Plugin.Configs.TryGetMonitorDefaultSelectableKey(groupId, out var defaultSelectableKey))
				{
					return defaultSelectableKey;
				}
				return null;
			}
		}

		private void Start()
		{
			if (ConfigManager.HouseDebugLogs.Value)
			{
				ManualLogSource mls = Plugin.mls;
				object arg = groupId;
				MonitorSelectable[] array = groupedSelectables;
				mls.LogDebug((object)$"[Group Init] {arg} | Selectables = {((array != null) ? array.Length : 0)}");
			}
			for (int i = 0; i < groupedSelectables.Length; i++)
			{
				MonitorSelectable monitorSelectable = groupedSelectables[i];
				if ((Object)(object)monitorSelectable == (Object)null)
				{
					if (ConfigManager.HouseDebugLogs.Value)
					{
						Plugin.mls.LogDebug((object)$"[Group Init] {groupId} | Index {i} = NULL");
					}
					continue;
				}
				if (ConfigManager.HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)$"[Group Init] {groupId} | Index {i} | Key = '{monitorSelectable.selectableKey}'");
				}
				monitorSelectable.SetTickVisible(visible: false);
			}
			((MonoBehaviour)this).Invoke("ApplyInitialSelection", 0f);
		}

		private void ApplyInitialSelection()
		{
			MonitorPurchaseSave componentInParent = ((Component)this).GetComponentInParent<MonitorPurchaseSave>(true);
			if ((Object)(object)componentInParent != (Object)null && componentInParent.TryRestoreSelection(this))
			{
				return;
			}
			string defaultSelectableKey = DefaultSelectableKey;
			if (ConfigManager.HouseDebugLogs.Value)
			{
				Plugin.mls.LogDebug((object)string.Format("[Default Apply] Group {0} | DefaultKey = '{1}'", groupId, defaultSelectableKey ?? "NULL"));
			}
			if (string.IsNullOrEmpty(defaultSelectableKey))
			{
				return;
			}
			for (int i = 0; i < groupedSelectables.Length; i++)
			{
				MonitorSelectable monitorSelectable = groupedSelectables[i];
				if ((Object)(object)monitorSelectable == (Object)null)
				{
					continue;
				}
				if (ConfigManager.HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)("[Default Apply] Compare '" + monitorSelectable.selectableKey + "' vs '" + defaultSelectableKey + "'"));
				}
				if (monitorSelectable.selectableKey == defaultSelectableKey)
				{
					if (ConfigManager.HouseDebugLogs.Value)
					{
						Plugin.mls.LogDebug((object)$"[Default Apply] MATCH -> Activating '{defaultSelectableKey}' in group {groupId}");
					}
					ForceActivate(monitorSelectable);
					return;
				}
			}
			if (ConfigManager.HouseDebugLogs.Value)
			{
				Plugin.mls.LogDebug((object)$"[Default Apply] NO MATCH FOUND for '{defaultSelectableKey}' in group {groupId}");
			}
		}

		public bool CanActivate(MonitorSelectable selectable)
		{
			if ((Object)(object)currentActive == (Object)(object)selectable)
			{
				return false;
			}
			SetActiveInternal(selectable);
			return true;
		}

		public void ForceActivate(MonitorSelectable selectable)
		{
			SetActiveInternal(selectable);
			if ((Object)(object)selectable != (Object)null && (Object)(object)selectable.actionTarget != (Object)null)
			{
				selectable.actionTarget.ApplyForced();
			}
		}

		private void SetActiveInternal(MonitorSelectable selectable)
		{
			if ((Object)(object)currentActive != (Object)null)
			{
				currentActive.SetTickVisible(visible: false);
				currentActive.actionTarget?.OnDeactivated();
			}
			currentActive = selectable;
			currentActive?.SetTickVisible(visible: true);
		}

		public bool IsCurrentActive(MonitorSelectable selectable)
		{
			return (Object)(object)currentActive == (Object)(object)selectable;
		}

		public void ClearActive()
		{
			currentActive?.SetTickVisible(visible: false);
			currentActive = null;
		}

		public void ClearActiveWithDeactivate()
		{
			if ((Object)(object)currentActive != (Object)null)
			{
				currentActive.SetTickVisible(visible: false);
				currentActive.actionTarget?.OnDeactivated();
			}
			currentActive = null;
		}

		internal static bool KeysMatch(string a, string b)
		{
			string text = NormalizeKey(a);
			string text2 = NormalizeKey(b);
			if (text == null || text2 == null)
			{
				return false;
			}
			return text == text2;
		}

		private static string NormalizeKey(string key)
		{
			if (string.IsNullOrWhiteSpace(key))
			{
				return null;
			}
			char[] array = new char[key.Length];
			int num = 0;
			foreach (char c in key)
			{
				if (char.IsLetterOrDigit(c))
				{
					array[num] = char.ToLowerInvariant(c);
					num++;
				}
			}
			return (num == 0) ? null : new string(array, 0, num);
		}
	}
	public class MonitorSelectablePurchase : MonoBehaviour
	{
		[SerializeField]
		private TMP_Text creditsNumber;

		[SerializeField]
		private Image lockImage;

		[SerializeField]
		private Image crossImage;

		[SerializeField]
		private AudioSource audioSource;

		[SerializeField]
		private AudioClip purchaseSuccessful;

		[SerializeField]
		private AudioClip purchaseUnsuccessful;

		[SerializeField]
		private int price;

		private bool purchased;

		private Terminal terminal;

		private MonitorSelectable selectable;

		private MonitorSelectableGroup selectableGroup;

		private MonitorPurchaseSave purchaseSave;

		private int selectableIndexInGroup;

		private bool purchasedSynced;

		private int groupIndexInSave = -1;

		private void Awake()
		{
			terminal = Object.FindObjectOfType<Terminal>();
			selectable = ((Component)this).GetComponent<MonitorSelectable>();
			selectableGroup = selectable?.actionTarget?.selectableGroup;
			if ((Object)(object)selectableGroup == (Object)null)
			{
				selectableGroup = ((Component)this).GetComponentInParent<MonitorSelectableGroup>();
			}
			if ((Object)(object)selectable != (Object)null && (Object)(object)selectable.actionTarget != (Object)null && (Object)(object)selectable.actionTarget.selectableGroup == (Object)null)
			{
				selectable.actionTarget.selectableGroup = selectableGroup;
			}
			selectableIndexInGroup = FindSelectableIndexInGroup(selectableGroup, selectable);
			ConfigEntry<int> entry;
			if ((Object)(object)selectableGroup == (Object)null || (Object)(object)selectable == (Object)null || Plugin.Configs == null)
			{
				if (ConfigManager.HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)$"[Prices] Missing refs. GroupNull={(Object)(object)selectableGroup == (Object)null} SelectableNull={(Object)(object)selectable == (Object)null} ConfigNull={Plugin.Configs == null}");
				}
				price = int.MaxValue;
			}
			else if (!Plugin.Configs.TryGetMonitorPriceEntry(selectableGroup.groupId, selectable.selectableKey, out entry))
			{
				if (ConfigManager.HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)$"[Prices] No config entry for {selectableGroup.groupId} | Key '{selectable.selectableKey}'");
				}
				price = int.MaxValue;
			}
			else
			{
				if (entry.Value < 0)
				{
					entry.Value = price;
					((BaseUnityPlugin)Plugin.Instance).Config.Save();
					if (ConfigManager.HouseDebugLogs.Value)
					{
						Plugin.mls.LogDebug((object)$"[Prices] Initialized {selectableGroup.groupId} | Key '{selectable.selectableKey}' -> {entry.Value}");
					}
				}
				price = entry.Value;
			}
			if ((Object)(object)creditsNumber != (Object)null)
			{
				creditsNumber.text = price + "c";
			}
		}

		private void Start()
		{
			purchaseSave = ((Component)this).GetComponentInParent<MonitorPurchaseSave>();
			if ((Object)(object)purchaseSave != (Object)null && (Object)(object)selectableGroup != (Object)null)
			{
				purchaseSave.TryGetGroupIndex(selectableGroup, out groupIndexInSave);
			}
			string text = selectableGroup?.DefaultSelectableKey;
			if (!string.IsNullOrEmpty(text) && (Object)(object)selectable != (Object)null && selectable.selectableKey == text)
			{
				purchased = true;
				DestroyPurchaseUI();
				return;
			}
			if (ConfigManager.HouseDebugLogs.Value)
			{
				Plugin.mls.LogDebug((object)string.Format("[Purchase Init] Group {0} | Selectable '{1}' | Default = '{2}'", selectableGroup?.groupId, selectable?.selectableKey, text ?? "NULL"));
			}
			if ((Object)(object)purchaseSave != (Object)null && purchaseSave.IsPurchased(selectableGroup, selectable, selectableIndexInGroup))
			{
				if (ConfigManager.HouseDebugLogs.Value)
				{
					Plugin.mls.LogDebug((object)("[Purchase Init] '" + selectable.selectableKey + "' is DEFAULT -> Marking purchased"));
				}
				purchased = true;
				DestroyPurchaseUI();
			}
			else
			{
				purchased = false;
			}
		}

		public bool IsPurchased()
		{
			string text = selectableGroup?.DefaultSelectableKey;
			if (!string.IsNullOrEmpty(text) && (Object)(object)selectable != (Object)null && selectable.selectableKey == text)
			{
				return true;
			}
			return purchased;
		}

		public bool TryPurchase()
		{
			if (IsPurchased())
			{
				return true;
			}
			if ((Object)(object)terminal == (Object)null || terminal.groupCredits < price)
			{
				if ((Object)(object)audioSource != (Object)null && (Object)(object)purchaseUnsuccessful != (Object)null)
				{
					audioSource.PlayOneShot(purchaseUnsuccessful);
				}
				return false;
			}
			MonitorCreditSync monitorCreditSync = Object.FindObjectOfType<MonitorCreditSync>();
			int newValue = terminal.groupCredits - price;
			monitorCreditSync.RequestSetCredits(newValue);
			if ((Object)(object)audioSource != (Object)null && (Object)(object)purchaseSuccessful != (Object)null)
			{
				audioSource.PlayOneShot(purchaseSuccessful);
			}
			purchased = true;
			MonitorPurchaseSync monitorPurchaseSync = Object.FindObjectOfType<MonitorPurchaseSync>();
			monitorPurchaseSync.RequestPurchase(groupIndexInSave, selectableIndexInGroup);
			DestroyPurchaseUI();
			return true;
		}

		private void DestroyPurchaseUI()
		{
			if ((Object)(object)creditsNumber != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)creditsNumber).gameObject);
			}
			if ((Object)(object)lockImage != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)lockImage).gameObject);
			}
			if ((Object)(object)crossImage != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)crossImage).gameObject);
			}
		}

		private int FindSelectableIndexInGroup(MonitorSelectableGroup group, MonitorSelectable targetSelectable)
		{
			if ((Object)(object)group == (Object)null || (Object)(object)targetSelectable == (Object)null || group.groupedSelectables == null)
			{
				return -1;
			}
			for (int i = 0; i < group.groupedSelectables.Length; i++)
			{
				if ((Object)(object)group.groupedSelectables[i] == (Object)(object)targetSelectable)
				{
					return i;
				}
			}
			return -1;
		}

		public void ApplyRemotePurchase(int groupIndex, int selectableIndex)
		{
			if (purchasedSynced)
			{
				return;
			}
			if (groupIndexInSave < 0)
			{
				MonitorPurchaseSave componentInParent = ((Component)this).GetComponentInParent<MonitorPurchaseSave>();
				if ((Object)(object)componentInParent != (Object)null && (Object)(object)selectableGroup != (Object)null)
				{
					componentInParent.TryGetGroupIndex(selectableGroup, out groupIndex