Decompiled source of PizzaTowerEscapeMusic ForkForMe v2.5.6

BepInEx/plugins/PizzaTowerEscapeMusic.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PizzaTowerEscapeMusic.Networking;
using PizzaTowerEscapeMusic.Scripting;
using PizzaTowerEscapeMusic.Scripting.Conditions;
using PizzaTowerEscapeMusic.Scripting.ScriptEvents;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyCompany("PizzaTowerEscapeMusic")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Plays music from Pizza Tower when the early ship leave alert appears")]
[assembly: AssemblyFileVersion("2.5.6.0")]
[assembly: AssemblyInformationalVersion("2.5.6")]
[assembly: AssemblyProduct("PizzaTowerEscapeMusic")]
[assembly: AssemblyTitle("PizzaTowerEscapeMusic")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.5.6.0")]
[module: UnverifiableCode]
public class ConditionConverter : JsonConverter<Condition>
{
	public override bool CanWrite => false;

	public override Condition ReadJson(JsonReader reader, Type objectType, Condition existingValue, bool hasExistingValue, JsonSerializer serializer)
	{
		JObject val = JObject.Load(reader);
		JToken val2 = default(JToken);
		if (!val.TryGetValue("conditionType", ref val2))
		{
			throw new Exception("Condition type is null!");
		}
		string text = Extensions.Value<string>((IEnumerable<JToken>)val2);
		if (1 == 0)
		{
		}
		Condition condition = text switch
		{
			"And" => new Condition_And(), 
			"Or" => new Condition_Or(), 
			"Not" => new Condition_Not(), 
			"Weather" => new Condition_Weather(), 
			"PlayerLocation" => new Condition_PlayerLocation(), 
			"PlayerAlive" => new Condition_PlayerAlive(), 
			"AllPlayersDead" => new Condition_AllPlayersDead(), 
			"PlayerHealth" => new Condition_PlayerHealth(), 
			"PlayerCrouching" => new Condition_PlayerCrouching(), 
			"PlayerInsanity" => new Condition_PlayerInsanity(), 
			"PlayerFearLevel" => new Condition_PlayerFearLevel(), 
			"PlayerAlone" => new Condition_PlayerAlone(), 
			"FiringPlayers" => new Condition_FiringPlayers(), 
			"ShipLanded" => new Condition_ShipLanded(), 
			"ShipInOrbit" => new Condition_ShipInOrbit(), 
			"ShipLeavingAlertCalled" => new Condition_ShipLeavingAlertCalled(), 
			"ShipIsLeaving" => new Condition_ShipIsLeaving(), 
			"MusicWithTagPlaying" => new Condition_MusicWithTagPlaying(), 
			"CurrentMoon" => new Condition_CurrentMoon(), 
			"Timer" => new Condition_Timer(), 
			"Counter" => new Condition_Counter(), 
			"Random" => new Condition_Random(), 
			"ApparatusDocked" => new Condition_ApparatusDocked(), 
			"ApparatusTaked" => new Condition_ApparatusTaked(), 
			"TimeOfDay" => new Condition_TimeOfDay(), 
			"SelectedLabel" => new Condition_SelectedLabel(), 
			_ => throw new Exception($"Condition type \"{val2}\" does not exist"), 
		};
		if (1 == 0)
		{
		}
		Condition condition2 = condition;
		serializer.Populate(((JToken)val).CreateReader(), (object)condition2);
		return condition2;
	}

	public override void WriteJson(JsonWriter writer, Condition value, JsonSerializer serializer)
	{
		throw new NotImplementedException();
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte A_1)
		{
			NullableFlags = new byte[1] { A_1 };
		}

		public NullableAttribute(byte[] A_1)
		{
			NullableFlags = A_1;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte A_1)
		{
			Flag = A_1;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int A_1)
		{
			Version = A_1;
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace PizzaTowerEscapeMusic
{
	public class Configuration
	{
		private readonly ConfigFile config;

		internal ConfigEntry<bool> useRandomMapSeed;

		internal ConfigEntry<bool> dontQueue;

		internal ConfigEntry<string> scriptingScripts;

		internal ConfigEntry<float> volumeMaster;

		internal ConfigEntry<string> selectLabelManually;

		public Configuration(ConfigFile config)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			this.config = config;
			useRandomMapSeed = config.Bind<bool>("General", "UseRandomMapSeed", false, new ConfigDescription("Whether to use the game's random map seed for randomization", (AcceptableValueBase)null, Array.Empty<object>()));
			dontQueue = config.Bind<bool>("General", "DontQueue", true, new ConfigDescription("Whether to not queue randomization events even RandomMapSeed not fully ready, UseRandomMapSeed required", (AcceptableValueBase)null, Array.Empty<object>()));
			scriptingScripts = config.Bind<string>("Scripting", "Scripts", "Default", new ConfigDescription("The names of the JSON script files that will be loaded (Separated by commas, do not put a space after the commas)", (AcceptableValueBase)null, Array.Empty<object>()));
			volumeMaster = config.Bind<float>("Volume", "Master", 0.5f, new ConfigDescription("The volume of the music as a whole, all volumes are scaled by this value", (AcceptableValueBase)null, Array.Empty<object>()));
			selectLabelManually = config.Bind<string>("LabelRandom", "SelectLabelManually", "", new ConfigDescription("Manually select label for groups. Format: Group1:Label1,Group2:Label2 (empty to skip)", (AcceptableValueBase)null, Array.Empty<object>()));
			volumeMaster.SettingChanged += delegate
			{
			};
			selectLabelManually.SettingChanged += delegate
			{
				PizzaTowerEscapeMusicManager.ScriptManager?.ApplySelectedLabels();
			};
			RemoveObsoleteEntries();
		}

		private void RemoveObsoleteEntry(string section, string key)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			ConfigDefinition val = new ConfigDefinition(section, key);
			config.Bind<string>(val, "", (ConfigDescription)null);
			config.Remove(val);
		}

		private void ReplaceObsoleteEntry<T>(string section, string key, ConfigEntry<T> replacement)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			ConfigDefinition val = new ConfigDefinition(section, key);
			ConfigEntry<T> val2 = config.Bind<T>(val, (T)((ConfigEntryBase)replacement).DefaultValue, (ConfigDescription)null);
			if (!EqualityComparer<T>.Default.Equals(val2.Value, (T)((ConfigEntryBase)replacement).DefaultValue))
			{
				replacement.Value = val2.Value;
			}
			config.Remove(val);
		}

		private void RemoveObsoleteEntries()
		{
			RemoveObsoleteEntry("Volume", "InsideFacility");
			RemoveObsoleteEntry("Volume", "OutsideFacility");
			RemoveObsoleteEntry("Volume", "InsideShip");
			RemoveObsoleteEntry("Volume", "CrouchingScale");
			RemoveObsoleteEntry("Music", "InsideFacility");
			RemoveObsoleteEntry("Music", "OutsideFacility");
			RemoveObsoleteEntry("Music", "HeavyWeather");
			ReplaceObsoleteEntry<string>("Scripting", "Script", scriptingScripts);
			config.Save();
		}
	}
	internal static class CustomManager
	{
		public static string GetFilePath(string path, string fallbackPath)
		{
			string[] directories = Directory.GetDirectories(Paths.PluginPath);
			for (int i = 0; i < directories.Length; i++)
			{
				string text = directories[i] + "/BGN-PizzaTowerEscapeMusic/" + path;
				if (File.Exists(text))
				{
					return text;
				}
			}
			string text2 = Paths.PluginPath + "/BGN-PizzaTowerEscapeMusic_Custom/" + path;
			if (File.Exists(text2))
			{
				return text2;
			}
			return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/" + fallbackPath;
		}
	}
	public class FacilityMeltdownIntegration : MonoBehaviour
	{
		private ManualLogSource logger;

		private GameEventListener gameEventListener;

		private Action registeredCallback;

		public void Initialize(ManualLogSource logger, GameEventListener gameEventListener)
		{
			this.logger = logger;
			this.gameEventListener = gameEventListener;
			TryHookIntoFacilityMeltdown();
		}

		private void TryHookIntoFacilityMeltdown()
		{
			try
			{
				if (Type.GetType("FacilityMeltdown.MeltdownPlugin, FacilityMeltdown") == null)
				{
					logger.LogInfo((object)"Could not find FacilityMeltdown mod, skipping");
					return;
				}
				logger.LogInfo((object)"FacilityMeltdown detected, hooking into meltdown events...");
				Type type = Type.GetType("FacilityMeltdown.API.MeltdownAPI, FacilityMeltdown");
				if (type == null)
				{
					logger.LogWarning((object)"Could not find MeltdownAPI type");
					return;
				}
				MethodInfo method = type.GetMethod("RegisterMeltdownListener", BindingFlags.Static | BindingFlags.Public);
				if (method == null)
				{
					logger.LogWarning((object)"Could not find RegisterMeltdownListener method in MeltdownAPI");
					return;
				}
				logger.LogInfo((object)"Found RegisterMeltdownListener method in MeltdownAPI");
				Action action = OnFacilityMeltdownStarted;
				method.Invoke(null, new object[1] { action });
				registeredCallback = action;
				logger.LogInfo((object)"Successfully registered as a meltdown listener!");
			}
			catch (Exception ex)
			{
				logger.LogError((object)("Failed to hook into FacilityMeltdown: " + ex.Message));
				logger.LogDebug((object)("Exception details: " + ex.ToString()));
			}
		}

		private void OnFacilityMeltdownStarted()
		{
			logger.LogInfo((object)"FacilityMeltdown meltdown event detected! Triggering music...");
			if ((Object)(object)gameEventListener != (Object)null)
			{
				gameEventListener.OnMeltdownStarted?.Invoke();
			}
		}

		private void OnDestroy()
		{
			logger.LogDebug((object)"FacilityMeltdown integration being destroyed");
		}
	}
	public class GameEventListener : MonoBehaviour
	{
		private ManualLogSource logger;

		public Action OnFrameUpdate = delegate
		{
		};

		public Action OnSoundManagerCreated = delegate
		{
		};

		public Action OnSoundManagerDestroyed = delegate
		{
		};

		public Action OnDungeonDoneGenerating = delegate
		{
		};

		public Action OnLevelLoaded = delegate
		{
		};

		public Action OnEndOfGame = delegate
		{
		};

		public Action OnShipLanded = delegate
		{
		};

		public Action OnShipTakeOff = delegate
		{
		};

		public Action OnShipInOrbit = delegate
		{
		};

		public Action OnShipLeavingAlertCalled = delegate
		{
		};

		public Action OnPlayerDamaged = delegate
		{
		};

		public Action OnPlayerDeath = delegate
		{
		};

		public Action OnPlayerEnteredFacility = delegate
		{
		};

		public Action OnPlayerExitedFacility = delegate
		{
		};

		public Action OnPlayerEnteredShip = delegate
		{
		};

		public Action OnPlayerExitedShip = delegate
		{
		};

		public Action OnApparatusTaken = delegate
		{
		};

		public Action OnMeltdownStarted = delegate
		{
		};

		public Action OnShipNotInOrbit = delegate
		{
		};

		public Action OnFiringPlayers = delegate
		{
		};

		public Action OnGameOver = delegate
		{
		};

		public Action<SelectableLevel> OnCurrentMoonChanged = delegate
		{
		};

		private int localSeed = 0;

		private bool syncedrandomMapSeed = false;

		private readonly Dictionary<string, object> previousValues = new Dictionary<string, object>();

		private static LungProp dockedApparatus;

		public static GameEventListener Instance { get; private set; }

		public static bool SyncedrandomMapSeed => (Object)(object)Instance != (Object)null && Instance.syncedrandomMapSeed;

		public static bool EndOfGameCalled { get; set; }

		public static bool ApparatusTaked { get; set; }

		private void Awake()
		{
			logger = Logger.CreateLogSource("PizzaTowerEscapeMusic GameEventListener");
			Instance = this;
			OnShipLanded = (Action)Delegate.Combine(OnShipLanded, new Action(FindDockedApparatus));
		}

		private void OnDestroy()
		{
			Instance = null;
		}

		private void FindDockedApparatus()
		{
			logger.LogDebug((object)"Checking for docked Apparatus...");
			LungProp[] array = Object.FindObjectsOfType<LungProp>();
			foreach (LungProp val in array)
			{
				if (val.isLungDocked)
				{
					logger.LogDebug((object)"Found docked Apparatus");
					dockedApparatus = val;
					return;
				}
			}
			logger.LogDebug((object)"Could not find docked Apparatus");
		}

		public static bool IsApparatusDocked()
		{
			return (Object)(object)dockedApparatus != (Object)null;
		}

		private void StartSyncedrandomMapSeed()
		{
			if (!((Object)(object)StartOfRound.Instance != (Object)null) || !SeedSyncService.SeedReceived || syncedrandomMapSeed)
			{
				return;
			}
			int randomMapSeed = StartOfRound.Instance.randomMapSeed;
			if (randomMapSeed != localSeed)
			{
				localSeed = randomMapSeed;
				logger.LogDebug((object)$"StartOfRound randomMapSeed updated: {randomMapSeed}");
				int capturedSeed = SeedSyncService.CapturedSeed;
				if (capturedSeed != -1 && randomMapSeed == capturedSeed)
				{
					logger.LogDebug((object)$"Seed match: RPC seed {capturedSeed} equals StartOfRound seed {randomMapSeed}");
					syncedrandomMapSeed = true;
				}
			}
		}

		private void ResetSyncedrandomMapSeed()
		{
			if (syncedrandomMapSeed)
			{
				localSeed = 0;
				syncedrandomMapSeed = false;
				logger.LogDebug((object)"SyncedrandomMapSeed flag reset");
			}
		}

		private void Update()
		{
			if ((Object)(object)SoundManager.Instance != (Object)null)
			{
				OnFrameUpdate();
			}
			CheckSoundManager();
			CheckDungeonDoneGenerating();
			CheckLevelLoaded();
			CheckEndOfGame();
			CheckShipLanded();
			CheckShipIsLeaving();
			CheckShipReturnToOrbit();
			CheckShipInOrbit();
			CheckShipNotInOrbit();
			CheckFiringPlayers();
			CheckGameOver();
			CheckShipLeavingAlertCalled();
			CheckPlayerDamaged();
			CheckPlayerDeath();
			CheckPlayerInsideFacility();
			CheckPlayerInsideShip();
			CheckApparatusTaken();
			CheckCurrentMoonChanged();
			CheckStartOfRoundNull();
			StartSyncedrandomMapSeed();
		}

		private T UpdateCached<T>(string key, T currentValue, T defaultValue)
		{
			if (!previousValues.TryGetValue(key, out var value))
			{
				value = defaultValue;
			}
			previousValues[key] = currentValue;
			return (T)value;
		}

		private void CheckSoundManager()
		{
			bool flag = (Object)(object)SoundManager.Instance != (Object)null;
			if (UpdateCached("SoundManager", flag, defaultValue: false) != flag)
			{
				if (flag)
				{
					logger.LogDebug((object)"Sound Manager created");
					OnSoundManagerCreated();
				}
				else
				{
					logger.LogDebug((object)"Sound Manager destroyed");
					OnSoundManagerDestroyed();
				}
			}
		}

		private void CheckDungeonDoneGenerating()
		{
			bool flag = (Object)(object)RoundManager.Instance != (Object)null && RoundManager.Instance.dungeonCompletedGenerating;
			bool flag2 = UpdateCached("DungeonDoneGenerating", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Dungeon done generating");
				OnDungeonDoneGenerating();
			}
		}

		private void CheckLevelLoaded()
		{
			bool flag = (Object)(object)RoundManager.Instance != (Object)null && RoundManager.Instance.dungeonFinishedGeneratingForAllPlayers;
			bool flag2 = UpdateCached("LevelLoaded", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Level loaded");
				OnLevelLoaded();
			}
		}

		private void CheckEndOfGame()
		{
			bool flag = (Object)(object)StartOfRound.Instance != (Object)null && EndOfGameCalled;
			bool flag2 = UpdateCached("EndOfGame", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"End of game");
				OnEndOfGame();
				EndOfGameCalled = false;
			}
		}

		private void CheckShipLanded()
		{
			bool flag = (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipHasLanded;
			bool flag2 = UpdateCached("ShipLanded", flag, defaultValue: true);
			if (flag != flag2 && !((Object)(object)StartOfRound.Instance == (Object)null))
			{
				if (flag)
				{
					logger.LogDebug((object)"Ship landed");
					OnShipLanded();
				}
				else
				{
					logger.LogDebug((object)"Ship takeoff");
					OnShipTakeOff();
				}
			}
		}

		private void CheckShipIsLeaving()
		{
			bool flag = (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipIsLeaving;
			bool flag2 = UpdateCached("ShipIsLeaving", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Ship is leaving");
			}
		}

		private void CheckShipReturnToOrbit()
		{
			bool flag = (Object)(object)StartOfRound.Instance == (Object)null || (!StartOfRound.Instance.shipHasLanded && !StartOfRound.Instance.shipIsLeaving);
			bool flag2 = UpdateCached("ShipReturnToOrbit", flag, defaultValue: true);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Ship returning to orbit");
			}
		}

		private void CheckShipInOrbit()
		{
			bool flag = (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.inShipPhase;
			bool flag2 = UpdateCached("ShipInOrbit", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Ship is in orbit");
				OnShipInOrbit();
				EndOfGameCalled = false;
				ApparatusTaked = false;
			}
		}

		private void CheckShipNotInOrbit()
		{
			bool flag = (Object)(object)StartOfRound.Instance != (Object)null && !StartOfRound.Instance.inShipPhase;
			bool flag2 = UpdateCached("ShipNotInOrbit", flag, defaultValue: true);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Ship not in orbit");
				OnShipNotInOrbit();
			}
		}

		private void CheckShipLeavingAlertCalled()
		{
			bool flag = (Object)(object)TimeOfDay.Instance != (Object)null && TimeOfDay.Instance.shipLeavingAlertCalled;
			bool flag2 = UpdateCached("ShipLeavingAlertCalled", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Ship leaving alert called");
				OnShipLeavingAlertCalled();
			}
		}

		private void CheckPlayerDamaged()
		{
			if (!((Object)(object)GameNetworkManager.Instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null))
			{
				int health = GameNetworkManager.Instance.localPlayerController.health;
				int num = UpdateCached("PlayerDamaged", health, 100);
				if (health < num)
				{
					logger.LogDebug((object)$"Player took damage (Health: {GameNetworkManager.Instance.localPlayerController.health})");
					OnPlayerDamaged();
				}
			}
		}

		private void CheckPlayerDeath()
		{
			bool flag = (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && GameNetworkManager.Instance.localPlayerController.isPlayerDead;
			bool flag2 = UpdateCached("PlayerDeath", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Player has died");
				OnPlayerDeath();
			}
		}

		private void CheckPlayerInsideFacility()
		{
			bool flag = (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && GameNetworkManager.Instance.localPlayerController.isInsideFactory;
			bool flag2 = UpdateCached("PlayerInsideFacility", flag, defaultValue: false);
			if (flag != flag2)
			{
				if (flag)
				{
					logger.LogDebug((object)"Player entered the facility");
					OnPlayerEnteredFacility();
				}
				else
				{
					logger.LogDebug((object)"Player exited the facility");
					OnPlayerExitedFacility();
				}
			}
		}

		private void CheckPlayerInsideShip()
		{
			bool flag = (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom;
			bool flag2 = UpdateCached("PlayerInsideShip", flag, defaultValue: false);
			if (flag != flag2)
			{
				if (flag)
				{
					logger.LogDebug((object)"Player entered the ship");
					OnPlayerEnteredShip();
				}
				else
				{
					logger.LogDebug((object)"Player exited the ship");
					OnPlayerExitedShip();
				}
			}
		}

		private void CheckApparatusTaken()
		{
			if (!((Object)(object)StartOfRound.Instance == (Object)null))
			{
				bool flag = (Object)(object)dockedApparatus != (Object)null && !dockedApparatus.isLungDocked;
				bool flag2 = UpdateCached("ApparatusTaken", flag, defaultValue: false);
				if (flag != flag2 && flag)
				{
					dockedApparatus = null;
					logger.LogDebug((object)"Apparatus was taken");
					ApparatusTaked = true;
					OnApparatusTaken();
				}
			}
		}

		private void CheckCurrentMoonChanged()
		{
			if (!((Object)(object)StartOfRound.Instance == (Object)null) && !((Object)(object)TimeOfDay.Instance == (Object)null))
			{
				TimeOfDay instance = TimeOfDay.Instance;
				SelectableLevel currentLevel = instance.currentLevel;
				SelectableLevel val = UpdateCached<SelectableLevel>("CurrentMoon", currentLevel, null);
				if (!((Object)(object)currentLevel == (Object)(object)val) && !((Object)(object)currentLevel == (Object)null) && !((Object)(object)val == (Object)null))
				{
					logger.LogDebug((object)("Level has changed to " + (((Object)(object)currentLevel != (Object)null) ? currentLevel.PlanetName : null)));
					OnCurrentMoonChanged(currentLevel);
				}
			}
		}

		private void CheckFiringPlayers()
		{
			bool flag = (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.firingPlayersCutsceneRunning;
			bool flag2 = UpdateCached("FiringPlayers", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Firing players cutscene running");
				OnFiringPlayers();
			}
		}

		private void CheckGameOver()
		{
			bool flag = (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.suckingPlayersOutOfShip;
			bool flag2 = UpdateCached("GameOver", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Game over");
				OnGameOver();
			}
		}

		private void CheckStartOfRoundNull()
		{
			bool flag = (Object)(object)StartOfRound.Instance == (Object)null;
			bool flag2 = UpdateCached("StartOfRoundNull", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"StartOfRound instance became null");
				ResetSyncedrandomMapSeed();
				SeedSyncService.ResetSeedReceived();
				ScriptEvent_LabelRandom.ClearQueueAndFlags();
				previousValues.Remove("CurrentMoon");
			}
		}
	}
	public class MusicManager : MonoBehaviour
	{
		private class MusicInstance
		{
			private readonly MusicManager manager;

			public Script script;

			public ScriptEvent_PlayMusic musicEvent;

			public AudioSource introAudioSource;

			public AudioSource mainAudioSource;

			public Script.VolumeGroup volumeGroup;

			private bool isStopping;

			private AudioClip introClip;

			private AudioClip mainClip;

			private bool isIntroPlaying;

			private bool mainScheduled;

			private bool introSwitchToMain;

			private float volume;

			public float FadeSpeed { get; private set; }

			public MusicInstance(MusicManager manager, Script script, ScriptEvent_PlayMusic musicEvent, AudioSource audioSource, AudioClip musicClip, AudioClip introClip = null)
			{
				this.manager = manager;
				this.script = script;
				this.musicEvent = musicEvent;
				introAudioSource = audioSource;
				this.introClip = introClip;
				mainClip = musicClip;
				isIntroPlaying = (Object)(object)introClip != (Object)null;
				if (isIntroPlaying)
				{
					audioSource.clip = introClip;
					audioSource.loop = false;
					mainAudioSource = manager.GetAudioSource();
					mainAudioSource.clip = mainClip;
					mainAudioSource.loop = musicEvent.loop;
					mainScheduled = false;
					audioSource.Play();
				}
				else
				{
					introAudioSource = null;
					mainAudioSource = audioSource;
					mainAudioSource.clip = mainClip;
					mainAudioSource.loop = musicEvent.loop;
					mainAudioSource.Play();
				}
				musicInstances.Add(this);
				if (musicEvent.tag != null)
				{
					if (!musicInstancesByTag.TryGetValue(musicEvent.tag, out var value))
					{
						value = new List<MusicInstance>(1);
						musicInstancesByTag.Add(musicEvent.tag, value);
					}
					value.Add(this);
				}
				volumeGroup = script.TryGetVolumeGroupOrDefault(musicEvent.tag);
				volume = volumeGroup.GetVolume(script);
			}

			public void Update(float deltaTime)
			{
				bool flag = introSwitchToMain;
				introSwitchToMain = false;
				if (isIntroPlaying)
				{
					if ((Object)(object)introAudioSource != (Object)null && (Object)(object)mainAudioSource != (Object)null && !mainScheduled)
					{
						int num = introClip.samples - introAudioSource.timeSamples;
						int num2 = (int)(0.5f * (float)introClip.frequency);
						if (num <= num2)
						{
							double num3 = (double)num / (double)introClip.frequency;
							double num4 = AudioSettings.dspTime + num3;
							mainAudioSource.PlayScheduled(num4);
							mainScheduled = true;
						}
					}
					if ((Object)(object)introAudioSource != (Object)null && !introAudioSource.isPlaying)
					{
						isIntroPlaying = false;
						introSwitchToMain = true;
					}
				}
				float num5 = (isStopping ? 0f : volumeGroup.GetVolume(script));
				float num6 = (isStopping ? volumeGroup.stoppingVolumeLerpSpeed : volumeGroup.volumeLerpSpeed);
				float num7 = (isStopping ? volumeGroup.GetStoppingVolumeLerpSpeedScale(script) : volumeGroup.GetVolumeLerpSpeedScale(script));
				float num8 = num6 * num7;
				volume = Mathf.Lerp(volume, num5, num8 * deltaTime);
				float value = PizzaTowerEscapeMusicManager.Configuration.volumeMaster.Value;
				if ((Object)(object)introAudioSource != (Object)null)
				{
					introAudioSource.volume = volume * value;
				}
				if ((Object)(object)mainAudioSource != (Object)null)
				{
					mainAudioSource.volume = volume * value;
				}
				AudioSource val = (isIntroPlaying ? introAudioSource : (mainAudioSource ?? introAudioSource));
				if (((!((Object)(object)val != (Object)null) || !val.isPlaying) && !introSwitchToMain && !flag) || (isStopping && (Object)(object)val != (Object)null && val.volume < 0.005f))
				{
					StopCompletely();
				}
			}

			public void FadeStop()
			{
				if (!isStopping)
				{
					isStopping = true;
					float stoppingVolumeLerpSpeedScale = volumeGroup.GetStoppingVolumeLerpSpeedScale(script);
					FadeSpeed = volumeGroup.stoppingVolumeLerpSpeed * stoppingVolumeLerpSpeedScale;
				}
			}

			public void StopCompletely()
			{
				if ((Object)(object)introAudioSource != (Object)null)
				{
					introAudioSource.Stop();
					audioSourcePool.Push(introAudioSource);
				}
				if ((Object)(object)mainAudioSource != (Object)null)
				{
					mainAudioSource.Stop();
					audioSourcePool.Push(mainAudioSource);
				}
				musicInstances.Remove(this);
				if (musicEvent.tag != null && musicInstancesByTag.TryGetValue(musicEvent.tag, out var value))
				{
					value.Remove(this);
				}
				mainScheduled = false;
			}
		}

		private Dictionary<string, float> lastGetIsMusicPlayingLogTimeByTag = new Dictionary<string, float>();

		private bool enablelogCooldown = true;

		private static readonly SemaphoreSlim _loadConcurrencySemaphore = new SemaphoreSlim(16, 16);

		private ManualLogSource logger;

		private static readonly List<MusicInstance> musicInstances = new List<MusicInstance>();

		private static readonly Dictionary<string, List<MusicInstance>> musicInstancesByTag = new Dictionary<string, List<MusicInstance>>();

		private static readonly Stack<AudioSource> audioSourcePool = new Stack<AudioSource>();

		private readonly Dictionary<string, AudioClip> loadedMusic = new Dictionary<string, AudioClip>();

		private void Awake()
		{
			logger = Logger.CreateLogSource("PizzaTowerEscapeMusic MusicManager");
		}

		private void Update()
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return;
			}
			for (int num = musicInstances.Count - 1; num >= 0; num--)
			{
				musicInstances[num].Update(Time.deltaTime);
			}
			bool flag = false;
			foreach (MusicInstance musicInstance in musicInstances)
			{
				if (musicInstance.musicEvent.silenceGameMusic)
				{
					flag = true;
					break;
				}
			}
			if (flag)
			{
				if (SoundManager.Instance.playingOutsideMusic && GetIsMusicPlaying())
				{
					SoundManager.Instance.playingOutsideMusic = false;
					logger.LogInfo((object)"Silenced the outside music because alternate music is playing");
				}
				if (TimeOfDay.Instance.TimeOfDayMusic.isPlaying && GetIsMusicPlaying())
				{
					TimeOfDay.Instance.TimeOfDayMusic.Stop();
					logger.LogInfo((object)"Silenced the time of day music because alternate music is playing");
				}
			}
		}

		public bool GetIsMusicPlaying(string tag = null)
		{
			if (tag == null)
			{
				return musicInstances.Count > 0;
			}
			if (musicInstancesByTag.TryGetValue(tag, out var value))
			{
				bool flag = true;
				if (enablelogCooldown)
				{
					if (!lastGetIsMusicPlayingLogTimeByTag.TryGetValue(tag, out var value2))
					{
						value2 = -30f;
					}
					if (Time.time - value2 >= 30f)
					{
						lastGetIsMusicPlayingLogTimeByTag[tag] = Time.time;
					}
					else
					{
						flag = false;
					}
				}
				if (flag)
				{
					logger.LogDebug((object)$"GetIsMusicPlaying says there's {value.Count} music instance(s) with the tag \"{tag}\"");
				}
				return value.Count > 0;
			}
			bool flag2 = true;
			if (enablelogCooldown)
			{
				if (!lastGetIsMusicPlayingLogTimeByTag.TryGetValue(tag, out var value3))
				{
					value3 = -30f;
				}
				if (Time.time - value3 >= 30f)
				{
					lastGetIsMusicPlayingLogTimeByTag[tag] = Time.time;
				}
				else
				{
					flag2 = false;
				}
			}
			if (flag2)
			{
				logger.LogDebug((object)("GetIsMusicPlaying says there was no music instance list for tag \"" + tag + "\""));
			}
			return false;
		}

		public void PlayMusic(Script script, ScriptEvent_PlayMusic musicEvent)
		{
			logger.LogDebug((object)("PlayMusic called\nTag:                         " + musicEvent.tag + $"\nOverlap handling:            {musicEvent.overlapHandling}" + $"\nAny music playing?:          {GetIsMusicPlaying()}" + $"\nAny music playing with tag?: {GetIsMusicPlaying(musicEvent.tag)}"));
			string text = musicEvent.musicNames[Random.Range(0, musicEvent.musicNames.Length)];
			string text2 = null;
			if (musicEvent.introMusicNames != null && musicEvent.introMusicNames.Length != 0)
			{
				text2 = musicEvent.introMusicNames[Random.Range(0, musicEvent.introMusicNames.Length)];
			}
			if (musicEvent.overlapHandling == ScriptEvent_PlayMusic.OverlapHandling.IgnoreAll && GetIsMusicPlaying())
			{
				logger.LogDebug((object)"PlayMusic canceled because other music was playing");
				return;
			}
			if (musicEvent.overlapHandling == ScriptEvent_PlayMusic.OverlapHandling.IgnoreTag && GetIsMusicPlaying(musicEvent.tag))
			{
				logger.LogDebug((object)("PlayMusic canceled because other music with the tag \"" + musicEvent.tag + "\" was playing"));
				return;
			}
			switch (musicEvent.overlapHandling)
			{
			case ScriptEvent_PlayMusic.OverlapHandling.OverrideAll:
				StopMusic();
				break;
			case ScriptEvent_PlayMusic.OverlapHandling.OverrideTag:
				StopMusic(musicEvent.tag);
				break;
			case ScriptEvent_PlayMusic.OverlapHandling.OverrideFadeAll:
				FadeStopMusic();
				break;
			case ScriptEvent_PlayMusic.OverlapHandling.OverrideFadeTag:
				FadeStopMusic(musicEvent.tag);
				break;
			}
			loadedMusic.TryGetValue(text, out var value);
			AudioClip value2 = null;
			if (text2 != null)
			{
				loadedMusic.TryGetValue(text2, out value2);
			}
			if ((Object)(object)value != (Object)null)
			{
				new MusicInstance(this, script, musicEvent, GetAudioSource(), value, value2);
				logger.LogInfo((object)("Playing music (" + text + ")" + ((text2 != null) ? (" with intro (" + text2 + ")") : "")));
			}
			else
			{
				logger.LogWarning((object)("Music (" + text + ") is null, cannot play. Maybe it wasn't loaded correctly?"));
			}
		}

		public void StopMusic(string targetTag = null)
		{
			foreach (MusicInstance item in new List<MusicInstance>(musicInstances))
			{
				if (targetTag == null || !(item.musicEvent.tag != targetTag))
				{
					item.StopCompletely();
				}
			}
		}

		public void FadeStopMusic(string targetTag = null)
		{
			foreach (MusicInstance item in new List<MusicInstance>(musicInstances))
			{
				if (targetTag == null || !(item.musicEvent.tag != targetTag))
				{
					item.FadeStop();
				}
			}
		}

		private AudioSource GetAudioSource()
		{
			if (audioSourcePool.Count > 0)
			{
				return audioSourcePool.Pop();
			}
			return ((Component)this).gameObject.AddComponent<AudioSource>();
		}

		public async void LoadNecessaryMusicClips()
		{
			if (PizzaTowerEscapeMusicManager.ScriptManager.loadedScripts.Count == 0)
			{
				logger.LogError((object)"No scripts are loaded, addon scripts may not work, please report this issue");
				return;
			}
			string scriptsConfig = PizzaTowerEscapeMusicManager.Configuration?.scriptingScripts?.Value;
			if (string.IsNullOrWhiteSpace(scriptsConfig))
			{
				logger.LogInfo((object)"No scripts configured, skipping music loading");
				return;
			}
			HashSet<string> musicToLoad = new HashSet<string>();
			foreach (Script loadedScript in PizzaTowerEscapeMusicManager.ScriptManager.loadedScripts)
			{
				ScriptEvent[] scriptEvents = loadedScript.scriptEvents;
				foreach (ScriptEvent scriptEvent in scriptEvents)
				{
					if (!(scriptEvent is ScriptEvent_PlayMusic playMusicEvent))
					{
						continue;
					}
					if (playMusicEvent.musicNames != null)
					{
						string[] musicNames = playMusicEvent.musicNames;
						foreach (string musicName4 in musicNames)
						{
							if (!loadedMusic.ContainsKey(musicName4))
							{
								musicToLoad.Add(musicName4);
							}
						}
					}
					if (playMusicEvent.introMusicNames == null)
					{
						continue;
					}
					string[] introMusicNames = playMusicEvent.introMusicNames;
					foreach (string introMusicName in introMusicNames)
					{
						if (!loadedMusic.ContainsKey(introMusicName))
						{
							musicToLoad.Add(introMusicName);
						}
					}
				}
			}
			if (musicToLoad.Count == 0)
			{
				logger.LogInfo((object)"All music clips already loaded");
				return;
			}
			logger.LogInfo((object)$"Loading {musicToLoad.Count} music clips...");
			List<Task<AudioClip>> loadTasks = new List<Task<AudioClip>>();
			foreach (string musicName3 in musicToLoad)
			{
				loadTasks.Add(LoadMusicClip(musicName3));
			}
			AudioClip[] clips = await Task.WhenAll(loadTasks);
			int loadedCount = 0;
			int index2 = 0;
			foreach (string musicName2 in musicToLoad)
			{
				AudioClip clip2 = clips[index2++];
				if ((Object)(object)clip2 != (Object)null)
				{
					loadedMusic[musicName2] = clip2;
					loadedCount++;
				}
			}
			index2 = 0;
			foreach (string musicName in musicToLoad)
			{
				AudioClip clip = clips[index2++];
				if ((Object)(object)clip != (Object)null)
				{
					try
					{
						clip.LoadAudioData();
					}
					catch (Exception ex)
					{
						Exception e = ex;
						logger.LogError((object)$"Failed to load audio data for {musicName}: {e}");
					}
				}
			}
			logger.LogInfo((object)$"Music clips done loading. Successfully loaded {loadedCount} out of {musicToLoad.Count}");
		}

		private Task<AudioClip> LoadMusicClip(string musicFileName)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			InterpretMusicFileName(musicFileName, out var audioType, out var finalFileName);
			string path = "file:///" + CustomManager.GetFilePath("Music/" + finalFileName, "DefaultMusic/" + finalFileName);
			UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(path, audioType);
			UnityWebRequestAsyncOperation val = request.SendWebRequest();
			TaskCompletionSource<AudioClip> tcs = new TaskCompletionSource<AudioClip>();
			((AsyncOperation)val).completed += delegate
			{
				Task.Run(async delegate
				{
					await _loadConcurrencySemaphore.WaitAsync();
					try
					{
						if ((int)request.result == 1)
						{
							AudioClip clip = DownloadHandlerAudioClip.GetContent(request);
							if ((Object)(object)clip != (Object)null)
							{
								((Object)clip).name = musicFileName;
								logger.LogInfo((object)("Loaded music (" + musicFileName + ") from file"));
								tcs.SetResult(clip);
							}
							else
							{
								logger.LogError((object)("DownloadHandlerAudioClip.GetContent returned null for " + musicFileName));
								tcs.SetResult(null);
							}
						}
						else
						{
							logger.LogError((object)($"Failed to load music ({musicFileName}) from file as audio type {audioType}, if the file extension and the audio type do not match the file extension may not be supported" + "\n- Path: " + path + "\n- Error: " + request.error));
							tcs.SetResult(null);
						}
					}
					finally
					{
						request.Dispose();
						_loadConcurrencySemaphore.Release();
					}
				});
			};
			return tcs.Task;
		}

		private void InterpretMusicFileName(string musicFileName, out AudioType audioType, out string finalFileName)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected I4, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if (!Enumerable.Contains(musicFileName, '.'))
			{
				audioType = (AudioType)20;
				finalFileName = musicFileName + ".wav";
				return;
			}
			string text = musicFileName.Split(new char[1] { '.' }).Last().ToLower();
			AudioType val = ((text == "ogg") ? ((AudioType)14) : ((text == "mp3") ? ((AudioType)13) : ((AudioType)20)));
			audioType = (AudioType)(int)val;
			finalFileName = musicFileName;
		}
	}
	public class PizzaTowerEscapeMusicManager : MonoBehaviour
	{
		private GameEventListener gameEventListener;

		private ManualLogSource logger;

		public static Configuration Configuration { get; private set; }

		public static ScriptManager ScriptManager { get; private set; }

		public static MusicManager MusicManager { get; private set; }

		public void Initialise(ManualLogSource logger, ConfigFile config)
		{
			this.logger = logger;
			Configuration = new Configuration(config);
			MusicManager = ((Component)this).gameObject.AddComponent<MusicManager>();
			this.gameEventListener = ((Component)this).gameObject.AddComponent<GameEventListener>();
			GameEventListener gameEventListener = this.gameEventListener;
			gameEventListener.OnSoundManagerDestroyed = (Action)Delegate.Combine(gameEventListener.OnSoundManagerDestroyed, (Action)delegate
			{
				MusicManager.StopMusic();
			});
			ScriptManager = new ScriptManager(Configuration.scriptingScripts.Value.Split(new char[1] { ',' }), this.gameEventListener);
			GameEventListener gameEventListener2 = this.gameEventListener;
			gameEventListener2.OnSoundManagerDestroyed = (Action)Delegate.Combine(gameEventListener2.OnSoundManagerDestroyed, new Action(ScriptManager.ClearAllScriptTimers));
			GameEventListener gameEventListener3 = this.gameEventListener;
			gameEventListener3.OnSoundManagerDestroyed = (Action)Delegate.Combine(gameEventListener3.OnSoundManagerDestroyed, new Action(ScriptManager.ClearAllScriptCounters));
			try
			{
				((Component)this).gameObject.AddComponent<FacilityMeltdownIntegration>().Initialize(logger, this.gameEventListener);
			}
			catch (Exception)
			{
				logger.LogInfo((object)"Could not initialize FacilityMeltdown integration, skipping");
			}
			try
			{
				LethalConfigIntegration.Initialize();
			}
			catch (Exception)
			{
				logger.LogInfo((object)"Could not initialize LethalConfig integration, skipping");
			}
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			logger.LogInfo((object)"Plugin pizzatowerescapemusic is loaded!");
		}

		private void Update()
		{
			ScriptManager.UpdateAllScriptTimers(Time.deltaTime);
		}

		public static void OnChainloaderStartupComplete()
		{
			if ((Object)(object)MusicManager != (Object)null)
			{
				MusicManager.LoadNecessaryMusicClips();
			}
		}
	}
	[BepInPlugin("bgn.pizzatowerescapemusic", "PizzaTowerEscapeMusic", "2.5.6")]
	[BepInProcess("Lethal Company.exe")]
	public class Plugin : BaseUnityPlugin
	{
		private void Awake()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			SeedSyncPatches.ApplyPatches();
			EndOfGamePatches.ApplyPatches();
			ChainloaderStartupPatch.ApplyPatches();
			GameObject val = new GameObject("PizzaTowerEscapeMusic Manager");
			val.AddComponent<PizzaTowerEscapeMusicManager>().Initialise(((BaseUnityPlugin)this).Logger, ((BaseUnityPlugin)this).Config);
			((Object)val).hideFlags = (HideFlags)61;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "bgn.pizzatowerescapemusic";

		public const string PLUGIN_NAME = "PizzaTowerEscapeMusic";

		public const string PLUGIN_VERSION = "2.5.6";

		public const string PLUGIN_VERSION_FULL = "2.5.6.0";
	}
	[HarmonyPatch]
	internal static class EndOfGamePatches
	{
		private static ManualLogSource logger = Logger.CreateLogSource("PizzaTowerEscapeMusic EndOfGamePatches");

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "EndOfGame")]
		private static void EndOfGame_Postfix(int bodiesInsured, int connectedPlayersOnServer, int scrapCollected)
		{
			logger.LogDebug((object)$"EndOfGame called with bodiesInsured={bodiesInsured}, connectedPlayersOnServer={connectedPlayersOnServer}, scrapCollected={scrapCollected}");
			GameEventListener.EndOfGameCalled = true;
		}

		internal static void ApplyPatches()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			try
			{
				Harmony val = new Harmony("com.pizzatowerescapemusic.endofgame");
				val.PatchAll(Assembly.GetExecutingAssembly());
				logger.LogInfo((object)"EndOfGame Harmony patches applied successfully");
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"Failed to apply EndOfGame Harmony patches: {arg}");
			}
		}

		internal static void RemovePatches()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			try
			{
				Harmony val = new Harmony("com.pizzatowerescapemusic.endofgame");
				val.UnpatchSelf();
				logger.LogInfo((object)"EndOfGame Harmony patches removed");
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"Failed to remove EndOfGame Harmony patches: {arg}");
			}
		}
	}
	[HarmonyPatch]
	internal static class ChainloaderStartupPatch
	{
		private static ManualLogSource logger = Logger.CreateLogSource("PizzaTowerEscapeMusic ChainloaderStartupPatch");

		private static bool chainloaderStartupCompleted = false;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Logger), "LogMessage")]
		private static void LogMessagePrefix(object data)
		{
			if (data is string text && text == "Chainloader startup complete" && !chainloaderStartupCompleted)
			{
				chainloaderStartupCompleted = true;
				logger.LogDebug((object)"Chainloader startup complete detected");
				PizzaTowerEscapeMusicManager.OnChainloaderStartupComplete();
			}
		}

		internal static void ApplyPatches()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			try
			{
				Harmony val = new Harmony("com.pizzatowerescapemusic.chainloaderstartup");
				val.PatchAll(Assembly.GetExecutingAssembly());
				logger.LogInfo((object)"Chainloader startup patch applied successfully");
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"Failed to apply Chainloader startup patch: {arg}");
			}
		}
	}
	internal static class LethalConfigIntegration
	{
		internal static void Initialize()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			LethalConfigManager.SkipAutoGen();
			LethalConfigManager.SetModDescription("PizzaTowerEscapeMusic");
			ConfigEntry<float> volumeMaster = PizzaTowerEscapeMusicManager.Configuration.volumeMaster;
			FloatStepSliderOptions val = new FloatStepSliderOptions
			{
				Name = "Master Volume",
				RequiresRestart = false
			};
			((BaseRangeOptions<float>)val).Min = 0f;
			((BaseRangeOptions<float>)val).Max = 1f;
			val.Step = 0.01f;
			FloatSliderConfigItem val2 = new FloatSliderConfigItem(volumeMaster, (FloatSliderOptions)val);
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val2);
			ConfigEntry<string> selectLabelManually = PizzaTowerEscapeMusicManager.Configuration.selectLabelManually;
			TextInputFieldConfigItem val3 = new TextInputFieldConfigItem(selectLabelManually, new TextInputFieldOptions
			{
				Name = "Select Label Manually",
				RequiresRestart = false,
				CharacterLimit = 200
			});
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val3);
		}
	}
}
namespace PizzaTowerEscapeMusic.Networking
{
	public static class SeedSyncService
	{
		private static ManualLogSource logger = Logger.CreateLogSource("PizzaTowerEscapeMusic SeedSyncService");

		private static bool seedReceived = false;

		private static int capturedSeed = -1;

		public static bool SeedReceived => seedReceived;

		public static int CapturedSeed => capturedSeed;

		public static event Action OnSeedReceived;

		public static void SetSeedReceived(int seed = -1)
		{
			if (!seedReceived)
			{
				seedReceived = true;
				capturedSeed = seed;
				logger.LogDebug((object)$"SeedReceived flag set with seed: {seed}");
				SeedSyncService.OnSeedReceived?.Invoke();
			}
		}

		public static void ResetSeedReceived()
		{
			if (seedReceived)
			{
				capturedSeed = -1;
				seedReceived = false;
				logger.LogDebug((object)"SeedReceived flag reset");
			}
		}

		public static void LogStatus()
		{
			logger.LogDebug((object)$"SeedReceived = {SeedReceived}");
		}
	}
	[HarmonyPatch]
	internal static class SeedSyncPatches
	{
		private static ManualLogSource logger = Logger.CreateLogSource("PizzaTowerEscapeMusic SeedSyncPatches");

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "OnPlayerConnectedClientRpc", new Type[]
		{
			typeof(ulong),
			typeof(int),
			typeof(ulong[]),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(bool)
		})]
		private static void OnPlayerConnectedClientRpc_Postfix(ulong clientId, int connectedPlayers, ulong[] connectedPlayerIdsOrdered, int assignedPlayerObjectId, int serverMoneyAmount, int levelID, int profitQuota, int timeUntilDeadline, int quotaFulfilled, int randomSeed, bool isChallenge)
		{
			logger.LogDebug((object)$"OnPlayerConnectedClientRpc captured randomSeed: {randomSeed}");
			SeedSyncService.SetSeedReceived(randomSeed);
		}

		internal static void ApplyPatches()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			try
			{
				Harmony val = new Harmony("com.pizzatowerescapemusic.seedsync");
				val.PatchAll(Assembly.GetExecutingAssembly());
				logger.LogInfo((object)"SeedSync Harmony patches applied successfully");
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"Failed to apply SeedSync Harmony patches: {arg}");
			}
		}

		internal static void RemovePatches()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			try
			{
				Harmony val = new Harmony("com.pizzatowerescapemusic.seedsync");
				val.UnpatchSelf();
				logger.LogInfo((object)"SeedSync Harmony patches removed");
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"Failed to remove SeedSync Harmony patches: {arg}");
			}
		}
	}
}
namespace PizzaTowerEscapeMusic.Scripting
{
	public class Script
	{
		public class VolumeRule
		{
			public string comment = string.Empty;

			[JsonRequired]
			public float volume;

			public Condition condition;
		}

		public class VolumeModifier
		{
			public string comment = string.Empty;

			[JsonRequired]
			public float volumeScale;

			public float volumeLerpSpeedScale = 1f;

			public float stoppingVolumeLerpSpeedScale = 1f;

			public Condition condition;
		}

		public class VolumeGroup
		{
			public string comment = string.Empty;

			public string tag = string.Empty;

			public float volumeLerpSpeed = 1f;

			public float stoppingVolumeLerpSpeed = 1f;

			public float masterVolume = 1f;

			public VolumeRule[] volumeRules = Array.Empty<VolumeRule>();

			public VolumeModifier[] volumeModifiers = Array.Empty<VolumeModifier>();

			public float GetVolume(Script script)
			{
				float num = 1f;
				VolumeRule[] array = volumeRules;
				foreach (VolumeRule volumeRule in array)
				{
					if (volumeRule.condition == null || volumeRule.condition.Check(script))
					{
						num = volumeRule.volume;
						break;
					}
				}
				VolumeModifier[] array2 = volumeModifiers;
				foreach (VolumeModifier volumeModifier in array2)
				{
					if (volumeModifier.condition == null || volumeModifier.condition.Check(script))
					{
						num *= volumeModifier.volumeScale;
					}
				}
				return num * masterVolume;
			}

			public float GetVolumeLerpSpeedScale(Script script)
			{
				float num = 1f;
				VolumeModifier[] array = volumeModifiers;
				foreach (VolumeModifier volumeModifier in array)
				{
					if (volumeModifier.condition == null || volumeModifier.condition.Check(script))
					{
						num *= volumeModifier.volumeLerpSpeedScale;
					}
				}
				return num;
			}

			public float GetStoppingVolumeLerpSpeedScale(Script script)
			{
				float num = 1f;
				VolumeModifier[] array = volumeModifiers;
				foreach (VolumeModifier volumeModifier in array)
				{
					if (volumeModifier.condition == null || volumeModifier.condition.Check(script))
					{
						num *= volumeModifier.stoppingVolumeLerpSpeedScale;
					}
				}
				return num;
			}
		}

		public class Timer
		{
			public string name;

			public float time;

			public Timer(string name)
			{
				this.name = name;
			}
		}

		public class Counter
		{
			public string name;

			public int count;

			public Counter(string name)
			{
				this.name = name;
			}
		}

		public string comment = string.Empty;

		public bool isAddon;

		public VolumeGroup[] volumeGroups = Array.Empty<VolumeGroup>();

		[JsonRequired]
		public ScriptEvent[] scriptEvents = Array.Empty<ScriptEvent>();

		[JsonIgnore]
		public readonly Dictionary<ScriptEvent.GameEventType, List<ScriptEvent>> loadedScriptEvents = new Dictionary<ScriptEvent.GameEventType, List<ScriptEvent>>();

		[JsonIgnore]
		public readonly Dictionary<string, VolumeGroup> loadedScriptVolumeGroups = new Dictionary<string, VolumeGroup>();

		[JsonIgnore]
		public readonly Dictionary<string, Timer> activeTimers = new Dictionary<string, Timer>();

		[JsonIgnore]
		public readonly Dictionary<string, Counter> activeCounters = new Dictionary<string, Counter>();

		[JsonIgnore]
		public readonly Dictionary<string, string> selectedLabelsByGroup = new Dictionary<string, string>();

		[JsonIgnore]
		public static VolumeGroup DefaultVolumeGroup { get; private set; } = new VolumeGroup();


		[JsonIgnore]
		public string selectedLabel
		{
			get
			{
				if (selectedLabelsByGroup.TryGetValue("", out var value))
				{
					return value;
				}
				return string.Empty;
			}
			set
			{
				selectedLabelsByGroup[""] = value;
			}
		}

		public void Initialise(ManualLogSource logger)
		{
			ScriptEvent[] array = scriptEvents;
			foreach (ScriptEvent scriptEvent in array)
			{
				if (!loadedScriptEvents.TryGetValue(scriptEvent.gameEventType, out var value))
				{
					value = new List<ScriptEvent>(1);
					loadedScriptEvents.Add(scriptEvent.gameEventType, value);
				}
				value.Add(scriptEvent);
			}
			VolumeGroup[] array2 = volumeGroups;
			foreach (VolumeGroup volumeGroup in array2)
			{
				if (!loadedScriptVolumeGroups.ContainsKey(volumeGroup.tag))
				{
					loadedScriptVolumeGroups.Add(volumeGroup.tag, volumeGroup);
				}
				else
				{
					logger.LogError((object)("Volume group tag \"" + volumeGroup.tag + "\" was already declared, you cannot have two volume groups with the same tag"));
				}
			}
		}

		public VolumeGroup TryGetVolumeGroupOrDefault(string tag)
		{
			if (tag == null || !loadedScriptVolumeGroups.ContainsKey(tag))
			{
				return DefaultVolumeGroup;
			}
			return loadedScriptVolumeGroups[tag];
		}

		public bool TryGetVolumeGroup(string tag, out VolumeGroup volumeGroup)
		{
			if (tag == null || !loadedScriptVolumeGroups.ContainsKey(tag))
			{
				volumeGroup = null;
				return false;
			}
			volumeGroup = loadedScriptVolumeGroups[tag];
			return true;
		}

		public void UpdateTimers(float deltaTime)
		{
			foreach (Timer value in activeTimers.Values)
			{
				value.time += deltaTime;
			}
		}

		public void ClearTimers()
		{
			activeTimers.Clear();
		}

		internal void ClearTimer(string timerName)
		{
			activeTimers.Remove(timerName);
		}

		public void ClearCounters()
		{
			activeCounters.Clear();
		}

		internal void ClearCounter(string counterName)
		{
			activeCounters.Remove(counterName);
		}
	}
	public class ScriptManager
	{
		private GameEventListener gameEventListener;

		private bool pendingManualLabelSelection = false;

		private bool selectLabelManuallyValid = true;

		private Dictionary<ScriptEvent.GameEventType, float> lastLogTimeByEvent = new Dictionary<ScriptEvent.GameEventType, float>();

		private bool enablelogCooldown = true;

		public readonly List<Script> loadedScripts = new List<Script>();

		public bool SelectLabelManuallyValid => selectLabelManuallyValid;

		public ManualLogSource Logger { get; private set; }

		public ScriptManager(string[] scriptNames, GameEventListener gameEventListener)
		{
			Logger = Logger.CreateLogSource("PizzaTowerEscapeMusic ScriptManager");
			this.gameEventListener = gameEventListener;
			Script script = new Script();
			loadedScripts.Add(script);
			foreach (string text in scriptNames)
			{
				if (string.IsNullOrWhiteSpace(text))
				{
					Logger.LogDebug((object)"Skipping empty script name");
					continue;
				}
				Script script2 = DeserializeScript(text);
				if (script2 != null)
				{
					script2.Initialise(Logger);
					if (script2.isAddon)
					{
						List<Script.VolumeGroup> list = script.volumeGroups.ToList();
						list.AddRange(script2.volumeGroups);
						script.volumeGroups = list.ToArray();
						List<ScriptEvent> list2 = script.scriptEvents.ToList();
						list2.AddRange(script2.scriptEvents);
						script.scriptEvents = list2.ToArray();
					}
					else
					{
						loadedScripts.Add(script2);
					}
					if (script2.isAddon)
					{
						Logger.LogInfo((object)("Script (" + text + ") loaded as addon"));
					}
					else
					{
						Logger.LogInfo((object)("Script (" + text + ") loaded"));
					}
				}
			}
			script.Initialise(Logger);
			gameEventListener.OnFrameUpdate = (Action)Delegate.Combine(gameEventListener.OnFrameUpdate, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.FrameUpdated);
			});
			gameEventListener.OnShipLanded = (Action)Delegate.Combine(gameEventListener.OnShipLanded, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ShipLanded);
			});
			gameEventListener.OnShipTakeOff = (Action)Delegate.Combine(gameEventListener.OnShipTakeOff, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ShipTakeOff);
			});
			gameEventListener.OnShipInOrbit = (Action)Delegate.Combine(gameEventListener.OnShipInOrbit, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ShipInOrbit);
			});
			gameEventListener.OnShipInOrbit = (Action)Delegate.Combine(gameEventListener.OnShipInOrbit, (Action)delegate
			{
				if (pendingManualLabelSelection)
				{
					pendingManualLabelSelection = false;
					ApplySelectedLabels();
				}
			});
			gameEventListener.OnShipLeavingAlertCalled = (Action)Delegate.Combine(gameEventListener.OnShipLeavingAlertCalled, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ShipLeavingAlertCalled);
			});
			gameEventListener.OnPlayerDamaged = (Action)Delegate.Combine(gameEventListener.OnPlayerDamaged, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerDamaged);
			});
			gameEventListener.OnPlayerDeath = (Action)Delegate.Combine(gameEventListener.OnPlayerDeath, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerDied);
			});
			gameEventListener.OnPlayerEnteredFacility = (Action)Delegate.Combine(gameEventListener.OnPlayerEnteredFacility, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerEnteredFacility);
			});
			gameEventListener.OnPlayerExitedFacility = (Action)Delegate.Combine(gameEventListener.OnPlayerExitedFacility, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerExitedFacility);
			});
			gameEventListener.OnPlayerEnteredShip = (Action)Delegate.Combine(gameEventListener.OnPlayerEnteredShip, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerEnteredShip);
			});
			gameEventListener.OnPlayerExitedShip = (Action)Delegate.Combine(gameEventListener.OnPlayerExitedShip, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerExitedShip);
			});
			gameEventListener.OnApparatusTaken = (Action)Delegate.Combine(gameEventListener.OnApparatusTaken, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ApparatusTaken);
			});
			gameEventListener.OnMeltdownStarted = (Action)Delegate.Combine(gameEventListener.OnMeltdownStarted, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.MeltdownStarted);
			});
			gameEventListener.OnLevelLoaded = (Action)Delegate.Combine(gameEventListener.OnLevelLoaded, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.LevelLoaded);
			});
			gameEventListener.OnEndOfGame = (Action)Delegate.Combine(gameEventListener.OnEndOfGame, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.EndOfGame);
			});
			gameEventListener.OnFiringPlayers = (Action)Delegate.Combine(gameEventListener.OnFiringPlayers, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.FiringPlayers);
			});
			gameEventListener.OnGameOver = (Action)Delegate.Combine(gameEventListener.OnGameOver, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.GameOver);
			});
			gameEventListener.OnShipNotInOrbit = (Action)Delegate.Combine(gameEventListener.OnShipNotInOrbit, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ShipNotInOrbit);
			});
			gameEventListener.OnCurrentMoonChanged = (Action<SelectableLevel>)Delegate.Combine(gameEventListener.OnCurrentMoonChanged, (Action<SelectableLevel>)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.CurrentMoonChanged);
			});
			Logger.LogInfo((object)"Done loading scripts");
			ApplySelectedLabels();
		}

		private void CheckScriptEvents(ScriptEvent.GameEventType eventType)
		{
			foreach (Script loadedScript in loadedScripts)
			{
				if (!loadedScript.loadedScriptEvents.TryGetValue(eventType, out var value))
				{
					continue;
				}
				foreach (ScriptEvent item in value)
				{
					if (!item.CheckConditions(loadedScript))
					{
						continue;
					}
					bool flag = true;
					if (enablelogCooldown)
					{
						if (!lastLogTimeByEvent.TryGetValue(eventType, out var value2))
						{
							value2 = -15f;
						}
						if (Time.time - value2 >= 15f)
						{
							lastLogTimeByEvent[eventType] = Time.time;
						}
						else
						{
							flag = false;
						}
					}
					if (flag)
					{
						Logger.LogDebug((object)("Conditions for a script event have been met!\n Script Event Type: " + item.scriptEventType + $"\n   Game Event Type: {item.gameEventType}" + "\n           Comment: " + item.comment));
					}
					item.Run(loadedScript);
				}
			}
		}

		private Script DeserializeScript(string name)
		{
			string filePath = CustomManager.GetFilePath("Scripts/" + name + ".json", "DefaultScripts/" + name + ".json");
			if (!File.Exists(filePath))
			{
				Logger.LogError((object)("Script \"" + name + "\" does not exist! Make sure you spelt it right the config, and make sure its file extension is \".json\""));
				return null;
			}
			string text = File.ReadAllText(filePath);
			Script result;
			try
			{
				result = JsonConvert.DeserializeObject<Script>(text);
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Failed to deserialize script \"" + name + "\":\n" + ex.Message));
				result = null;
			}
			return result;
		}

		public void UpdateAllScriptTimers(float deltaTime)
		{
			foreach (Script loadedScript in loadedScripts)
			{
				loadedScript.UpdateTimers(deltaTime);
			}
		}

		public void ClearAllScriptTimers()
		{
			foreach (Script loadedScript in loadedScripts)
			{
				loadedScript.ClearTimers();
			}
		}

		public void ClearAllScriptCounters()
		{
			foreach (Script loadedScript in loadedScripts)
			{
				loadedScript.ClearCounters();
			}
		}

		public void ApplySelectedLabels()
		{
			if ((Object)(object)StartOfRound.Instance != (Object)null && !StartOfRound.Instance.inShipPhase)
			{
				pendingManualLabelSelection = true;
				Logger.LogInfo((object)"Cannot apply manual label selection when not in ship phase, Changes pending");
				return;
			}
			pendingManualLabelSelection = false;
			string text = PizzaTowerEscapeMusicManager.Configuration?.selectLabelManually?.Value;
			if (string.IsNullOrWhiteSpace(text))
			{
				selectLabelManuallyValid = true;
				return;
			}
			string[] array = text.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			bool flag = true;
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				string[] array3 = text2.Split(new char[1] { ':' }, 2);
				if (array3.Length != 2)
				{
					Logger.LogWarning((object)("Invalid selectLabelManually entry: '" + text2 + "', expected Group:Label"));
					flag = false;
					continue;
				}
				string text3 = array3[0].Trim();
				string text4 = array3[1].Trim();
				if (string.IsNullOrEmpty(text3) || string.IsNullOrEmpty(text4))
				{
					Logger.LogWarning((object)("Empty group or label in entry: '" + text2 + "'"));
					flag = false;
					continue;
				}
				if (dictionary.ContainsKey(text3))
				{
					Logger.LogWarning((object)("Duplicate group '" + text3 + "' in selectLabelManually configuration, will use label '" + text4 + "' (previous label '" + dictionary[text3] + "')"));
				}
				dictionary[text3] = text4;
			}
			selectLabelManuallyValid = flag;
			foreach (KeyValuePair<string, string> item in dictionary)
			{
				string key = item.Key;
				string value = item.Value;
				foreach (Script loadedScript in loadedScripts)
				{
					loadedScript.selectedLabelsByGroup[key] = value;
				}
				Logger.LogDebug((object)("Applied manual label selection: group='" + key + "', label='" + value + "'"));
			}
		}
	}
}
namespace PizzaTowerEscapeMusic.Scripting.ScriptEvents
{
	[JsonConverter(typeof(ScriptEventConverter))]
	public abstract class ScriptEvent
	{
		public enum GameEventType
		{
			FrameUpdated,
			ShipLanded,
			ShipTakeOff,
			ShipLeavingAlertCalled,
			PlayerDamaged,
			PlayerDied,
			PlayerEnteredFacility,
			PlayerExitedFacility,
			PlayerEnteredShip,
			PlayerExitedShip,
			ApparatusTaken,
			CurrentMoonChanged,
			MeltdownStarted,
			ShipInOrbit,
			ShipNotInOrbit,
			LevelLoaded,
			EndOfGame,
			FiringPlayers,
			GameOver
		}

		public string comment = string.Empty;

		[JsonRequired]
		public string scriptEventType = string.Empty;

		[JsonRequired]
		public GameEventType gameEventType;

		public Condition[] conditions = Array.Empty<Condition>();

		public bool CheckConditions(Script script)
		{
			return !conditions.Any((Condition c) => !c.Check(script));
		}

		public abstract void Run(Script script);
	}
	public class ScriptEventConverter : JsonConverter<ScriptEvent>
	{
		public override bool CanWrite => false;

		public override ScriptEvent ReadJson(JsonReader reader, Type objectType, ScriptEvent existingValue, bool hasExistingValue, JsonSerializer serializer)
		{
			JObject val = JObject.Load(reader);
			JToken val2 = default(JToken);
			if (!val.TryGetValue("scriptEventType", ref val2))
			{
				throw new Exception("scriptEventType type is null!");
			}
			ScriptEvent scriptEvent = Extensions.Value<string>((IEnumerable<JToken>)val2) switch
			{
				"SetVolumeGroupMasterVolume" => new ScriptEvent_SetVolumeGroupMasterVolume(), 
				"LabelRandom" => new ScriptEvent_LabelRandom(), 
				"ResetCounters" => new ScriptEvent_ResetCounters(), 
				"ResetTimers" => new ScriptEvent_ResetTimers(), 
				"StopMusic" => new ScriptEvent_StopMusic(), 
				"PlayMusic" => new ScriptEvent_PlayMusic(), 
				_ => throw new Exception($"Condition type \"{val2}\" does not exist"), 
			};
			serializer.Populate(((JToken)val).CreateReader(), (object)scriptEvent);
			return scriptEvent;
		}

		public override void WriteJson(JsonWriter writer, ScriptEvent value, JsonSerializer serializer)
		{
			throw new NotImplementedException();
		}
	}
	public class ScriptEvent_PlayMusic : ScriptEvent
	{
		public enum OverlapHandling
		{
			IgnoreAll,
			IgnoreTag,
			OverrideAll,
			OverrideTag,
			OverrideFadeAll,
			OverrideFadeTag,
			Overlap
		}

		public bool loop;

		public bool silenceGameMusic = true;

		[JsonRequired]
		public OverlapHandling overlapHandling;

		public string tag;

		[JsonRequired]
		public string[] musicNames = Array.Empty<string>();

		public string[] introMusicNames = Array.Empty<string>();

		public override void Run(Script script)
		{
			if (musicNames.Length != 0)
			{
				PizzaTowerEscapeMusicManager.MusicManager.PlayMusic(script, this);
			}
		}
	}
	public class ScriptEvent_ResetTimers : ScriptEvent
	{
		public string[] targetTimerNames;

		public override void Run(Script script)
		{
			if (targetTimerNames != null)
			{
				string[] array = targetTimerNames;
				foreach (string timerName in array)
				{
					script.ClearTimer(timerName);
				}
			}
		}
	}
	public class ScriptEvent_ResetCounters : ScriptEvent
	{
		public string[] targetCounterNames;

		public override void Run(Script script)
		{
			if (targetCounterNames != null)
			{
				string[] array = targetCounterNames;
				foreach (string counterName in array)
				{
					script.ClearCounter(counterName);
				}
			}
		}
	}
	public class ScriptEvent_SetVolumeGroupMasterVolume : ScriptEvent
	{
		public string[] targetTags = Array.Empty<string>();

		[JsonRequired]
		public float masterVolume;

		public override void Run(Script script)
		{
			if (targetTags.Length == 0)
			{
				Script.DefaultVolumeGroup.masterVolume = masterVolume;
				return;
			}
			string[] array = targetTags;
			foreach (string text in array)
			{
				if (!script.loadedScriptVolumeGroups.TryGetValue(text, out var value))
				{
					PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)("Script Event SetVolumeGroupMasterVolume was called for volume group with tag \"" + text + "\", but there is no volume group of that tag"));
				}
				else
				{
					value.masterVolume = masterVolume;
				}
			}
		}
	}
	public class ScriptEvent_StopMusic : ScriptEvent
	{
		public string[] targetTags;

		public bool instant;

		public override void Run(Script script)
		{
			if (targetTags != null)
			{
				string[] array = targetTags;
				foreach (string targetTag in array)
				{
					if (instant)
					{
						PizzaTowerEscapeMusicManager.MusicManager.StopMusic(targetTag);
					}
					else
					{
						PizzaTowerEscapeMusicManager.MusicManager.FadeStopMusic(targetTag);
					}
				}
			}
			else if (instant)
			{
				PizzaTowerEscapeMusicManager.MusicManager.StopMusic();
			}
			else
			{
				PizzaTowerEscapeMusicManager.MusicManager.FadeStopMusic();
			}
		}
	}
	public class ScriptEvent_LabelRandom : ScriptEvent
	{
		private struct QueuedLabelRandom
		{
			public Script script;

			public string group;

			public string[] labels;

			public List<(string label, float weight)> entries;

			public float totalWeight;
		}

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

			private object <>2__current;

			public Script script;

			public string group;

			public string[] labels;

			public List<(string label, float weight)> entries;

			public float totalWeight;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					SelectLabelWithSeed(script, group, labels, entries, totalWeight);
					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();
			}
		}

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

			private object <>2__current;

			private QueuedLabelRandom <queued>5__1;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<queued>5__1 = default(QueuedLabelRandom);
				<>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;
					queueProcessing = true;
					<>2__current = (object)new WaitForSeconds(0.2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					while (pendingEvents.Count > 0)
					{
						<queued>5__1 = pendingEvents.Dequeue();
						ExecuteWithDelay(<queued>5__1.script, <queued>5__1.group, <queued>5__1.labels, <queued>5__1.entries, <queued>5__1.totalWeight);
						<queued>5__1 = default(QueuedLabelRandom);
					}
					queueProcessing = false;
					PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogDebug((object)"LabelRandom: queue processed");
					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();
			}
		}

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

			private object <>2__current;

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

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

			[DebuggerHidden]
			public <WaitForSyncedThenProcess>d__7(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;
					break;
				}
				if (!GameEventListener.SyncedrandomMapSeed)
				{
					<>2__current = (object)new WaitForSeconds(0.2f);
					<>1__state = 1;
					return true;
				}
				PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogDebug((object)"LabelRandom: SyncedrandomMapSeed");
				ProcessQueue();
				return false;
			}

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

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

		private static Queue<QueuedLabelRandom> pendingEvents = new Queue<QueuedLabelRandom>();

		private static bool queueProcessing = false;

		private static bool subscribedToSeedReceived = false;

		[JsonRequired]
		public string group = string.Empty;

		[JsonRequired]
		public string[] labels = Array.Empty<string>();

		public override void Run(Script script)
		{
			if (string.IsNullOrEmpty(group))
			{
				PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)"LabelRandom: group must be specified and non-empty");
			}
			else
			{
				if (labels.Length == 0)
				{
					return;
				}
				List<(string, float)> list = new List<(string, float)>();
				float num = 0f;
				string[] array = labels;
				foreach (string text in array)
				{
					string[] array2 = text.Split(new char[1] { ':' });
					if (array2.Length != 2)
					{
						PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)("LabelRandom: malformed entry '" + text + "', expected 'label:weight'"));
						continue;
					}
					string text2 = array2[0].Trim();
					if (string.IsNullOrEmpty(text2))
					{
						PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)("LabelRandom: label is empty '" + text + "'"));
						continue;
					}
					if (!float.TryParse(array2[1], out var result))
					{
						PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)("LabelRandom: weight is not a number '" + text + "'"));
						continue;
					}
					if (result <= 0f)
					{
						PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)("LabelRandom: weight must be positive '" + text + "'"));
						continue;
					}
					list.Add((text2, result));
					num += result;
				}
				if (list.Count == 0)
				{
					return;
				}
				if (PizzaTowerEscapeMusicManager.Configuration != null && PizzaTowerEscapeMusicManager.Configuration.useRandomMapSeed != null && PizzaTowerEscapeMusicManager.Configuration.useRandomMapSeed.Value)
				{
					if ((Object)(object)StartOfRound.Instance == (Object)null)
					{
						PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogDebug((object)"LabelRandom: StartOfRound instance is null, skipping");
					}
					else if ((((NetworkBehaviour)StartOfRound.Instance).IsHost && ((NetworkBehaviour)StartOfRound.Instance).IsServer) || (SeedSyncService.SeedReceived && GameEventListener.SyncedrandomMapSeed) || (PizzaTowerEscapeMusicManager.Configuration.dontQueue != null && PizzaTowerEscapeMusicManager.Configuration.dontQueue.Value))
					{
						ExecuteWithDelay(script, group, labels, list, num);
					}
					else
					{
						EnqueueEvent(script, group, labels, list, num);
					}
				}
				else
				{
					float randomValue = Random.Range(0f, num);
					SelectLabel(script, group, list, num, randomValue);
				}
			}
		}

		private static void EnqueueEvent(Script script, string group, string[] labels, List<(string label, float weight)> entries, float totalWeight)
		{
			QueuedLabelRandom queuedLabelRandom = default(QueuedLabelRandom);
			queuedLabelRandom.script = script;
			queuedLabelRandom.group = group;
			queuedLabelRandom.labels = labels;
			queuedLabelRandom.entries = entries;
			queuedLabelRandom.totalWeight = totalWeight;
			QueuedLabelRandom item = queuedLabelRandom;
			pendingEvents.Enqueue(item);
			PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogDebug((object)$"LabelRandom: event queued (waiting for seed). Queue size: {pendingEvents.Count}");
			if (!subscribedToSeedReceived)
			{
				SeedSyncService.OnSeedReceived += OnSeedReceived;
				subscribedToSeedReceived = true;
			}
		}

		private static void OnSeedReceived()
		{
			PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogDebug((object)"LabelRandom: OnSeedReceived");
			if (GameEventListener.SyncedrandomMapSeed)
			{
				ProcessQueue();
				return;
			}
			GameEventListener gameEventListener = GameEventListener.Instance ?? Object.FindObjectOfType<GameEventListener>();
			if ((Object)(object)gameEventListener == (Object)null)
			{
				PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)"LabelRandom: cannot find GameEventListener instance, cannot wait for sync");
			}
			else
			{
				((MonoBehaviour)gameEventListener).StartCoroutine(WaitForSyncedThenProcess());
			}
		}

		[IteratorStateMachine(typeof(<WaitForSyncedThenProcess>d__7))]
		private static IEnumerator WaitForSyncedThenProcess()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForSyncedThenProcess>d__7(0);
		}

		private static void ProcessQueue()
		{
			if (!queueProcessing)
			{
				GameEventListener gameEventListener = GameEventListener.Instance ?? Object.FindObjectOfType<GameEventListener>();
				if ((Object)(object)gameEventListener == (Object)null)
				{
					PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)"LabelRandom: cannot find GameEventListener instance, cannot start delay coroutine");
				}
				else
				{
					((MonoBehaviour)gameEventListener).StartCoroutine(ProcessQueueWithDelay());
				}
			}
		}

		[IteratorStateMachine(typeof(<ProcessQueueWithDelay>d__9))]
		private static IEnumerator ProcessQueueWithDelay()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ProcessQueueWithDelay>d__9(0);
		}

		private static void ExecuteWithDelay(Script script, string group, string[] labels, List<(string label, float weight)> entries, float totalWeight)
		{
			GameEventListener gameEventListener = GameEventListener.Instance ?? Object.FindObjectOfType<GameEventListener>();
			if ((Object)(object)gameEventListener == (Object)null)
			{
				PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)"LabelRandom: cannot find GameEventListener to start coroutine, falling back to immediate selection");
				SelectLabelWithSeed(script, group, labels, entries, totalWeight);
			}
			else
			{
				((MonoBehaviour)gameEventListener).StartCoroutine(DelayedSelection(script, group, labels, entries, totalWeight));
			}
		}

		[IteratorStateMachine(typeof(<DelayedSelection>d__11))]
		private static IEnumerator DelayedSelection(Script script, string group, string[] labels, List<(string label, float weight)> entries, float totalWeight)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedSelection>d__11(0)
			{
				script = script,
				group = group,
				labels = labels,
				entries = entries,
				totalWeight = totalWeight
			};
		}

		private static void SelectLabelWithSeed(Script script, string group, string[] labels, List<(string label, float weight)> entries, float totalWeight)
		{
			int randomMapSeed = StartOfRound.Instance.randomMapSeed;
			int num = group.GetHashCode();
			foreach (string text in labels)
			{
				num ^= text.GetHashCode();
			}
			int seed = randomMapSeed ^ num;
			Random random = new Random(seed);
			float randomValue = (float)(random.NextDouble() * (double)totalWeight);
			SelectLabel(script, group, entries, totalWeight, randomValue);
		}

		private static void SelectLabel(Script script, string group, List<(string label, float weight)> entries, float totalWeight, float randomValue)
		{
			string text = PizzaTowerEscapeMusicManager.Configuration?.selectLabelManually?.Value;
			if (!string.IsNullOrWhiteSpace(text))
			{
				ScriptManager scriptManager = PizzaTowerEscapeMusicManager.ScriptManager;
				if (scriptManager != null && scriptManager.SelectLabelManuallyValid)
				{
					string[] array = text.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
					string[] array2 = array;
					foreach (string text2 in array2)
					{
						string[] array3 = text2.Split(new char[1] { ':' }, 2);
						if (array3.Length == 2)
						{
							string text3 = array3[0].Trim();
							string text4 = array3[1].Trim();
							if (text3.Equals(group))
							{
								string text5 = (string.IsNullOrEmpty(group) ? "" : group);
								script.selectedLabelsByGroup[text5] = text4;
								PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogDebug((object)("LabelRandom: using manually selected label '" + text4 + "' for group '" + text5 + "'"));
								return;
							}
						}
					}
				}
			}
			float num = 0f;
			string text6 = null;
			foreach (var entry in entries)
			{
				string item = entry.label;
				float item2 = entry.weight;
				num += item2;
				if (randomValue <= num)
				{
					text6 = item;
					break;
				}
			}
			if (text6 != null)
			{
				string text7 = (string.IsNullOrEmpty(group) ? "" : group);
				script.selectedLabelsByGroup[text7] = text6;
				PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogDebug((object)("LabelRandom: selected label '" + text6 + "' for group '" + text7 + "'"));
			}
		}

		public static void ClearQueueAndFlags()
		{
			pendingEvents.Clear();
			queueProcessing = false;
			subscribedToSeedReceived = false;
			SeedSyncService.OnSeedReceived -= OnSeedReceived;
			PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogDebug((object)"LabelRandom: queue and flags cleared");
		}
	}
}
namespace PizzaTowerEscapeMusic.Scripting.Conditions
{
	[JsonConverter(typeof(ConditionConverter))]
	public abstract class Condition
	{
		[JsonRequired]
		public string conditionType = string.Empty;

		public abstract bool Check(Script script);
	}
	public abstract class ConditionComparableNumber : Condition
	{
		public enum ComparisonType
		{
			Equals,
			NotEquals,
			GreaterThan,
			LessThan,
			GreaterThanOrEquals,
			LessThanOrEquals
		}

		[JsonRequired]
		public ComparisonType comparisonType;
	}
	public class Condition_And : Condition
	{
		[JsonRequired]
		public Condition[] conditions = Array.Empty<Condition>();

		public override bool Check(Script script)
		{
			return !conditions.Any((Condition c) => !c.Check(script));
		}
	}
	public class Condition_ApparatusDocked : Condition
	{
		public override bool Check(Script script)
		{
			return GameEventListener.IsApparatusDocked();
		}
	}
	public class Condition_ApparatusTaked : Condition
	{
		public override bool Check(Script script)
		{
			return GameEventListener.ApparatusTaked;
		}
	}
	public class Condition_CurrentMoon : Condition
	{
		private static readonly Dictionary<string, int> moonNameToId = new Dictionary<string, int>();

		[JsonRequired]
		public string moonName = string.Empty;

		private bool isDisabled;

		public override bool Check(Script script)
		{
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return false;
			}
			if (isDisabled)
			{
				return false;
			}
			if (!moonNameToId.TryGetValue(moonName, out var value))
			{
				SelectableLevel[] levels = StartOfRound.Instance.levels;
				foreach (SelectableLevel val in levels)
				{
					if (!moonNameToId.ContainsKey(val.PlanetName))
					{
						moonNameToId.Add(val.PlanetName, val.levelID);
					}
				}
				if (!moonNameToId.TryGetValue(moonName, out value))
				{
					PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)("From CurrentMoon condition: Found no existing level with the name \"" + moonName + "\""));
					isDisabled = true;
					return false;
				}
			}
			return TimeOfDay.Instance.currentLevel.levelID == value;
		}
	}
	public class Condition_MusicWithTagPlaying : Condition
	{
		[JsonRequired]
		public string tag = string.Empty;

		public override bool Check(Script script)
		{
			return PizzaTowerEscapeMusicManager.MusicManager.GetIsMusicPlaying(tag);
		}
	}
	public class Condition_Not : Condition
	{
		[JsonRequired]
		public Condition condition;

		public override bool Check(Script script)
		{
			return condition == null || !condition.Check(script);
		}
	}
	public class Condition_Or : Condition
	{
		[JsonRequired]
		public Condition[] conditions = Array.Empty<Condition>();

		public override bool Check(Script script)
		{
			return conditions.Any((Condition c) => c.Check(script));
		}
	}
	public class Condition_PlayerAlive : Condition
	{
		public override bool Check(Script script)
		{
			return !((Object)(object)GameNetworkManager.Instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null) && !GameNetworkManager.Instance.localPlayerController.isPlayerDead;
		}
	}
	public class Condition_AllPlayersDead : Condition
	{
		public override bool Check(Script script)
		{
			return (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.allPlayersDead;
		}
	}
	public class Condition_PlayerCrouching : Condition
	{
		public override bool Check(Script script)
		{
			return !((Object)(object)GameNetworkManager.Instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null) && GameNetworkManager.Instance.localPlayerController.isCrouching;
		}
	}
	public class Condition_PlayerHealth : ConditionComparableNumber
	{
		[JsonRequired]
		public int value;

		public override bool Check(Script script)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			int health = GameNetworkManager.Instance.localPlayerController.health;
			return comparisonType switch
			{
				ComparisonType.Equals => health == value, 
				ComparisonType.NotEquals => health != value, 
				ComparisonType.GreaterThan => health > value, 
				ComparisonType.LessThan => health < value, 
				ComparisonType.GreaterThanOrEquals => health >= value, 
				ComparisonType.LessThanOrEquals => health <= value, 
				_ => false, 
			};
		}
	}
	public class Condition_PlayerInsanity : ConditionComparableNumber
	{
		[JsonRequired]
		public float level;

		public override bool Check(Script script)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			float num = GameNetworkManager.Instance.localPlayerController.insanityLevel / GameNetworkManager.Instance.localPlayerController.maxInsanityLevel;
			return comparisonType switch
			{
				ComparisonType.Equals => level == num, 
				ComparisonType.NotEquals => level != num, 
				ComparisonType.GreaterThan => level > num, 
				ComparisonType.LessThan => level < num, 
				ComparisonType.GreaterThanOrEquals => level >= num, 
				ComparisonType.LessThanOrEquals => level <= num, 
				_ => false, 
			};
		}
	}
	public class Condition_PlayerFearLevel : ConditionComparableNumber
	{
		[JsonRequired]
		public float level;

		public override bool Check(Script script)
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return false;
			}
			float fearLevel = StartOfRound.Instance.fearLevel;
			return comparisonType switch
			{
				ComparisonType.Equals => level == fearLevel, 
				ComparisonType.NotEquals => level != fearLevel, 
				ComparisonType.GreaterThan => level > fearLevel, 
				ComparisonType.LessThan => level < fearLevel, 
				ComparisonType.GreaterThanOrEquals => level >= fearLevel, 
				ComparisonType.LessThanOrEquals => level <= fearLevel, 
				_ => false, 
			};
		}
	}
	public class Condition_PlayerLocation : Condition
	{
		public enum Location
		{
			Ship,
			Facility
		}

		[JsonRequired]
		public Location location;

		public override bool Check(Script script)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			Location location = this.location;
			return (location == Location.Ship) ? GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom : (location == Location.Facility && GameNetworkManager.Instance.localPlayerController.isInsideFactory);
		}
	}
	public class Condition_PlayerAlone : Condition
	{
		public override bool Check(Script script)
		{
			return !((Object)(object)GameNetworkManager.Instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null) && GameNetworkManager.Instance.localPlayerController.isPlayerAlone;
		}
	}
	public class Condition_FiringPlayers : Condition
	{
		public override bool Check(Script script)
		{
			return !((Object)(object)StartOfRound.Instance == (Object)null) && StartOfRound.Instance.firingPlayersCutsceneRunning;
		}
	}
	public class Condition_Random : Condition
	{
		[JsonRequired]
		public float chance;

		public override bool Check(Script script)
		{
			return Random.Range(0f, 1f) <= chance;
		}
	}
	public class Condition_ShipLanded : Condition
	{
		public override bool Check(Script script)
		{
			return !((Object)(object)StartOfRound.Instance == (Object)null) && StartOfRound.Instance.shipHasLanded;
		}
	}
	public class Condition_ShipInOrbit : Condition
	{
		public override bool Check(Script script)
		{
			return !((Object)(object)StartOfRound.Instance == (Object)null) && StartOfRound.Instance.inShipPhase;
		}
	}
	public class Condition_ShipLeavingAlertCalled : Condition
	{
		public override bool Check(Script script)
		{
			return !((Object)(object)TimeOfDay.Instance == (Object)null) && TimeOfDay.Instance.shipLeavingAlertCalled;
		}
	}
	public class Condition_ShipIsLeaving : Condition
	{
		public override bool Check(Script script)
		{
			return !((Object)(object)StartOfRound.Instance == (Object)null) && StartOfRound.Instance.shipIsLeaving;
		}
	}
	public class Condition_TimeOfDay : ConditionComparableNumber
	{
		[JsonRequired]
		public float time;

		public override bool Check(Script script)
		{
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return false;
			}
			float num = TimeOfDay.Instance.currentDayTime / TimeOfDay.Instance.totalTime;
			return comparisonType switch
			{
				ComparisonType.Equals => num == time, 
				ComparisonType.NotEquals => num != time, 
				ComparisonType.GreaterThan => num > time, 
				ComparisonType.LessThan => num < time, 
				ComparisonType.GreaterThanOrEquals => num >= time, 
				ComparisonType.LessThanOrEquals => num <= time, 
				_ => false, 
			};
		}
	}
	public class Condition_Timer : Condition
	{
		[JsonRequired]
		public string timerName = string.Empty;

		[JsonRequired]
		public float timeGoal;

		public ConditionComparableNumber.ComparisonType? timerComparisonType;

		public override bool Check(Script script)
		{
			if (!script.activeTimers.TryGetValue(timerName, out var value))
			{
				value = new Script.Timer(timerName);
				script.activeTimers.Add(timerName, value);
			}
			ConditionComparableNumber.ComparisonType valueOrDefault = timerComparisonType.GetValueOrDefault(ConditionComparableNumber.ComparisonType.GreaterThanOrEquals);
			bool result = false;
			switch (valueOrDefault)
			{
			case ConditionComparableNumber.ComparisonType.Equals:
				result = value.time == timeGoal;
				break;
			case ConditionComparableNumber.ComparisonType.NotEquals:
				result = value.time != timeGoal;
				break;
			case ConditionComparableNumber.ComparisonType.GreaterThan:
				result = value.time > timeGoal;
				break;
			case ConditionComparableNumber.ComparisonType.LessThan:
				result = value.time < timeGoal;
				break;
			case ConditionComparableNumber.ComparisonType.GreaterThanOrEquals:
				result = value.time >= timeGoal;
				break;
			case ConditionComparableNumber.ComparisonType.LessThanOrEquals:
				result = value.time <= timeGoal;
				break;
			}
			return result;
		}
	}
	public class Condition_Counter : Condition
	{
		[JsonRequired]
		public string counterName = string.Empty;

		[JsonRequired]
		public int counterGoal;

		public ConditionComparableNumber.ComparisonType? counterComparisonType;

		public override bool Check(Script script)
		{
			if (!script.activeCounters.TryGetValue(counterName, out var value))
			{
				value = new Script.Counter(counterName);
				script.activeCounters.Add(counterName, value);
			}
			value.count++;
			ConditionComparableNumber.ComparisonType valueOrDefault = counterComparisonType.GetValueOrDefault(ConditionComparableNumber.ComparisonType.GreaterThanOrEquals);
			bool result = false;
			switch (valueOrDefault)
			{
			case ConditionComparableNumber.ComparisonType.Equals:
				result = value.count == counterGoal;
				break;
			case ConditionComparableNumber.ComparisonType.NotEquals:
				result = value.count != counterGoal;
				break;
			case ConditionComparableNumber.ComparisonType.GreaterThan:
				result = value.count > counterGoal;
				break;
			case ConditionComparableNumber.ComparisonType.LessThan:
				result = value.count < counterGoal;
				break;
			case ConditionComparableNumber.ComparisonType.GreaterThanOrEquals:
				result = value.count >= counterGoal;
				break;
			case ConditionComparableNumber.ComparisonType.LessThanOrEquals:
				result = value.count <= counterGoal;
				break;
			}
			return result;
		}
	}
	public class Condition_Weather : Condition
	{
		[JsonRequired]
		public object weather;

		private static Type _weatherConfigHelperType;

		private static MethodInfo _resolveWeatherMethod;

		private static PropertyInfo _vanillaWeatherTypeProp;

		public override bool Check(Script script)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return false;
			}
			LevelWeatherType currentLevelWeather = TimeOfDay.Instance.currentLevelWeather;
			if (weather is LevelWeatherType val)
			{
				return currentLevelWeather == val;
			}
			if (!(weather is string text) || _weatherConfigHelperType == null || _resolveWeatherMethod == null || _vanillaWeatherTypeProp == null)
			{
				return false;
			}
			bool result;
			try
			{
				object obj = _resolveWeatherMethod.Invoke(null, new object[1] { text });
				if (obj == null)
				{
					result = false;
				}
				else
				{
					LevelWeatherType val2 = (LevelWeatherType)_vanillaWeatherTypeProp.GetValue(obj);
					result = currentLevelWeather == val2;
				}
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		static Condition_Weather()
		{
			try
			{
				_weatherConfigHelperType = Type.GetType("WeatherRegistry.ConfigHelper, WeatherRegistry");
				if (_weatherConfigHelperType != null)
				{
					_resolveWeatherMethod = _weatherConfigHelperType.GetMethod("ResolveStringToWeather", new Type[1] { typeof(string) });
					Type type = Type.GetType("WeatherRegistry.Weather, WeatherRegistry");
					if (type != null)
					{
						_vanillaWeatherTypeProp = type.GetProperty("VanillaWeatherType");
					}
				}
			}
			catch (Exception)
			{
				_weatherConfigHelperType = null;
				_resolveWeatherMethod = null;
				_vanillaWeatherTypeProp = null;
			}
		}
	}
	public class Condition_SelectedLabel : Condition
	{
		[JsonRequired]
		public string label = string.Empty;

		[JsonRequired]
		public string group = string.Empty;

		public override bool Check(Script script)
		{
			if (string.IsNullOrEmpty(group))
			{
				PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)"Condition_SelectedLabel: group must be specified and non-empty");
				return false;
			}
			if (script.selectedLabelsByGroup.TryGetValue(group, out var value))
			{
				return value == label;
			}
			return false;
		}
	}
}