Decompiled source of Mutators v0.5.8

Mutators.dll

Decompiled 6 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mutators.Extensions;
using Mutators.Managers;
using Mutators.Mutators;
using Mutators.Mutators.Behaviours;
using Mutators.Mutators.Behaviours.Custom;
using Mutators.Mutators.Behaviours.UI;
using Mutators.Mutators.Patches;
using Mutators.Network;
using Mutators.Network.Meta;
using Mutators.Patches;
using Mutators.Settings;
using Mutators.Settings.Specific;
using Mutators.Utility;
using Photon.Pun;
using Photon.Realtime;
using REPOLib;
using REPOLib.Modules;
using Sirenix.Utilities;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Xepos")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.5.8.0")]
[assembly: AssemblyInformationalVersion("0.5.8+a00333adc72e7e85bf4d020a3d4823359670b49c")]
[assembly: AssemblyProduct("Mutators")]
[assembly: AssemblyTitle("Mutators")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.5.8.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
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 P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[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 P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Mutators
{
	internal class AssetStore
	{
		internal static ExplosionPreset Preset { get; set; }
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Xepos.REPO-Mutators";

		public const string NAME = "Mutators";

		public const string PLUGIN_VERSION = "0.5.8";
	}
	[BepInDependency("REPOLib", "2.1.0")]
	[BepInPlugin("Xepos.REPO-Mutators", "Mutators", "0.5.8")]
	public class RepoMutators : BaseUnityPlugin
	{
		internal const string MainScenePath = "Assets/Scenes/Main/Main.unity";

		internal const string NETWORKMANAGER_NAME = "MutatorsNetworkManager";

		internal static RepoMutators Instance { get; private set; }

		internal static ModSettings Settings { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "mutators");
			BundleLoader.LoadBundle(text, (Action<AssetBundle>)delegate(AssetBundle assetbundle)
			{
				AssetStore.Preset = assetbundle.LoadAsset<ExplosionPreset>("explosion default");
				GameObject val2 = assetbundle.LoadAsset<GameObject>("FiringMyLaser");
				val2.SetActive(false);
				val2.AddComponent<PhotonView>();
				val2.AddComponent<LaserFiringBehaviour>();
				NetworkPrefabs.RegisterNetworkPrefab("Xepos.REPO-Mutators/FiringMyLaser", val2);
				_logger.LogInfo((object)"Loaded Mutators asset bundle");
			}, false);
			Settings = new ModSettings(((BaseUnityPlugin)this).Config);
			MutatorSettings.Initialize(((BaseUnityPlugin)this).Config);
			GameObject val = new GameObject("RepoMutatorsPrefab")
			{
				hideFlags = (HideFlags)61
			};
			val.SetActive(false);
			val.AddComponent<PhotonView>();
			val.AddComponent<MutatorsNetworkManager>();
			string myPrefabId = "Xepos.REPO-Mutators/MutatorsNetworkManager";
			NetworkPrefabs.RegisterNetworkPrefab(myPrefabId, val);
			SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode loadSceneMode)
			{
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				if (!(((Scene)(ref scene)).path != "Assets/Scenes/Main/Main.unity") && SemiFunc.IsMasterClientOrSingleplayer())
				{
					if ((Object)(object)RunManager.instance.levelCurrent == (Object)(object)RunManager.instance.levelMainMenu)
					{
						if ((Object)(object)MutatorsNetworkManager.Instance != (Object)null && (Object)(object)((Component)MutatorsNetworkManager.Instance).gameObject != (Object)null)
						{
							Object.Destroy((Object)(object)((Component)MutatorsNetworkManager.Instance).gameObject);
						}
					}
					else if (!((Object)(object)MutatorsNetworkManager.Instance != (Object)null) && SemiFunc.RunIsLobbyMenu())
					{
						Logger.LogDebug((object)"Reviving network manager");
						NetworkPrefabs.SpawnNetworkPrefab(myPrefabId, Vector3.zero, Quaternion.identity, (byte)0, (object[])null);
						MutatorManager instance = MutatorManager.Instance;
						IMutator weightedMutator = instance.GetWeightedMutator();
						Logger.LogDebug((object)("Picked weighted mutator: " + weightedMutator.Name));
						instance.CurrentMutator = weightedMutator;
						MutatorsNetworkManager.Instance.SendActiveMutator(weightedMutator.Name);
						Logger.LogDebug((object)("Mutator set: " + weightedMutator.Name));
					}
				}
			};
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
			Logger.LogDebug((object)"Initializing default mutators.");
			MutatorManager.Instance.InitializeDefaultMutators();
		}

		internal void Patch()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_006f: Expected O, but got Unknown
			bool flag = Chainloader.PluginInfos.Values.Any((PluginInfo x) => x.Metadata.GUID == "soundedsquash.spawnmanager");
			_logger.LogInfo((object)$"HasSpawnManager: {flag}");
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll(typeof(RunManagerPatch));
			Harmony.PatchAll(typeof(LoadingUIPatch));
			Harmony.PatchAll(typeof(MapToolControllerPatch));
			Harmony.PatchAll(typeof(SemiFuncPatch));
			Harmony.PatchAll(typeof(MenuPagePatch));
			Harmony.PatchAll(typeof(SpectateCameraPatch));
			if (!flag)
			{
				Harmony.PatchAll(typeof(EnemyDirectorPatch));
			}
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			foreach (IMutator value in MutatorManager.Instance.RegisteredMutators.Values)
			{
				value.Unpatch();
			}
		}
	}
}
namespace Mutators.Utility
{
	internal static class DescriptionUtils
	{
		internal enum DescriptionReplacementType
		{
			REPLACE,
			PREPEND,
			APPEND
		}

		internal static IEnumerator LateUpdateDescription(string description, DescriptionReplacementType replacementType = DescriptionReplacementType.REPLACE)
		{
			while (!Object.op_Implicit((Object)(object)MutatorDescriptionAnnouncingBehaviour.Instance))
			{
				yield return (object)new WaitForSeconds(0.1f);
			}
			TextMeshProUGUI text = MutatorDescriptionAnnouncingBehaviour.Instance.Text;
			switch (replacementType)
			{
			case DescriptionReplacementType.REPLACE:
				((TMP_Text)text).text = description;
				break;
			case DescriptionReplacementType.PREPEND:
				((TMP_Text)text).text = description + "\n" + ((TMP_Text)text).text;
				break;
			case DescriptionReplacementType.APPEND:
				((TMP_Text)text).text = ((TMP_Text)text).text + "\n" + description;
				break;
			}
		}
	}
	public static class TemporaryItemUtils
	{
		public static void RemoveMarkedItems(string marker)
		{
			string marker2 = marker;
			StatsManager instance = StatsManager.instance;
			foreach (string item in (from item in instance.item
				where item.Key.Contains("(" + marker2 + ")")
				select item into x
				select x.Key).ToList())
			{
				instance.item.Remove(item);
				instance.itemStatBattery.Remove(item);
			}
		}

		public static void DropMarkedItems(string marker)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			Inventory instance = Inventory.instance;
			foreach (InventorySpot inventorySpot in instance.inventorySpots)
			{
				ItemEquippable currentItem = inventorySpot.CurrentItem;
				if (Object.op_Implicit((Object)(object)currentItem) && Object.op_Implicit((Object)(object)((Component)currentItem).gameObject.GetComponent<TemporaryLevelItemBehaviour>()))
				{
					((Component)currentItem).GetComponent<ItemEquippable>().ForceUnequip(instance.playerAvatar.PlayerVisionTarget.VisionTransform.position, SemiFunc.IsMultiplayer() ? instance.physGrabber.photonView.ViewID : (-1));
				}
			}
			RemoveMarkedItems(marker);
		}
	}
}
namespace Mutators.Settings
{
	public abstract class AbstractMutatorSettings
	{
		protected const string WeightConfigKey = "Weight";

		protected const string MinimumLevelConfigKey = "Minimum level";

		protected const string MaximumLevelConfigKey = "Maximum level";

		public abstract string MutatorName { get; }

		public abstract string MutatorDescription { get; }

		public abstract uint Weight { get; }

		public abstract uint MinimumLevel { get; }

		public abstract uint MaximumLevel { get; }

		public virtual bool IsEligibleForSelection()
		{
			int levelsCompleted = RunManager.instance.levelsCompleted;
			if (MaximumLevel != 0 && MinimumLevel > MaximumLevel)
			{
				RepoMutators.Logger.LogWarning((object)(MutatorName + " was configured with a minimum level larger than the maximum level!"));
				RepoMutators.Logger.LogWarning((object)"This configuration is consider invalid, the level bounds will be ignored.");
				return true;
			}
			if (MaximumLevel == 0)
			{
				return levelsCompleted >= MinimumLevel;
			}
			if (levelsCompleted >= MinimumLevel)
			{
				return levelsCompleted <= MaximumLevel;
			}
			return false;
		}
	}
	public class EnemyDisablingMutatorSettings : GenericMutatorSettings
	{
		private readonly ConfigEntry<string> _excludedEnemies;

		public IList<string> ExcludedEnemies { get; private set; } = new List<string>();


		public EnemyDisablingMutatorSettings(string name, string description, ConfigFile config, params string[] defaultDisabledEnemies)
			: base(name, description, config)
		{
			_excludedEnemies = config.Bind<string>(GenericMutatorSettings.GetSection(name), "Excluded enemies", string.Join(", ", defaultDisabledEnemies), "Enemies that cannot be spawned by the " + name + " Mutator. (Comma separated e.g. Apex Predator,Huntsman)");
			CacheEnemies();
		}

		internal void CacheEnemies()
		{
			ExcludedEnemies = (from value in _excludedEnemies.Value.Split(",")
				select value.Trim()).ToList();
		}
	}
	public class GenericMutatorSettings : AbstractMutatorSettings
	{
		private readonly ConfigEntry<uint> _weight;

		private readonly ConfigEntry<uint> _minimumLevel;

		private readonly ConfigEntry<uint> _maximumLevel;

		public override string MutatorName { get; }

		public override string MutatorDescription { get; }

		public override uint Weight => _weight.Value;

		public override uint MinimumLevel => _minimumLevel.Value;

		public override uint MaximumLevel => _maximumLevel.Value;

		public GenericMutatorSettings(string name, string description, ConfigFile config)
		{
			MutatorName = name;
			MutatorDescription = description;
			_weight = config.Bind<uint>(GetSection(name), "Weight", 100u, "Weighted chance for the " + name + " Mutator to be active.");
			_minimumLevel = config.Bind<uint>(GetSection(name), "Minimum level", 0u, "The minimum level on which the " + name + " Mutator can show up");
			_maximumLevel = config.Bind<uint>(GetSection(name), "Maximum level", 1000u, "The maximum level on which the " + name + " mutator can show up (0 = no upper bound)");
		}

		protected static string GetSection(string name)
		{
			return name + " Mutator";
		}
	}
	internal interface ILevelRemovingMutatorSettings
	{
		bool AllowCustomLevels { get; }
	}
	internal class ModSettings
	{
		private readonly ConfigEntry<float> _mutatorDisplayY;

		private readonly ConfigEntry<float> _mutatorDisplaySize;

		private readonly ConfigEntry<string> _mutatorDisplayToggleKey;

		private readonly ConfigEntry<float> _mutatorDescriptionDisplayY;

		private readonly ConfigEntry<float> _mutatorDescriptionDisplaySize;

		private readonly ConfigEntry<float> _mutatorDescriptionInitialDisplayTime;

		private readonly ConfigEntry<bool> _mutatorDescriptionPinned;

		private readonly ConfigEntry<bool> _mutatorDescriptionInMapTool;

		private readonly ConfigEntry<float> _targetDisplaySize;

		private readonly ConfigEntry<float> _specialActionY;

		private readonly ConfigEntry<string> _specialActionKey;

		public float MutatorDisplayY => _mutatorDisplayY.Value;

		public float MutatorDisplaySize => _mutatorDisplaySize.Value;

		public KeyCode MutatorDisplayToggleKey { get; private set; }

		public float MutatorDescriptionDisplayY => _mutatorDescriptionDisplayY.Value;

		public float MutatorDescriptionDisplaySize => _mutatorDescriptionDisplaySize.Value;

		public float MutatorDescriptionInitialDisplayTime => _mutatorDescriptionInitialDisplayTime.Value;

		public bool MutatorDescriptionPinned => _mutatorDescriptionPinned.Value;

		public bool MutatorDescriptionInMapTool => _mutatorDescriptionInMapTool.Value;

		public float TargetDisplaySize => _targetDisplaySize.Value;

		public float SpecialActionY => _specialActionY.Value;

		public KeyCode SpecialActionKey { get; private set; }

		internal ModSettings(ConfigFile config)
		{
			_mutatorDisplayY = config.Bind<float>("Mutator Interface", "Y position", -75f, "The Y position of the active Mutator overlay");
			_mutatorDisplaySize = config.Bind<float>("Mutator Interface", "Size", 30f, "The size of the active Mutator overlay");
			_mutatorDisplayToggleKey = config.Bind<string>("Mutator Interface", "Mutator display toggle key", "H", "The key use to toggle the active Mutator overlay");
			_mutatorDescriptionDisplayY = config.Bind<float>("Mutator Interface", "Description Y position", -110f, "The Y position of the active Mutator's description overlay");
			_mutatorDescriptionDisplaySize = config.Bind<float>("Mutator Interface", "Description size", 20f, "The size of the active Mutator's description overlay");
			_mutatorDescriptionInitialDisplayTime = config.Bind<float>("Mutator Interface", "Description initial display time", 8f, "The time for which the mutator's description is on screen when starting the level");
			_mutatorDescriptionPinned = config.Bind<bool>("Mutator Interface", "Description always active", false, "If true, \"Description initial display time\" will be ignored and the description will always stay on screen");
			_mutatorDescriptionInMapTool = config.Bind<bool>("Mutator Interface", "Description active in map tool", true, "If true, the mutator's description will be displayed when opening the map tool");
			_targetDisplaySize = config.Bind<float>("Mutator Interface", "Target Size", 40f, "The size of the target (e.g. president health) overlay");
			_specialActionY = config.Bind<float>("Special Action", "Special Action Y position", -50f, "The Y position of the Special Action overlay");
			_specialActionKey = config.Bind<string>("Special Action", "Special Action Key", "R", "Keybind that activates the Special Action");
			CacheKeys();
		}

		internal void CacheKeys()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got I4
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got I4
			//IL_0028->IL0028: Incompatible stack types: O vs I4
			//IL_0022->IL0028: Incompatible stack types: I4 vs O
			//IL_0022->IL0028: Incompatible stack types: O vs I4
			//IL_0055->IL0055: Incompatible stack types: O vs I4
			//IL_004f->IL0055: Incompatible stack types: I4 vs O
			//IL_004f->IL0055: Incompatible stack types: O vs I4
			object obj = this;
			int num;
			if (Enum.TryParse(typeof(KeyCode), _mutatorDisplayToggleKey.Value, out object result))
			{
				obj = (object)(KeyCode)result;
				num = (int)obj;
			}
			else
			{
				num = 0;
				obj = num;
				num = (int)obj;
			}
			((ModSettings)num).MutatorDisplayToggleKey = (KeyCode)obj;
			object obj2 = this;
			int num2;
			if (Enum.TryParse(typeof(KeyCode), _specialActionKey.Value, out object result2))
			{
				obj2 = (object)(KeyCode)result2;
				num2 = (int)obj2;
			}
			else
			{
				num2 = 0;
				obj2 = num2;
				num2 = (int)obj2;
			}
			((ModSettings)num2).SpecialActionKey = (KeyCode)obj2;
		}
	}
	public static class MutatorSettings
	{
		public static NopMutatorSettings NopMutator { get; private set; }

		public static ApolloElevenMutatorSettings ApolloEleven { get; private set; }

		public static GenericMutatorSettings OutWithABang { get; private set; }

		public static DuckThisMutatorSettings DuckThis { get; private set; }

		public static UltraViolenceMutatorSettings UltraViolence { get; private set; }

		public static ProtectThePresidentMutatorSettings ProtectThePresident { get; private set; }

		public static OneShotOneKillMutatorSettings OneShotOneKill { get; private set; }

		public static GenericMutatorSettings RustyServos { get; private set; }

		public static HandleWithCareMutatorSettings HandleWithCare { get; private set; }

		public static GenericMutatorSettings HuntingSeason { get; private set; }

		public static ThereCanOnlyBeOneMutatorSettings ThereCanOnlyBeOne { get; private set; }

		public static GenericMutatorSettings VolatileCargo { get; private set; }

		public static SealedAwayMutatorSettings SealedAway { get; private set; }

		public static GenericMutatorSettings ProtectTheWeak { get; private set; }

		public static FiringMyLaserMutatorSettings FiringMyLaser { get; private set; }

		public static VoiceoverMutatorSettings Voiceover { get; private set; }

		public static TheFloorIsLavaMutatorSettings TheFloorIsLava { get; private set; }

		public static void Initialize(ConfigFile config)
		{
			NopMutator = new NopMutatorSettings(config);
			ApolloEleven = new ApolloElevenMutatorSettings("Apollo 11", "Level-wide Zero-Gravity", config);
			OutWithABang = new GenericMutatorSettings("Out With a Bang!", "Monsters explode on death", config);
			DuckThis = new DuckThisMutatorSettings("Duck This", "Ducks aggro on sight instead of on interaction\nAlways spawn at least 1 duck", config);
			UltraViolence = new UltraViolenceMutatorSettings("Ultra-Violence", "Immediately activates the final extraction phase", config);
			ProtectThePresident = new ProtectThePresidentMutatorSettings("Protect the President", "A random player becomes the \"President\"\nIf they die, everyone else self-destructs", config);
			OneShotOneKill = new OneShotOneKillMutatorSettings("One Shot, One Kill", "Any damage taken by a player is lethal", config);
			RustyServos = new GenericMutatorSettings("Rusty Servos", "Players cannot jump\n+3 Grab Range", config);
			HandleWithCare = new HandleWithCareMutatorSettings("Handle With Care", "Valuables are worth more but break on any impact", config);
			HuntingSeason = new GenericMutatorSettings("Hunting Season", "No valuables spawn, weapons spawn instead\nEnemy respawn time reduced to 10 seconds\nOrb drop cap is removed", config);
			ThereCanOnlyBeOne = new ThereCanOnlyBeOneMutatorSettings("There Can Only Be One", "All monster spawns are of the same type", config);
			VolatileCargo = new GenericMutatorSettings("Volatile Cargo", "Valuables explode on destruction\nExplosion radius and strength based on value", config);
			SealedAway = new SealedAwayMutatorSettings("Sealed Away", "Breaking valuables has a chance to spawn monsters", config);
			ProtectTheWeak = new ProtectTheWeakMutatorSettings("Protect the Weak", "Protect your weaker friends!", config);
			FiringMyLaser = new FiringMyLaserMutatorSettings("Firing My Laser", "Fire your laser by pressing {specialActionKey}\nUncontrollably fire your laser when taking damage", config);
			Voiceover = new VoiceoverMutatorSettings("Voiceover", "Player voices are shuffled", config);
			TheFloorIsLava = new TheFloorIsLavaMutatorSettings("The Floor Is Lava", "You take damage while standing on the floor", config);
		}
	}
}
namespace Mutators.Settings.Specific
{
	public class ApolloElevenMutatorSettings : GenericMutatorSettings
	{
		private readonly ConfigEntry<bool> _applyToEnemies;

		private readonly ConfigEntry<bool> _applyInCart;

		private readonly ConfigEntry<string> _downwardsKey;

		public bool ApplyToEnemies => _applyToEnemies.Value;

		public bool ApplyInCart => _applyInCart.Value;

		public KeyCode DownwardsKey { get; private set; }

		internal ApolloElevenMutatorSettings(string name, string description, ConfigFile config)
			: base(name, description, config)
		{
			_applyToEnemies = config.Bind<bool>(GenericMutatorSettings.GetSection(name), "Apply to monsters", false, "If true, Zero-Gravity will also be applied to monsters while the " + name + " Mutator is active.");
			_applyInCart = config.Bind<bool>(GenericMutatorSettings.GetSection(name), "Apply in cart/extraction", true, "If true, Zero-Gravity will also apply to valuables in the cart and extraction points.");
			_downwardsKey = config.Bind<string>(GenericMutatorSettings.GetSection(name), "Downwards momentum keybind", "LeftControl", "(Client sided) If bound, this key can be used to control yourself downwards while the " + name + " Mutator is active");
			CacheKey();
		}

		internal void CacheKey()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (Enum.TryParse(typeof(KeyCode), _downwardsKey.Value, out object result))
			{
				DownwardsKey = (KeyCode)result;
			}
			else
			{
				DownwardsKey = (KeyCode)0;
			}
		}
	}
	public class DuckThisMutatorSettings : GenericMutatorSettings
	{
		private readonly ConfigEntry<float> _duckAggroCooldown;

		public float AggroCooldown => _duckAggroCooldown.Value;

		internal DuckThisMutatorSettings(string name, string description, ConfigFile config)
			: base(name, description, config)
		{
			_duckAggroCooldown = config.Bind<float>(GenericMutatorSettings.GetSection(name), "Duck aggro cooldown", 50f, "The cooldown between duck aggro while the Duck This Mutator is active.");
		}
	}
	public class FiringMyLaserMutatorSettings : GenericMutatorSettings
	{
		private readonly ConfigEntry<int> _laserActionCooldown;

		private readonly ConfigEntry<int> _laserActionEnemyDamage;

		private readonly ConfigEntry<bool> _laserActionEnabled;

		public int LaserActionCooldown => _laserActionCooldown.Value;

		public int LaserActionEnemyDamage => _laserActionEnemyDamage.Value;

		public bool LaserActionEnabled => _laserActionEnabled.Value;

		internal FiringMyLaserMutatorSettings(string name, string description, ConfigFile config)
			: base(name, description, config)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			_laserActionEnabled = config.Bind<bool>(GenericMutatorSettings.GetSection(name), "Allow manual laser action", true, "If true, players can manually use their laser action while the cooldown is over. Otherwise, only use the laser when getting hit");
			_laserActionCooldown = config.Bind<int>(GenericMutatorSettings.GetSection(name), "Laser action cooldown", 60, new ConfigDescription("The amount of seconds before the laser special action can be used again.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 10000), Array.Empty<object>()));
			_laserActionEnemyDamage = config.Bind<int>(GenericMutatorSettings.GetSection(name), "Laser action enemy damage", 30, new ConfigDescription("The amount of damage the laser special action deals to enemies per tick.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 200), Array.Empty<object>()));
		}
	}
	public class HandleWithCareMutatorSettings : GenericMutatorSettings
	{
		private readonly ConfigEntry<float> _valueMultiplier;

		private readonly ConfigEntry<bool> _instaDestroySurplus;

		private readonly ConfigEntry<bool> _multiplySurplus;

		public float ValueMultiplier => _valueMultiplier.Value;

		public bool InstantlyDestroySurplus => _instaDestroySurplus.Value;

		public bool MultiplySurplusValue => _multiplySurplus.Value;

		internal HandleWithCareMutatorSettings(string name, string description, ConfigFile config)
			: base(name, description, config)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			_valueMultiplier = config.Bind<float>(GenericMutatorSettings.GetSection(name), "Value Multiplier", 2f, new ConfigDescription("The amount by which the value of valuables should be multiplier when " + name + " is active.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			_instaDestroySurplus = config.Bind<bool>(GenericMutatorSettings.GetSection(name), "Instantly Destroy Surplus on Damage", false, "If true, while the " + name + " Mutator is active, the surplus will instantly be destroyed when taking any damage, just like other valuables.");
			_multiplySurplus = config.Bind<bool>(GenericMutatorSettings.GetSection(name), "Multiply Surplus Value", false, "If true, while the " + name + " Mutator is active, the surplus value will be multiplied, just like other valuables.");
		}
	}
	public class NopMutatorSettings : AbstractMutatorSettings
	{
		private readonly ConfigEntry<uint> _weight;

		private readonly ConfigEntry<uint> _minimumLevel;

		private readonly ConfigEntry<uint> _maximumLevel;

		public override string MutatorName => "None";

		public override string MutatorDescription => "A normal run, no special effects";

		public override uint Weight => _weight.Value;

		public override uint MinimumLevel => _minimumLevel.Value;

		public override uint MaximumLevel => _maximumLevel.Value;

		internal NopMutatorSettings(ConfigFile config)
		{
			_weight = config.Bind<uint>("No Mutator", "Weight", (uint)((ulong)(global::Mutators.Mutators.Mutators.All().Length - 1) * 100uL), "Weighted chance for no mutator to be active.");
			_minimumLevel = config.Bind<uint>("No Mutator", "Minimum level", 0u, "The minimum level on which no mutator can show up");
			_maximumLevel = config.Bind<uint>("No Mutator", "Maximum level", 1000u, "The maximum level on which no mutator can show up (0 = no upper bound)");
		}
	}
	public class OneShotOneKillMutatorSettings : EnemyDisablingMutatorSettings
	{
		private readonly ConfigEntry<bool> _instaReviveInTruckOrExtraction;

		private readonly ConfigEntry<uint> _instaReviveHealth;

		public bool InstaReviveInTruckOrExtraction => _instaReviveInTruckOrExtraction.Value;

		public int InstaReviveHealth { get; private set; }

		internal OneShotOneKillMutatorSettings(string name, string description, ConfigFile config)
			: base(name, description, config, "Peeper")
		{
			_instaReviveInTruckOrExtraction = config.Bind<bool>(GenericMutatorSettings.GetSection(name), "Instant revive in truck or extraction", false, "If true, while the " + name + " Mutator is active, players are instantly revived with full head if their head is brought to the truck or an active extraction point.");
			_instaReviveHealth = config.Bind<uint>(GenericMutatorSettings.GetSection(name), "Instant revive health", 0u, "The amount of health the player should be revived with when Instant revive is enabled. (0 = Revive with max health)");
			Cache();
		}

		private void Cache()
		{
			InstaReviveHealth = (int)Math.Clamp(_instaReviveHealth.Value, 0u, 2147483647u);
		}
	}
	public class ProtectThePresidentMutatorSettings : GenericMutatorSettings
	{
		private readonly ConfigEntry<byte> _minimumPlayerCount;

		public byte MinimumPlayerCount => _minimumPlayerCount.Value;

		internal ProtectThePresidentMutatorSettings(string name, string description, ConfigFile config)
			: base(name, description, config)
		{
			_minimumPlayerCount = config.Bind<byte>(GenericMutatorSettings.GetSection(name), "Minimum player amount requirement", (byte)3, "The minimum amount of players required for the " + name + " Mutator to be available for selection.");
		}

		public override bool IsEligibleForSelection()
		{
			if (base.IsEligibleForSelection())
			{
				Room currentRoom = PhotonNetwork.CurrentRoom;
				if (currentRoom != null)
				{
					return currentRoom.PlayerCount >= MinimumPlayerCount;
				}
				return false;
			}
			return false;
		}
	}
	public class ProtectTheWeakMutatorSettings : GenericMutatorSettings
	{
		private readonly ConfigEntry<byte> _minimumPlayerCount;

		public byte MinimumPlayerCount => _minimumPlayerCount.Value;

		internal ProtectTheWeakMutatorSettings(string name, string description, ConfigFile config)
			: base(name, description, config)
		{
			_minimumPlayerCount = config.Bind<byte>(GenericMutatorSettings.GetSection(name), "Minimum player amount requirement", (byte)3, "The minimum amount of players required for the " + name + " Mutator to be available for selection.");
		}

		public override bool IsEligibleForSelection()
		{
			if (base.IsEligibleForSelection())
			{
				Room currentRoom = PhotonNetwork.CurrentRoom;
				if (currentRoom != null)
				{
					return currentRoom.PlayerCount >= MinimumPlayerCount;
				}
				return false;
			}
			return false;
		}
	}
	public class SealedAwayMutatorSettings : EnemyDisablingMutatorSettings
	{
		private readonly ConfigEntry<int> _maximumMonsterSpawns;

		private readonly ConfigEntry<float> _monsterSpawnChance;

		public int MaximumMonsterSpawns => _maximumMonsterSpawns.Value;

		public float MonsterSpawnChance => _monsterSpawnChance.Value;

		internal SealedAwayMutatorSettings(string name, string description, ConfigFile config)
			: base(name, description, config, "Voodoo", "Shadow Child")
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			_maximumMonsterSpawns = config.Bind<int>(GenericMutatorSettings.GetSection(name), "Maximum monster spawns", 5, new ConfigDescription("Maximum amount of extra monsters that can be spawned by the " + name + " Mutator per level.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
			_monsterSpawnChance = config.Bind<float>(GenericMutatorSettings.GetSection(name), "Monster spawn chance", 10f, new ConfigDescription("The chance that a monster is spawned when breaking a valuable when the " + name + " Mutator is active.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
		}
	}
	public class TheFloorIsLavaMutatorSettings : GenericMutatorSettings, ILevelRemovingMutatorSettings
	{
		private readonly ConfigEntry<bool> _usePercentageDamage;

		private readonly ConfigEntry<bool> _allowCustomLevels;

		private readonly ConfigEntry<bool> _disableEnemies;

		public int DamagePerTick { get; private set; }

		public int ImmunePlayerCount { get; private set; }

		public bool UsePercentageDamage => _usePercentageDamage.Value;

		public bool AllowCustomLevels => _allowCustomLevels.Value;

		public bool DisableEnemies => _disableEnemies.Value;

		internal TheFloorIsLavaMutatorSettings(string name, string description, ConfigFile config)
			: base(name, description, config)
		{
			ConfigEntry<int> val = config.Bind<int>(GenericMutatorSettings.GetSection(name), "Damage", 1, "The amount of damage that players receive per second when standing on floor tiles.");
			_usePercentageDamage = config.Bind<bool>(GenericMutatorSettings.GetSection(name), "Use percentage damage", false, "If true, players will receive percentage max health damage instead of a flat amount.");
			ConfigEntry<int> val2 = config.Bind<int>(GenericMutatorSettings.GetSection(name), "Immune player count", 0, "The amount of players that are immune to " + name + " damage.");
			_allowCustomLevels = config.Bind<bool>(GenericMutatorSettings.GetSection(name), "Allow custom levels", true, "If false, custom levels cannot be picked while the " + name + " Mutator is active.");
			_disableEnemies = config.Bind<bool>(GenericMutatorSettings.GetSection(name), "Disable enemies", false, "If true, no enemies will spawn while the " + name + " Mutator is active.");
			DamagePerTick = Math.Clamp(val.Value, 1, int.MaxValue);
			ImmunePlayerCount = Math.Clamp(val2.Value, 0, int.MaxValue);
		}
	}
	public class ThereCanOnlyBeOneMutatorSettings : EnemyDisablingMutatorSettings
	{
		private readonly ConfigEntry<uint> _groupSpawnsThreshold;

		public uint GroupSpawnsThreshold => _groupSpawnsThreshold.Value;

		internal ThereCanOnlyBeOneMutatorSettings(string name, string description, ConfigFile config)
			: base(name, description, config)
		{
			_groupSpawnsThreshold = config.Bind<uint>(GenericMutatorSettings.GetSection(name), "Group spawn minimum level", 8u, "The minimum level from which enemy groups (e.g. 3 mentalists or 10 gnomes) can be spawned by the " + name + " Mutator.");
		}
	}
	public class UltraViolenceMutatorSettings : EnemyDisablingMutatorSettings
	{
		private ConfigEntry<bool> _keepOnLight;

		private readonly ConfigEntry<byte> _minimumPlayerCount;

		public bool KeepOnLight => _keepOnLight.Value;

		public byte MinimumPlayerCount => _minimumPlayerCount.Value;

		internal UltraViolenceMutatorSettings(string name, string description, ConfigFile config)
			: base(name, description, config)
		{
			_keepOnLight = config.Bind<bool>(GenericMutatorSettings.GetSection(name), "Keep on lights", false, "Keep on the level lighting while the " + name + " Mutator is active.");
			_minimumPlayerCount = config.Bind<byte>(GenericMutatorSettings.GetSection(name), "Minimum player amount requirement", (byte)0, "The minimum amount of players required for the " + name + " Mutator to be available for selection.");
		}

		public override bool IsEligibleForSelection()
		{
			if (base.IsEligibleForSelection())
			{
				Room currentRoom = PhotonNetwork.CurrentRoom;
				if (currentRoom != null)
				{
					return currentRoom.PlayerCount >= MinimumPlayerCount;
				}
				return false;
			}
			return false;
		}
	}
	public class VoiceoverMutatorSettings : GenericMutatorSettings
	{
		private readonly ConfigEntry<byte> _minimumPlayerCount;

		public byte MinimumPlayerCount => _minimumPlayerCount.Value;

		internal VoiceoverMutatorSettings(string name, string description, ConfigFile config)
			: base(name, description, config)
		{
			_minimumPlayerCount = config.Bind<byte>(GenericMutatorSettings.GetSection(name), "Minimum player amount requirement", (byte)3, "The minimum amount of players required for the " + name + " Mutator to be available for selection.");
		}

		public override bool IsEligibleForSelection()
		{
			if (base.IsEligibleForSelection())
			{
				Room currentRoom = PhotonNetwork.CurrentRoom;
				if (currentRoom != null)
				{
					return currentRoom.PlayerCount >= MinimumPlayerCount;
				}
				return false;
			}
			return false;
		}
	}
}
namespace Mutators.Patches
{
	[HarmonyPatch(typeof(EnemyDirector))]
	internal class EnemyDirectorPatch
	{
		private static List<EnemySetup> _startingEnemyList = new List<EnemySetup>();

		private static bool _isListSet;

		[HarmonyPrefix]
		[HarmonyPriority(600)]
		[HarmonyPatch("GetEnemy")]
		private static void EnemyDirectorGetEnemyPrefix(ref List<EnemySetup> ___enemyList, int ___enemyListIndex)
		{
			if (!SemiFunc.IsMultiplayer() || !SemiFunc.IsNotMasterClient())
			{
				___enemyList.RemoveAll((EnemySetup x) => (Object)(object)x == (Object)null);
				if (!_isListSet)
				{
					_startingEnemyList = new List<EnemySetup>(___enemyList);
					_isListSet = true;
				}
				if (___enemyList.Count == 0)
				{
					EnemySetup val = ScriptableObject.CreateInstance<EnemySetup>();
					val.spawnObjects = new List<GameObject>();
					___enemyList.Add(val);
				}
				while (___enemyList.Count < ___enemyListIndex + 1)
				{
					int index = Random.Range(0, _startingEnemyList.Count);
					___enemyList.Add(___enemyList[index]);
				}
			}
		}
	}
	[HarmonyPatch(typeof(LoadingUI))]
	internal class LoadingUIPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(800)]
		[HarmonyPatch("StopLoading")]
		private static void LoadingUIStopLoadingPostfix()
		{
			if (SemiFunc.RunIsLevel())
			{
				GameObject hud = GameObject.Find("Game Hud");
				GameObject health = GameObject.Find("Health");
				CreateMutatorText(hud, health);
				CreateMutatorDescriptionText(hud, health);
				CreateTargetPlayerText(hud, health);
				IMutator currentMutator = MutatorManager.Instance.CurrentMutator;
				if (currentMutator != null && currentMutator.HasSpecialAction)
				{
					GameObject energy = GameObject.Find("Energy");
					CreateSpecialActionText(hud, health, energy);
				}
			}
		}

		private static void CreateMutatorText(GameObject hud, GameObject health)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Mutator");
			val.transform.SetParent(hud.transform, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			TextMeshProUGUI component = health.GetComponent<TextMeshProUGUI>();
			((TMP_Text)val2).font = ((TMP_Text)component).font;
			((TMP_Text)val2).fontMaterial = ((TMP_Text)component).fontMaterial;
			RectTransform component2 = val.GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(200f, 50f);
			component2.anchorMin = new Vector2(1f, 1f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.pivot = new Vector2(1f, 1f);
			component2.anchoredPosition = new Vector2(0f, RepoMutators.Settings.MutatorDisplayY);
			((TMP_Text)val2).alignment = (TextAlignmentOptions)516;
			val.AddComponent<MutatorAnnouncingBehaviour>();
			((TMP_Text)val2).text = MutatorManager.Instance.CurrentMutator.Name;
			((TMP_Text)val2).fontSize = RepoMutators.Settings.MutatorDisplaySize;
			((Behaviour)val2).enabled = true;
		}

		private static void CreateMutatorDescriptionText(GameObject hud, GameObject health)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Mutator Description");
			val.transform.SetParent(hud.transform, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			TextMeshProUGUI component = health.GetComponent<TextMeshProUGUI>();
			((TMP_Text)val2).font = ((TMP_Text)component).font;
			((TMP_Text)val2).fontMaterial = ((TMP_Text)component).fontMaterial;
			RectTransform component2 = val.GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(300f, 100f);
			component2.anchorMin = new Vector2(1f, 1f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.pivot = new Vector2(1f, 1f);
			component2.anchoredPosition = new Vector2(0f, RepoMutators.Settings.MutatorDescriptionDisplayY);
			((TMP_Text)val2).alignment = (TextAlignmentOptions)516;
			((TMP_Text)val2).verticalAlignment = (VerticalAlignmentOptions)256;
			val.AddComponent<MutatorDescriptionAnnouncingBehaviour>();
			((TMP_Text)val2).text = string.Empty;
			((TMP_Text)val2).lineSpacing = -50f;
			((TMP_Text)val2).fontSize = RepoMutators.Settings.MutatorDescriptionDisplaySize;
			((Behaviour)val2).enabled = true;
		}

		private static void CreateTargetPlayerText(GameObject hud, GameObject health)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ChosenPlayerTarget");
			val.transform.SetParent(hud.transform, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			TextMeshProUGUI component = health.GetComponent<TextMeshProUGUI>();
			((TMP_Text)val2).font = ((TMP_Text)component).font;
			((TMP_Text)val2).fontMaterial = ((TMP_Text)component).fontMaterial;
			((Graphic)val2).color = ((Graphic)component).color;
			RectTransform component2 = val.GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(300f, 50f);
			component2.anchorMin = new Vector2(0.5f, 1f);
			component2.anchorMax = new Vector2(0.5f, 1f);
			component2.pivot = new Vector2(0.5f, 1f);
			component2.anchoredPosition = new Vector2(0f, 10f);
			((TMP_Text)val2).alignment = (TextAlignmentOptions)4098;
			val.AddComponent<TargetPlayerAnnouncingBehaviour>();
			((TMP_Text)val2).text = string.Empty;
			((TMP_Text)val2).fontSize = RepoMutators.Settings.TargetDisplaySize;
			((Behaviour)val2).enabled = true;
		}

		private static void CreateSpecialActionText(GameObject hud, GameObject health, GameObject energy)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("SpecialAction");
			val.transform.SetParent(hud.transform, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			Zap(val, energy);
			GameObject val3 = new GameObject("SpecialActionMax");
			val3.transform.SetParent(val.transform, false);
			TextMeshProUGUI val4 = val3.AddComponent<TextMeshProUGUI>();
			TextMeshProUGUI component = health.GetComponent<TextMeshProUGUI>();
			((TMP_Text)val2).font = ((TMP_Text)component).font;
			((TMP_Text)val2).fontWeight = ((TMP_Text)component).fontWeight;
			((TMP_Text)val2).fontMaterial = ((TMP_Text)component).fontMaterial;
			((Graphic)val2).color = Color.red;
			RectTransform component2 = val.GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(120f, 50f);
			component2.anchorMin = new Vector2(0f, 1f);
			component2.anchorMax = new Vector2(0f, 1f);
			component2.pivot = new Vector2(0f, 1f);
			component2.anchoredPosition = new Vector2(29f, RepoMutators.Settings.SpecialActionY);
			((TMP_Text)val2).alignment = (TextAlignmentOptions)513;
			((TMP_Text)val2).text = string.Empty;
			((TMP_Text)val2).fontStyle = (FontStyles)1;
			((TMP_Text)val2).fontSize = 40f;
			((Behaviour)val2).enabled = true;
			((TMP_Text)val4).font = ((TMP_Text)component).font;
			((TMP_Text)val4).fontMaterial = ((TMP_Text)component).fontMaterial;
			((Graphic)val4).color = Color.red;
			RectTransform component3 = val3.GetComponent<RectTransform>();
			component3.sizeDelta = new Vector2(120f, 50f);
			component3.anchorMin = new Vector2(0f, 1f);
			component3.anchorMax = new Vector2(0f, 1f);
			component3.pivot = new Vector2(0f, 1f);
			component3.anchoredPosition = new Vector2(45f, 5f);
			((TMP_Text)val4).alignment = (TextAlignmentOptions)513;
			val.AddComponent<SpecialActionAnnouncingBehaviour>();
			((TMP_Text)val4).text = string.Empty;
			((TMP_Text)val4).fontSize = 20f;
			((Behaviour)val4).enabled = true;
		}

		private static void Zap(GameObject specialActionObject, GameObject energy)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("SpecialActionZap");
			val.transform.SetParent(specialActionObject.transform, false);
			Image component = ((Component)energy.transform.Find("Zap")).GetComponent<Image>();
			Image val2 = val.AddComponent<Image>();
			val2.sprite = component.sprite;
			((Graphic)val2).color = Color.red;
			RectTransform component2 = val.GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(25f, 25f);
			component2.anchoredPosition = new Vector2(-75f, 0f);
		}
	}
	[HarmonyPatch(typeof(MapToolController))]
	internal class MapToolControllerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void Postfix(MapToolController __instance)
		{
			MutatorDescriptionAnnouncingBehaviour instance = MutatorDescriptionAnnouncingBehaviour.Instance;
			if (Object.op_Implicit((Object)(object)instance) && __instance.Active && RepoMutators.Settings.MutatorDescriptionInMapTool && (Object)(object)__instance.PlayerAvatar == (Object)(object)PlayerAvatar.instance)
			{
				((SemiUI)instance).Show();
			}
		}
	}
	[HarmonyPatch(typeof(MenuPage))]
	internal class MenuPagePatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("LockAndHide")]
		private static void MenuPageLockAndHidePostfix()
		{
			MutatorAnnouncingBehaviour instance = MutatorAnnouncingBehaviour.instance;
			MutatorDescriptionAnnouncingBehaviour instance2 = MutatorDescriptionAnnouncingBehaviour.Instance;
			TargetPlayerAnnouncingBehaviour instance3 = TargetPlayerAnnouncingBehaviour.instance;
			SpecialActionAnnouncingBehaviour instance4 = SpecialActionAnnouncingBehaviour.instance;
			if (Object.op_Implicit((Object)(object)instance))
			{
				((SemiUI)instance).Hide();
			}
			if (Object.op_Implicit((Object)(object)instance2))
			{
				((SemiUI)instance2).Hide();
			}
			if (Object.op_Implicit((Object)(object)instance3))
			{
				((SemiUI)instance3).Hide();
			}
			if (Object.op_Implicit((Object)(object)instance4))
			{
				((SemiUI)instance4).Hide();
			}
		}
	}
	[HarmonyPatch(typeof(RunManager))]
	internal class RunManagerPatch
	{
		private static readonly ISet<string> vanillaLevelNames = new HashSet<string> { "Level - Artic", "Level - Manor", "Level - Wizard", "Level - Museum" };

		[HarmonyPostfix]
		[HarmonyPatch("ChangeLevel")]
		private static void RunManagerChangeLevelPostfix()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.IsMultiplayer() && SemiFunc.IsNotMasterClient())
			{
				return;
			}
			RepoMutators.Logger.LogDebug((object)"RunManagerPatch Host only");
			if (!SemiFunc.IsMultiplayer() && !SemiFunc.RunIsLobbyMenu() && (Object)(object)MutatorsNetworkManager.Instance == (Object)null)
			{
				RepoMutators.Logger.LogDebug((object)"Spawning singleplayer NetworkManager");
				string text = "Xepos.REPO-Mutators/MutatorsNetworkManager";
				GameObject val = NetworkPrefabs.SpawnNetworkPrefab(text, Vector3.zero, Quaternion.identity, (byte)0, (object[])null);
				if (val != null)
				{
					val.SetActive(true);
				}
				GetAndSendMutator();
			}
			ApplyPatch();
		}

		[HarmonyPostfix]
		[HarmonyPatch("UpdateLevel")]
		private static void RunManagerUpdateLevelPostfix()
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				RepoMutators.Logger.LogDebug((object)"RunManagerPatch Client only");
				ApplyPatch();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("SetRunLevel")]
		private static void RunManagerChangeLevelPrefix(RunManager __instance, ref Level ___previousRunLevel)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && MutatorManager.Instance.CurrentMutator.Settings is ILevelRemovingMutatorSettings levelRemovingMutatorSettings && !levelRemovingMutatorSettings.AllowCustomLevels)
			{
				RepoMutators.Logger.LogInfo((object)"Removing custom levels from selection");
				__instance.levels.RemoveAll((Level l) => !vanillaLevelNames.Contains(((Object)l).name));
				if (__instance.levels.Count == 1)
				{
					___previousRunLevel = null;
				}
				else if (__instance.levels.Count == 0)
				{
					___previousRunLevel = null;
					RepoMutators.Logger.LogError((object)"Attempted to start a run with 0 available levels, please revisit your mod settings!");
					RepoMutators.Logger.LogError((object)"There must be at least one level available to choose from!");
				}
			}
		}

		private static void ApplyPatch()
		{
			MutatorManager instance = MutatorManager.Instance;
			if (IsInShop() && SemiFunc.IsMasterClientOrSingleplayer())
			{
				MutatorsNetworkManager.Instance.ClearBufferedRPCs();
				GetAndSendMutator();
			}
			else if (SemiFunc.RunIsLevel())
			{
				RepoMutators.Logger.LogDebug((object)("Applying patch now for mutator: " + instance.CurrentMutator.Name));
				instance.CurrentMutator.Patch();
			}
			else if (SemiFunc.RunIsArena())
			{
				instance.SetActiveMutator("None");
			}
		}

		private static void GetAndSendMutator()
		{
			IMutator weightedMutator = MutatorManager.Instance.GetWeightedMutator();
			MutatorsNetworkManager.Instance.SendActiveMutator(weightedMutator.Name);
		}

		private static bool IsInShop()
		{
			RunManager instance = RunManager.instance;
			return ((Object)instance.levelCurrent).name == ((Object)instance.levelShop).name;
		}
	}
	[HarmonyPatch(typeof(SemiFunc))]
	internal class SemiFuncPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(800)]
		[HarmonyPatch("OnSceneSwitch")]
		private static void SemiFuncOnSceneSwitchPostfix(bool _gameOver, bool _leaveGame)
		{
			if (_leaveGame)
			{
				MutatorManager instance = MutatorManager.Instance;
				instance.SetActiveMutator("None");
			}
		}
	}
	[HarmonyPatch(typeof(SpectateCamera))]
	internal class SpectateCameraPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("LateUpdate")]
		private static void SpectateCameraLateUpdatePostfix()
		{
			SpecialActionAnnouncingBehaviour instance = SpecialActionAnnouncingBehaviour.instance;
			if (Object.op_Implicit((Object)(object)instance))
			{
				((SemiUI)instance).Hide();
			}
		}
	}
}
namespace Mutators.Network
{
	internal class MutatorsNetworkManager : MonoBehaviourPunCallbacks
	{
		private PhotonView _photonView;

		private readonly bool _debug;

		internal static MutatorsNetworkManager Instance { get; private set; }

		private void Awake()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			((Component)this).transform.parent = ((Component)StatsManager.instance).transform;
			((Object)((Component)this).gameObject).name = "MutatorsNetworkManager";
			GameObject gameObject = ((Component)this).gameObject;
			((Object)gameObject).hideFlags = (HideFlags)(((Object)gameObject).hideFlags & -62);
			_photonView = ((Component)this).GetComponent<PhotonView>();
			if (_debug)
			{
				Run(PrintViewId());
			}
		}

		private IEnumerator PrintViewId()
		{
			while (true)
			{
				yield return (object)new WaitForSeconds(3f);
				RepoMutators.Logger.LogInfo((object)$"ViewID - {_photonView.ViewID}");
			}
		}

		internal void ClearBufferedRPCs()
		{
			if (_photonView.IsMine)
			{
				PhotonNetwork.RemoveBufferedRPCs(_photonView.ViewID, (string)null, (int[])null);
			}
		}

		public void SendMetadata(IDictionary<string, object> metadata)
		{
			Send<Hashtable>(metadata.ToPhotonHashtable(), SetMetadata, (RpcTarget)4);
		}

		public void SendActiveMutator(string name, IDictionary<string, object>? metadata = null)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				Hashtable value = metadata?.ToPhotonHashtable();
				Send<string, Hashtable>(name, value, SetActiveMutator, (RpcTarget)4);
			}
		}

		public void SendComponentForViews(int[] views, Type componentType)
		{
			Send(views, componentType.FullName, AddComponentToViewGameObject, (RpcTarget)4);
		}

		internal void SendScaleChange(int photonViewId, float scale)
		{
			Send(photonViewId, scale, SetScale, (RpcTarget)4);
		}

		public void SendMetaToHost(string sender, IDictionary<string, object> meta)
		{
			Hashtable val = meta.ToPhotonHashtable();
			if (SemiFunc.IsMultiplayer() && !SemiFunc.IsMasterClient())
			{
				_photonView.RPC("SetClientMetadata", (RpcTarget)2, new object[2] { sender, val });
			}
		}

		[PunRPC]
		public void AddComponentToViewGameObject(int[] views, string componentType)
		{
			Type type = Type.GetType(componentType);
			if (type == null)
			{
				RepoMutators.Logger.LogError((object)("Failed to resolve type: " + componentType));
				return;
			}
			foreach (int num in views)
			{
				PhotonView val = PhotonView.Find(num);
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)((Component)val).gameObject))
				{
					((Component)val).gameObject.AddComponent(type);
				}
			}
		}

		[PunRPC]
		public void SetActiveMutator(string name, Hashtable? hashtable)
		{
			bool flag = SemiFunc.RunIsLevel();
			RepoMutators.Logger.LogDebug((object)("Set mutator to " + name + ", applying patch " + (flag ? "now" : "later")));
			MutatorManager.Instance.SetActiveMutator(name, flag);
			IDictionary<string, object> dictionary;
			if (hashtable != null)
			{
				dictionary = hashtable.FromPhotonHashtable();
			}
			else
			{
				IDictionary<string, object> dictionary2 = new Dictionary<string, object>();
				dictionary = dictionary2;
			}
			IDictionary<string, object> dictionary3 = dictionary;
			MutatorManager instance = MutatorManager.Instance;
			instance.metadata = dictionary3;
			if (SemiFunc.IsMultiplayer() || dictionary3.Count != 0)
			{
				instance.OnMetadataChanged?.Invoke(dictionary3);
			}
		}

		[PunRPC]
		public void SetMetadata(Hashtable hashtable)
		{
			MutatorManager instance = MutatorManager.Instance;
			IDictionary<string, object> dictionary = hashtable.FromPhotonHashtable();
			RepoMutators.Logger.LogDebug((object)("[RPC] Received metadata: " + string.Join(", ", dictionary.Select((KeyValuePair<string, object> kvp) => $"{kvp.Key}: {kvp.Value}"))));
			dictionary = (instance.metadata = instance.metadata.DeepMergedWith(dictionary));
			instance.OnMetadataChanged?.Invoke(dictionary);
		}

		[PunRPC]
		public void SetClientMetadata(string steamId, Hashtable hashtable)
		{
			MutatorManager instance = MutatorManager.Instance;
			IDictionary<string, object> value = hashtable.FromPhotonHashtable();
			IDictionary<string, object> value2 = new Dictionary<string, object> { { steamId, value } };
			IDictionary<string, object> dict = new Dictionary<string, object> { { "clients", value2 } };
			IDictionary<string, object> obj = (instance.metadata = instance.metadata.DeepMergedWith(dict));
			instance.OnMetadataChanged?.Invoke(obj);
		}

		[PunRPC]
		public void SetScale(int viewId, float scale)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			PhotonView val = PhotonView.Find(viewId);
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).transform.localScale = new Vector3(scale, scale, scale);
			}
		}

		[PunRPC]
		public void SendModVersion()
		{
			((MonoBehaviour)this).StartCoroutine(ComparedModVersionCoroutine());
		}

		[PunRPC]
		public void CompareModVersion(string version, PhotonMessageInfo info)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (version == "0.5.8")
			{
				RepoMutators.Logger.LogInfo((object)(info.Sender.NickName + " is on the same version!"));
			}
			else
			{
				HandleVersionMismatch(version, info.Sender.NickName);
			}
		}

		public override void OnPlayerEnteredRoom(Player newPlayer)
		{
			if (_photonView.IsMine)
			{
				_photonView.RPC("SendModVersion", newPlayer, Array.Empty<object>());
			}
		}

		private void HandleVersionMismatch(string version, string playerName)
		{
			string[] array = version.Split('.');
			string[] array2 = "0.5.8".Split('.');
			if (array[0] != array2[0] || array[1] != array2[1])
			{
				RepoMutators.Logger.LogError((object)(playerName + " is on version " + version + ", which doesn't match the host version!"));
			}
			else if (array[2] != array2[2])
			{
				RepoMutators.Logger.LogWarning((object)(playerName + " is on version " + version + ", which doesn't match the host version!"));
			}
		}

		private bool ValidateClientMeta(IDictionary<string, object> clientMeta, IDictionary<string, IAllowedClientMeta> allowedMeta)
		{
			foreach (KeyValuePair<string, object> clientMetum in clientMeta)
			{
				if (!allowedMeta.TryGetValue(clientMetum.Key, out IAllowedClientMeta value))
				{
					return false;
				}
				if (value.HasNested())
				{
					if (!(clientMetum.Value is IDictionary<string, object> clientMeta2))
					{
						return false;
					}
					if (!ValidateClientMeta(clientMeta2, value.NestedMeta))
					{
						return false;
					}
				}
			}
			return true;
		}

		private void Send<T>(T data, Action<T> rpcMethod, RpcTarget rpcTarget)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.IsMultiplayer())
			{
				if (SemiFunc.IsMasterClient())
				{
					_photonView.RPC(rpcMethod.Method.Name, rpcTarget, new object[1] { data });
					rpcMethod(data);
				}
			}
			else
			{
				rpcMethod(data);
			}
		}

		private void Send<T, D>(T data, D value, Action<T, D> rpcMethod, RpcTarget rpcTarget)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.IsMultiplayer())
			{
				if (SemiFunc.IsMasterClient())
				{
					_photonView.RPC(rpcMethod.Method.Name, rpcTarget, new object[2] { data, value });
					rpcMethod(data, value);
				}
			}
			else
			{
				rpcMethod(data, value);
			}
		}

		private IEnumerator ComparedModVersionCoroutine()
		{
			while ((Object)(object)_photonView == (Object)null)
			{
				yield return (object)new WaitForSeconds(0.5f);
			}
			_photonView.RPC("CompareModVersion", (RpcTarget)2, new object[1] { "0.5.8" });
		}

		internal void Run(IEnumerator coroutine)
		{
			((MonoBehaviour)this).StartCoroutine(coroutine);
		}
	}
}
namespace Mutators.Network.Meta
{
	public class AllowedClientMeta : IAllowedClientMeta
	{
		public bool PurgeAfterAccepting { get; private set; }

		public IDictionary<string, IAllowedClientMeta> NestedMeta { get; private set; }

		public AllowedClientMeta(IDictionary<string, IAllowedClientMeta> meta, bool purgeAfterAccepting = false)
		{
			PurgeAfterAccepting = purgeAfterAccepting;
			NestedMeta = meta;
		}

		public AllowedClientMeta(bool purgeAfterAccepting = false)
		{
			PurgeAfterAccepting = purgeAfterAccepting;
			NestedMeta = new Dictionary<string, IAllowedClientMeta>();
		}
	}
	public interface IAllowedClientMeta
	{
		bool PurgeAfterAccepting { get; }

		IDictionary<string, IAllowedClientMeta> NestedMeta { get; }

		bool HasNested()
		{
			if (NestedMeta != null)
			{
				return NestedMeta.Count > 0;
			}
			return false;
		}
	}
}
namespace Mutators.Mutators
{
	public interface IMutator
	{
		string Name { get; }

		string Description { get; }

		bool Active { get; }

		bool HasSpecialAction { get; }

		AbstractMutatorSettings Settings { get; }

		IReadOnlyList<Type> Patches { get; }

		IReadOnlyList<Func<bool>> Conditions { get; }

		void Patch();

		void Unpatch();
	}
	public class Mutator : IMutator
	{
		private readonly Harmony _harmony;

		private readonly IList<Type> _patches;

		private readonly IList<Func<bool>> _conditions;

		private readonly IList<Action> _beforePatchAllHooks = new List<Action>();

		private readonly IList<Action> _afterPatchAllHooks = new List<Action>();

		private readonly IList<Action> _beforeUnpatchAllHooks = new List<Action>();

		private readonly IList<Action> _afterUnpatchAllHooks = new List<Action>();

		public string Name => Settings.MutatorName;

		public string Description => Settings.MutatorDescription;

		public bool Active { get; private set; }

		public bool HasSpecialAction { get; private set; }

		public AbstractMutatorSettings Settings { get; private set; }

		public IReadOnlyList<Func<bool>> Conditions => new ReadOnlyCollection<Func<bool>>(_conditions);

		public IReadOnlyList<Type> Patches => new ReadOnlyCollection<Type>(_patches);

		public Mutator(AbstractMutatorSettings settings, IList<Type> patches, IList<Func<bool>> conditions = null, bool specialActionOverlay = false)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			Settings = settings;
			_harmony = new Harmony("Xepos.REPO-Mutators-" + settings.MutatorName);
			_patches = patches ?? new List<Type>();
			_conditions = conditions ?? new List<Func<bool>>();
			HasSpecialAction = specialActionOverlay;
			foreach (Type patch in _patches)
			{
				TryAddHook(patch, "BeforePatchAll", _beforePatchAllHooks);
				TryAddHook(patch, "AfterPatchAll", _afterPatchAllHooks);
				TryAddHook(patch, "BeforeUnpatchAll", _beforeUnpatchAllHooks);
				TryAddHook(patch, "AfterUnpatchAll", _afterUnpatchAllHooks);
			}
		}

		public Mutator(AbstractMutatorSettings settings, Type patch, IList<Func<bool>> conditions = null, bool specialActionOverlay = false)
			: this(settings, new List<Type>(1) { patch }, conditions, specialActionOverlay)
		{
		}

		public void Patch()
		{
			RepoMutators.Logger.LogDebug((object)$"{Name} active: {Active}");
			if (Active)
			{
				return;
			}
			RepoMutators.Logger.LogDebug((object)$"About to apply {_patches.Count} patches for {Name}");
			Active = true;
			LinqExtensions.ForEach<Action>((IEnumerable<Action>)_beforePatchAllHooks, (Action<Action>)delegate(Action action)
			{
				action?.Invoke();
			});
			foreach (Type patch in _patches)
			{
				_harmony.PatchAll(patch);
				RepoMutators.Logger.LogDebug((object)("Applied patch: " + patch.Name));
			}
			LinqExtensions.ForEach<Action>((IEnumerable<Action>)_afterPatchAllHooks, (Action<Action>)delegate(Action action)
			{
				action?.Invoke();
			});
		}

		public void Unpatch()
		{
			if (Active)
			{
				LinqExtensions.ForEach<Action>((IEnumerable<Action>)_beforeUnpatchAllHooks, (Action<Action>)delegate(Action action)
				{
					action?.Invoke();
				});
				_harmony.UnpatchSelf();
				Active = false;
				LinqExtensions.ForEach<Action>((IEnumerable<Action>)_afterUnpatchAllHooks, (Action<Action>)delegate(Action action)
				{
					action?.Invoke();
				});
				RepoMutators.Logger.LogDebug((object)("Unpatched mutator: " + Name));
			}
		}

		private static void TryAddHook(Type type, string methodName, IList<Action> hookList)
		{
			MethodInfo method = type.GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (method == null)
			{
				return;
			}
			if (method.GetParameters().Length != 0)
			{
				RepoMutators.Logger.LogWarning((object)("Lifecycle hook '" + methodName + "' in type '" + type.FullName + "' must not have parameters."));
				return;
			}
			if (method.ReturnType != typeof(void))
			{
				RepoMutators.Logger.LogWarning((object)("Lifecycle hook '" + methodName + "' in type '" + type.FullName + "' must return void."));
				return;
			}
			try
			{
				Action item = (Action)Delegate.CreateDelegate(typeof(Action), method);
				hookList.Add(item);
				RepoMutators.Logger.LogDebug((object)("Lifecycle hook '" + methodName + "' in type '" + type.FullName + "' was succesfully registered"));
			}
			catch (Exception ex)
			{
				RepoMutators.Logger.LogError((object)("Failed to bind lifecycle hook '" + methodName + "' in type '" + type.FullName + "': " + ex.Message));
			}
		}
	}
	public static class Mutators
	{
		public const string NopMutatorName = "None";

		public const string OutWithABangName = "Out With a Bang!";

		public const string ApolloElevenName = "Apollo 11";

		public const string UltraViolenceName = "Ultra-Violence";

		public const string DuckThisName = "Duck This";

		public const string ProtectThePresidentName = "Protect the President";

		public const string OneShotOneKillName = "One Shot, One Kill";

		public const string RustyServosName = "Rusty Servos";

		public const string HandleWithCareName = "Handle With Care";

		public const string HuntingSeasonName = "Hunting Season";

		public const string ThereCanOnlyBeOneName = "There Can Only Be One";

		public const string VolatileCargoName = "Volatile Cargo";

		public const string SealedAwayName = "Sealed Away";

		public const string ProtectTheWeakName = "Protect the Weak";

		public const string FiringMyLaserName = "Firing My Laser";

		public const string VoiceoverName = "Voiceover";

		public const string TheFloorIsLavaName = "The Floor Is Lava";

		public const string NopMutatorDescription = "A normal run, no special effects";

		public const string OutWithABangDescription = "Monsters explode on death";

		public const string ApolloElevenDescription = "Level-wide Zero-Gravity";

		public const string UltraViolenceDescription = "Immediately activates the final extraction phase";

		public const string DuckThisDescription = "Ducks aggro on sight instead of on interaction\nAlways spawn at least 1 duck";

		public const string ProtectThePresidentDescription = "A random player becomes the \"President\"\nIf they die, everyone else self-destructs";

		public const string OneShotOneKillDescription = "Any damage taken by a player is lethal";

		public const string RustyServosDescription = "Players cannot jump\n+3 Grab Range";

		public const string HandleWithCareDescription = "Valuables are worth more but break on any impact";

		public const string HuntingSeasonDescription = "No valuables spawn, weapons spawn instead\nEnemy respawn time reduced to 10 seconds\nOrb drop cap is removed";

		public const string ThereCanOnlyBeOneDescription = "All monster spawns are of the same type";

		public const string VolatileCargoDescription = "Valuables explode on destruction\nExplosion radius and strength based on value";

		public const string SealedAwayDescription = "Breaking valuables has a chance to spawn monsters";

		public const string ProtectTheWeakDescription = "Protect your weaker friends!";

		public const string FiringMyLaserDescription = "Fire your laser by pressing {specialActionKey}\nUncontrollably fire your laser when taking damage";

		public const string VoiceoverDescription = "Player voices are shuffled";

		public const string TheFloorIsLavaDescription = "You take damage while standing on the floor";

		internal static string[] All()
		{
			return new string[16]
			{
				"None", "Out With a Bang!", "Apollo 11", "Ultra-Violence", "Duck This", "Protect the President", "Rusty Servos", "Handle With Care", "Hunting Season", "There Can Only Be One",
				"Volatile Cargo", "Sealed Away", "Protect the Weak", "Firing My Laser", "Voiceover", "The Floor Is Lava"
			};
		}
	}
	public class NopMutator : IMutator
	{
		private static readonly IReadOnlyList<Type> _patches = Array.Empty<Type>();

		private static readonly IReadOnlyList<Func<bool>> _conditions = Array.Empty<Func<bool>>();

		public string Name => "None";

		public string Description => "A normal run, no special effects";

		public bool Active { get; private set; }

		public AbstractMutatorSettings Settings { get; private set; }

		public IReadOnlyList<Type> Patches => _patches;

		public IReadOnlyList<Func<bool>> Conditions => _conditions;

		public bool HasSpecialAction => false;

		internal NopMutator(AbstractMutatorSettings settings)
		{
			Settings = settings;
		}

		public void Patch()
		{
			Active = true;
		}

		public void Unpatch()
		{
			Active = false;
		}
	}
}
namespace Mutators.Mutators.Patches
{
	internal class ApolloElevenPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LevelGenerator))]
		[HarmonyPatch("GenerateDone")]
		private static void LevelGeneratorGenerateDonePostfix()
		{
			if (SemiFunc.RunIsLevel())
			{
				PlayerController.instance.AntiGravity(float.MaxValue);
				if (SemiFunc.IsMasterClientOrSingleplayer())
				{
					MakeAllPhysGrabObjectsZeroGravity();
				}
			}
			else
			{
				PlayerController.instance.AntiGravity(0f);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PhysGrabObjectImpactDetector))]
		[HarmonyPatch("Update")]
		private static void PhysGrabObjectImpactDetectorUpdatePostfix(PhysGrabObjectImpactDetector __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && !MutatorSettings.ApolloEleven.ApplyInCart && !__instance.isNotValuable)
			{
				if (__instance.inCart && !__instance.inCartPrevious)
				{
					__instance.physGrabObject.OverrideDrag(0.5f, 0.1f);
					__instance.physGrabObject.OverrideAngularDrag(0.5f, 0.1f);
					__instance.physGrabObject.OverrideZeroGravity(0.1f);
				}
				else if (!__instance.inCart && __instance.inCartPrevious)
				{
					MakeObjectZeroGravity(__instance.physGrabObject);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerController))]
		[HarmonyPatch("AntiGravity")]
		private static bool PlayControllerAntiGravityPrefix(float _timer)
		{
			return _timer == float.MaxValue;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PhysGrabObject))]
		[HarmonyPatch("OverrideDrag")]
		private static bool PhysGrabObjectOverrideDragPrefix(PhysGrabObject __instance, float value, float time)
		{
			if (__instance.impactDetector.inCart && !MutatorSettings.ApolloEleven.ApplyInCart)
			{
				return true;
			}
			return time == float.MaxValue;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PhysGrabObject))]
		[HarmonyPatch("OverrideAngularDrag")]
		private static bool PhysGrabObjectOverrideAngularDragPrefix(PhysGrabObject __instance, float value, float time)
		{
			if (__instance.impactDetector.inCart && !MutatorSettings.ApolloEleven.ApplyInCart)
			{
				return true;
			}
			return time == float.MaxValue;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PhysGrabObject))]
		[HarmonyPatch("OverrideZeroGravity")]
		private static bool PhysGrabObjectOverrideZeroGravityPrefix(PhysGrabObject __instance, float time)
		{
			if (__instance.impactDetector.inCart && !MutatorSettings.ApolloEleven.ApplyInCart)
			{
				return true;
			}
			return time == float.MaxValue;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerController))]
		[HarmonyPatch("FixedUpdate")]
		private static void PlayerControllerFixedUpdatePrefix(PlayerController __instance)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (!ChatManager.instance.StateIsActive() && Input.GetKey(MutatorSettings.ApolloEleven.DownwardsKey))
			{
				__instance.rb.AddForce(Vector3.down * 50f, (ForceMode)0);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(RoundDirector))]
		[HarmonyPatch("PhysGrabObjectAdd")]
		private static void RoundDirectorPhysGrabObjectAddPostfix(PhysGrabObject _physGrabObject)
		{
			MakeObjectZeroGravity(_physGrabObject);
		}

		private static void MakeAllPhysGrabObjectsZeroGravity()
		{
			foreach (PhysGrabObject physGrabObject in RoundDirector.instance.physGrabObjects)
			{
				MakeObjectZeroGravity(physGrabObject);
			}
		}

		private static void MakeObjectZeroGravity(PhysGrabObject physGrabObject)
		{
			if (MutatorSettings.ApolloEleven.ApplyToEnemies || !Object.op_Implicit((Object)(object)((Component)physGrabObject).GetComponent<EnemyRigidbody>()))
			{
				physGrabObject.OverrideDrag(0.5f, float.MaxValue);
				physGrabObject.OverrideAngularDrag(0.5f, float.MaxValue);
				physGrabObject.OverrideZeroGravity(float.MaxValue);
			}
		}
	}
	internal class DuckThisPatch
	{
		private const string Ducky = "Apex Predator";

		[HarmonyPostfix]
		[HarmonyPriority(100)]
		[HarmonyPatch(typeof(EnemyDirector))]
		[HarmonyPatch("AmountSetup")]
		private static void EnemyDirectorAmountSetupPostfix(EnemyDirector __instance)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			IList<EnemySetup> enemyList = __instance.enemyList;
			EnemySetup item = default(EnemySetup);
			if (enemyList.Any((EnemySetup setup) => setup.spawnObjects.Select((GameObject so) => so.GetComponent<EnemyParent>()).Any((EnemyParent ep) => (Object)(object)ep != (Object)null && ep.enemyName == "Apex Predator")) || !Enemies.TryGetEnemyByName("Apex Predator", ref item))
			{
				return;
			}
			IList<EnemySetup> list = enemyList.Where(delegate(EnemySetup setup)
			{
				IEnumerable<EnemyParent> source = from so in setup.spawnObjects
					select so.GetComponent<EnemyParent>() into ep
					where (Object)(object)ep != (Object)null
					select ep;
				return source.All((EnemyParent ep) => (int)ep.difficulty == 0) && source.All((EnemyParent ep) => ep.enemyName != "Apex Predator");
			}).ToList();
			if (list.Count == 0)
			{
				RepoMutators.Logger.LogWarning((object)"No suitable enemies found to replace with Apex Predator");
				return;
			}
			EnemySetup val = list[Random.RandomRangeInt(0, list.Count)];
			if (enemyList.Remove(val))
			{
				RepoMutators.Logger.LogDebug((object)("[" + MutatorSettings.DuckThis.MutatorName + "] " + ((Object)val).name + " was removed in favor of Apex Predator"));
				enemyList.Add(item);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(EnemyDuck))]
		[HarmonyPatch("Update")]
		private static void EnemyDuckUpdatePrefix(EnemyDuck __instance)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				DuckThisBehaviour orAddComponent = ComponentHolderProtocol.GetOrAddComponent<DuckThisBehaviour>((Object)(object)__instance);
				if (((int)__instance.currentState == 5 || (int)__instance.currentState == 6 || (int)__instance.currentState == 7) && orAddComponent.CanNotice())
				{
					__instance.UpdateState((State)11);
				}
				if ((int)__instance.currentState == 16)
				{
					__instance.playerTarget = null;
					__instance.UpdateState((State)1);
					orAddComponent.NoticeCooldown = MutatorSettings.DuckThis.AggroCooldown;
				}
			}
		}
	}
	internal class FiringMyLaserPatch
	{
		private const string LaserActionEnabled = "laserActionEnabled";

		private static bool LaserBlocked;

		private static void AfterPatchAll()
		{
			MutatorManager instance = MutatorManager.Instance;
			instance.OnMetadataChanged = (Action<IDictionary<string, object>>)Delegate.Combine(instance.OnMetadataChanged, new Action<IDictionary<string, object>>(OnMetadataChanged));
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(LevelGenerator))]
		[HarmonyPatch("GenerateDone")]
		private static void LevelGeneratorGenerateDonePostfix()
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				IDictionary<string, object> metadata = new Dictionary<string, object> { 
				{
					"laserActionEnabled",
					MutatorSettings.FiringMyLaser.LaserActionEnabled
				} };
				MutatorsNetworkManager.Instance.SendMetadata(metadata);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerAvatar))]
		[HarmonyPatch("Start")]
		private static void PlayerAvatarStartPostfix(PlayerAvatar __instance)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			GameObject val = NetworkPrefabs.SpawnNetworkPrefab("Xepos.REPO-Mutators/FiringMyLaser", Vector3.zero, Quaternion.identity, (byte)0, new object[4]
			{
				__instance.steamID,
				MutatorSettings.FiringMyLaser.LaserActionCooldown,
				MutatorSettings.FiringMyLaser.LaserActionEnemyDamage,
				MutatorSettings.FiringMyLaser.LaserActionEnabled
			});
			if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val == (Object)null)
			{
				RepoMutators.Logger.LogWarning((object)("Failed to create laser for " + __instance.playerName));
			}
			else if (!SemiFunc.IsMultiplayer())
			{
				val.transform.SetParent(((Component)__instance).transform, false);
				LaserFiringBehaviour componentInChildren = val.GetComponentInChildren<LaserFiringBehaviour>();
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					val.SetActive(true);
					componentInChildren.laserCooldown = MutatorSettings.FiringMyLaser.LaserActionCooldown;
					componentInChildren.laserCooldownTimer = MutatorSettings.FiringMyLaser.LaserActionCooldown;
					componentInChildren.manualActionEnabled = MutatorSettings.FiringMyLaser.LaserActionEnabled;
					((HurtCollider)val.GetComponentInChildren<PlayerIgnoringHurtCollider>(true)).enemyDamage = MutatorSettings.FiringMyLaser.LaserActionEnemyDamage;
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(HurtCollider))]
		[HarmonyPatch("PlayerHurt")]
		private static bool HurtColliderPlayerHurt(HurtCollider __instance, PlayerAvatar _player)
		{
			if (__instance is PlayerIgnoringHurtCollider playerIgnoringHurtCollider && playerIgnoringHurtCollider.ignoredPlayers.Contains(_player))
			{
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerHealth))]
		[HarmonyPatch("HurtOtherRPC")]
		private static void PlayerHealthHurtOtherRPCPrefix(PlayerHealth __instance, int damage, Vector3 hurtPosition, int enemyIndex)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance.playerAvatar != (Object)(object)PlayerAvatar.instance) && enemyIndex == -1 && !(hurtPosition != Vector3.zero))
			{
				LaserBlocked = true;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerHealth))]
		[HarmonyPatch("Hurt")]
		private static void PlayerHealthHurtPostfix(PlayerHealth __instance, int damage)
		{
			if (damage >= 1 && !__instance.playerAvatar.deadSet && !LaserBlocked)
			{
				LaserFiringBehaviour componentInChildren = ((Component)__instance.playerAvatar).GetComponentInChildren<LaserFiringBehaviour>();
				if (Object.op_Implicit((Object)(object)componentInChildren) && !componentInChildren.IsActive())
				{
					componentInChildren.FireLaser(2.5f);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(1)]
		[HarmonyPatch(typeof(PlayerHealth))]
		[HarmonyPatch("Hurt")]
		private static void PlayerHealthHurtLaserResetPostfix()
		{
			LaserBlocked = false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerAvatar))]
		[HarmonyPatch("PlayerDeath")]
		private static void PlayerAvatarReviveRPCPostfix(PlayerAvatar __instance)
		{
			LaserFiringBehaviour componentInChildren = ((Component)__instance).GetComponentInChildren<LaserFiringBehaviour>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				componentInChildren.StopLaser(localOnly: true);
			}
		}

		private static void OnMetadataChanged(IDictionary<string, object> metadata)
		{
			if (!metadata.Get<bool>("laserActionEnabled"))
			{
				MutatorsNetworkManager.Instance.Run(DescriptionUtils.LateUpdateDescription("Fire your laser by pressing {specialActionKey}\nUncontrollably fire your laser when taking damage".Split("\n")[1]));
			}
			MutatorManager instance = MutatorManager.Instance;
			instance.OnMetadataChanged = (Action<IDictionary<string, object>>)Delegate.Remove(instance.OnMetadataChanged, new Action<IDictionary<string, object>>(OnMetadataChanged));
		}

		private static void BeforeUnpatchAll()
		{
			LaserBlocked = false;
			MutatorManager instance = MutatorManager.Instance;
			instance.OnMetadataChanged = (Action<IDictionary<string, object>>)Delegate.Remove(instance.OnMetadataChanged, new Action<IDictionary<string, object>>(OnMetadataChanged));
		}
	}
	internal class HandleWithCarePatch
	{
		private const string SurplusValuable = "Surplus Valuable";

		private static readonly IList<ValuableObject> valuableObjects = new List<ValuableObject>();

		private static bool SetupDone = false;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ValuableObject))]
		[HarmonyPatch("Awake")]
		private static void ValuableObjectAwake(ValuableObject __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && (MutatorSettings.HandleWithCare.MultiplySurplusValue || !((Object)((Component)__instance).gameObject).name.StartsWith("Surplus Valuable")))
			{
				RepoMutators.Logger.LogInfo((object)$"{((Object)__instance).name}: {__instance.photonView}");
				valuableObjects.Add(__instance);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ValuableObject))]
		[HarmonyPatch("DollarValueSetLogic")]
		private static void ValuableObjectDollarValueSetLogicPostfix(ValuableObject __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && SetupDone && (MutatorSettings.HandleWithCare.MultiplySurplusValue || !((Object)((Component)__instance).gameObject).name.StartsWith("Surplus Valuable")))
			{
				__instance.dollarValueCurrent *= MutatorSettings.HandleWithCare.ValueMultiplier;
				__instance.dollarValueOriginal *= MutatorSettings.HandleWithCare.ValueMultiplier;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(LevelGenerator))]
		[HarmonyPatch("GenerateDone")]
		private static void LevelGeneratorGenerateDonePostfix()
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			SetupDone = true;
			foreach (ValuableObject valuableObject in valuableObjects)
			{
				valuableObject.dollarValueCurrent *= MutatorSettings.HandleWithCare.ValueMultiplier;
				valuableObject.dollarValueOriginal *= MutatorSettings.HandleWithCare.ValueMultiplier;
				valuableObject.photonView.RPC("DollarValueSetRPC", (RpcTarget)1, new object[1] { valuableObject.dollarValueCurrent });
			}
			valuableObjects.Clear();
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PhysGrabObjectImpactDetector))]
		[HarmonyPatch("BreakRPC")]
		private static void PhysGrabObjectImpactDetectorBreakRPCPrefix(PhysGrabObjectImpactDetector __instance, ref float valueLost, bool _loseValue)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && (MutatorSettings.HandleWithCare.InstantlyDestroySurplus || !((Object)__instance).name.StartsWith("Surplus Valuable")) && __instance.isValuable && _loseValue)
			{
				valueLost = __instance.valuableObject.dollarValueCurrent;
			}
		}

		private static void BeforeUnpatchAll()
		{
			SetupDone = false;
		}
	}
	internal class HuntingSeasonPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(300)]
		[HarmonyPatch(typeof(EnemyDirector))]
		[HarmonyPatch("Start")]
		private static void EnemyDirectorAmountSetupPostfix(EnemyDirector __instance)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			__instance.DisableEnemies((EnemySetup setup) => setup.spawnObjects.All(delegate(GameObject so)
			{
				EnemyParent component = so.GetComponent<EnemyParent>();
				if ((Object)(object)component == (Object)null)
				{
					return true;
				}
				if (!(component.enemyName == "Peeper"))
				{
					EnemyHealth componentInChildren = so.GetComponentInChildren<EnemyHealth>();
					if (componentInChildren == null)
					{
						return false;
					}
					return !componentInChildren.spawnValuable;
				}
				return true;
			}));
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(StatsManager))]
		[HarmonyPatch("ItemFetchName")]
		private static void StatsManagerItemFetchNamePrefix(ref string itemName, ItemAttributes itemAttributes)
		{
			if (Object.op_Implicit((Object)(object)((Component)itemAttributes).GetComponent<TemporaryLevelItemBehaviour>()))
			{
				itemName += "(Hunting Season)";
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(LevelGenerator))]
		[HarmonyPatch("GenerateDone")]
		private static void LevelGeneratorGenerateDonePostfix()
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !SemiFunc.RunIsLevel())
			{
				return;
			}
			int num = RoundDirector.instance.physGrabObjects.Count / 2;
			foreach (PhysGrabObject item in RoundDirector.instance.physGrabObjects.ToList())
			{
				if (!item.isNonValuable)
				{
					item.DestroyPhysGrabObject();
				}
			}
			RepoMutators.Logger.LogDebug((object)string.Format("[{0}] Spawning {1} weapons", "Hunting Season", num));
			Item[] possibleItems = GetPossibleItems();
			IList<LevelPoint> list = SemiFunc.LevelPointsGetAll();
			IList<PhotonView> list2 = new List<PhotonView>();
			for (int i = 0; i < num; i++)
			{
				LevelPoint val = list[Random.Range(0, list.Count)];
				Item val2 = possibleItems[Random.Range(0, possibleItems.Length)];
				Vector3 position = ((Component)val).transform.position;
				position.y += 2f;
				GameObject val3 = Items.SpawnItem(val2, position, Quaternion.identityQuaternion);
				if (!((Object)(object)val3 == (Object)null))
				{
					val3.AddComponent<TemporaryLevelItemBehaviour>();
					PhotonView component = val3.GetComponent<PhotonView>();
					if (Object.op_Implicit((Object)(object)component))
					{
						list2.Add(component);
					}
				}
			}
			MutatorsNetworkManager.Instance.SendComponentForViews(list2.Select((PhotonView x) => x.ViewID).ToArray(), typeof(TemporaryLevelItemBehaviour));
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemAttributes))]
		[HarmonyPatch("Start")]
		private static void ItemAttributesStartPostfix(ItemAttributes __instance)
		{
			TemporaryLevelItemBehaviour component = ((Component)__instance).gameObject.GetComponent<TemporaryLevelItemBehaviour>();
			if (Object.op_Implicit((Object)(object)component))
			{
				__instance.itemName += " (Temporary)";
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(EnemyParent))]
		[HarmonyPatch("Despawn")]
		private static void EnemyParentDespawnPostfix(EnemyParent __instance)
		{
			if (__instance.Enemy.HasHealth && __instance.DespawnedTimer > 10f)
			{
				__instance.DespawnedTimer = 10f;
				__instance.Enemy.Health.spawnValuableCurrent = 0;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(RunManager))]
		[HarmonyPriority(500)]
		[HarmonyPatch("ChangeLevel")]
		private static void RunManagerChangeLevelPostfix()
		{
			if (!SemiFunc.IsMultiplayer() || !SemiFunc.IsNotMasterClient())
			{
				TemporaryItemUtils.DropMarkedItems("Hunting Season");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(RunManager))]
		[HarmonyPriority(500)]
		[HarmonyPatch("UpdateLevel")]
		private static void RunManagerUpdateLevelPostfix()
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				TemporaryItemUtils.DropMarkedItems("Hunting Season");
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PunManager))]
		[HarmonyPatch("SyncAllDictionaries")]
		private static void PunManagerSyncAllDictionariesPrefix()
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.RunIsShop())
			{
				TemporaryItemUtils.RemoveMarkedItems("Hunting Season");
			}
		}

		private static Item[] GetPossibleItems()
		{
			return Items.AllItems.Where((Item i) => (int)i.itemType == 7 || (int)i.itemType == 9).ToArray();
		}
	}
	internal class LessIsMorePatch
	{
		private const string SurplusValuable = "Surplus Valuable";

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ValuableObject))]
		[HarmonyPatch("DollarValueSetLogic")]
		private static void ValuableObjectDollarValueSetLogicPostfix(ValuableObject __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer() && (MutatorSettings.HandleWithCare.MultiplySurplusValue || !((Object)((Component)__instance).gameObject).name.StartsWith("Surplus Valuable")))
			{
				__instance.dollarValueCurrent /= 2f;
				__instance.dollarValueOriginal /= 2f;
			}
		}
	}
	internal class OneShotOneKillPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerHealthGrab))]
		[HarmonyPatch("Start")]
		private static void PlayerHealthGrabStart(PlayerHealthGrab __instance)
		{
			((Behaviour)__instance).enabled = false;
		}

		[HarmonyPostfix]
		[HarmonyPriority(300)]
		[HarmonyPatch(typeof(EnemyDirector))]
		[HarmonyPatch("Start")]
		private static void EnemyDirectorAmountSetupPostfix(EnemyDirector __instance)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				__instance.DisableEnemies();
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(450)]
		[HarmonyPatch(typeof(PlayerDeathHead))]
		[HarmonyPatch("Update")]
		private static void PlayerDeathHeadUpdatePostfix(PlayerDeathHead __instance)
		{
			if (__instance.triggered && MutatorSettings.OneShotOneKill.InstaReviveInTruckOrExtraction && !SemiFunc.IsNotMasterClient())
			{
				if (__instance.roomVolumeCheck.inTruck)
				{
					DoRevive(__instance, inTruck: true);
				}
				else if (__instance.roomVolumeCheck.inExtractionPoint)
				{
					DoRevive(__instance, inTruck: false);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerHealth))]
		[HarmonyPatch("Hurt")]
		private static void PlayerHealthHurtPrefix(PlayerHealth __instance, ref int damage, ref bool savingGrace)
		{
			if (!__instance.godMode && damage >= 1)
			{
				damage = __instance.maxHealth;
				savingGrace = false;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerHealth))]
		[HarmonyPatch("HurtOther")]
		private static void PlayerHealthHurtOtherPrefix(PlayerHealth __instance, ref int damage, ref bool savingGrace)
		{
			if (!__instance.godMode && damage >= 1)
			{
				damage = __instance.maxHealth;
				savingGrace = false;
			}
		}

		private static void DoRevive(PlayerDeathHead playerDeathHead, bool inTruck)
		{
			int num = ((MutatorSettings.OneShotOneKill.InstaReviveHealth == 0) ? (playerDeathHead.playerAvatar.playerHealth.maxHealth - 1) : (MutatorSettings.OneShotOneKill.InstaReviveHealth - 1));
			playerDeathHead.playerAvatar.Revive(inTruck);
			if (num > 0)
			{
				playerDeathHead.playerAvatar.playerHealth.HealOther(num, true);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyHealth))]
	internal class OutWithABangPatch
	{
		private static ExplosionPreset explosionPreset = null;

		private static readonly float ExplosionSizeFallback = 1.2f;

		private static readonly int ExplosionDamageFallback = 100;

		private static readonly IDictionary<Difficulty, (float size, int damage)> SizeDamage = InitDamageMap();

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void EnemeyHealthAwakePostfix(EnemyHealth __instance)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			EnemyHealth __instance2 = __instance;
			if ((Object)(object)explosionPreset == (Object)null)
			{
				explosionPreset = Object.Instantiate<ExplosionPreset>(AssetStore.Preset);
			}
			EnemyParent enemyParent = __instance2.enemy.EnemyParent;
			if (enemyParent.enemyName != "Banger")
			{
				ParticleScriptExplosion particleScriptExplosion = ComponentHolderProtocol.AddComponent<ParticleScriptExplosion>((Object)(object)__instance2);
				particleScriptExplosion.explosionPreset = explosionPreset;
				float explosionSize = ExplosionSizeFallback;
				int explosionDamage = ExplosionDamageFallback;
				if (SizeDamage.TryGetValue(enemyParent.difficulty, out (float, int) value))
				{
					(explosionSize, explosionDamage) = value;
				}
				__instance2.onDeath.AddListener((UnityAction)delegate
				{
					Explode(__instance2.enemy, particleScriptExplosion, explosionSize, explosionDamage);
				});
			}
		}

		private static void Explode(Enemy enemy, ParticleScriptExplosion particleScriptExplosion, float size, int damage)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			particleScriptExplosion.Spawn(enemy.CenterTransform.position, size, damage, damage, 1f, false, false, 1f);
		}

		private static IDictionary<Difficulty, (float size, int damage)> InitDamageMap()
		{
			return new Dictionary<Difficulty, (float, int)>
			{
				{
					(Difficulty)0,
					(0.6f, 25)
				},
				{
					(Difficulty)1,
					(0.9f, 50)
				},
				{
					(Difficulty)2,
					(ExplosionSizeFallback, ExplosionDamageFallback)
				}
			};
		}
	}
	internal class ProtectThePresidentPatch
	{
		private const string PresidentId = "presidentId";

		private static bool _presidentAlive = true;

		private static bool _failureMessageSent = false;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(LevelGenerator))]
		[HarmonyPatch("GenerateDone")]
		private static void LevelGeneratorGenerateDonePostfix()
		{
			_presidentAlive = true;
			_failureMessageSent = false;
			if (SemiFunc.IsMultiplayer() && SemiFunc.IsMasterClient())
			{
				PlayerAvatar val = PickPresidentPlayer();
				RepoMutators.Logger.LogDebug((object)("Picked " + val.playerName + " as the president!"));
				MutatorsNetworkManager.Instance.SendMetadata(new Dictionary<string, object> { { "presidentId", val.steamID } });
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(NetworkManager))]
		[HarmonyPatch("OnPlayerLeftRoom")]
		private static void NetworkManagerOnPlayerLeftRoomPrefix(Player otherPlayer)
		{
			PlayerAvatar val = SemiFunc.PlayerGetFromName(otherPlayer.NickName);
			if (val.steamID == MutatorManager.Instance.Metadata.Get<string>("presidentId"))
			{
				MutatorManager instance = MutatorManager.Instance;
				instance.OnMetadataChanged = (Action<IDictionary<string, object>>)Delegate.Combine(instance.OnMetadataChanged, new Action<IDictionary<string, object>>(OnMetadataChanged));
				if (SemiFunc.IsMultiplayer() && SemiFunc.IsMasterClient())
				{
					PlayerAvatar val2 = PickPresidentPlayer();
					MutatorsNetworkManager.Instance.SendMetadata(new Dictionary<string, object> { { "presidentId", val2.steamID } });
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerAvatar))]
		[HarmonyPatch("PlayerDeathRPC")]
		private static void PlayerAvatarPlayerDeathRPCPostfix(PlayerAvatar __instance, int enemyIndex)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			string text = MutatorManager.Instance.Metadata.Get<string>("presidentId");
			if (__instance.steamID == text && __instance.steamID != PlayerAvatar.instance.steamID)
			{
				_presidentAlive = false;
				PlayerAvatar val = SemiFunc.PlayerGetFromSteamID(text);
				SemiFunc.UIFocusText("President " + ((val != null && val.playerName != null) ? (val.playerName + " ") : "") + " has died.", Color.white, AssetManager.instance.colorYellow, 3f);
				ChatManager.instance.PossessSelfDestruction();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ChatManager))]
		[HarmonyPatch("PossessChat")]
		private static void ChatManagerPossessChatPrefix(PossessChatID _possessChatID, ref string message)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			if (!_presidentAlive && !_failureMessageSent && (int)_possessChatID == 3)
			{
				message = "We have failed " + (SemiFunc.PlayerGetFromSteamID(MutatorManager.Instance.Metadata.Get<string>("presidentId"))?.playerName ?? " the president");
				_failureMessageSent = true;
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(100)]
		[HarmonyPatch(typeof(PlayerHealth))]
		[HarmonyPatch("UpdateHealthRPC")]
		private static void PlayerHealthUpdateHealthRPCPostfix(PlayerHealth __instance)
		{
			string text = MutatorManager.Instance.Metadata.Get<string>("presidentId");
			if (!(__instance.playerAvatar.steamID != text) && !(text == PlayerAvatar.instance.steamID))
			{
				UpdatePresidentHealth(text);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(LoadingUI))]
		[HarmonyPatch("StopLoading")]
		private static void InitializePresidentHealth()
		{
			if (!SemiFunc.RunIsLevel())
			{
				TargetPlayerAnnouncingBehaviour instance = TargetPlayerAnnouncingBehaviour.instance;
				if (Object.op_Implicit((Object)(object)instance))
				{
					((TMP_Text)instance.Text).text = string.Empty;
				}
			}
			else
			{
				string text = MutatorManager.Instance.Metadata.Get<string>("presidentId");
				if (text != PlayerAvatar.instance.steamID)
				{
					MutatorsNetworkManager.Instance.Run(InitializePresidentHealthEnumerator(text));
				}
			}
		}

		private static void UpdatePresidentHealth(string presidentId)
		{
			TargetPlayerAnnouncingBehaviour instance = TargetPlayerAnnouncingBehaviour.instance;
			if (Object.op_Implicit((Object)(object)instance))
			{
				RepoMutators.Logger.LogDebug((object)"Updating President Health");
				((TMP_Text)instance.Text).text = BuildPresidentText(presidentId);
			}
		}

		internal static string BuildPresidentText(string presidentId)
		{
			PlayerAvatar val = SemiFunc.PlayerAvatarGetFromSteamID(presidentId);
			return string.Format("{0}: {1}/{2}", val.playerName ?? "President", val.playerHealth.health, val.playerHealth.maxHealth);
		}

		private static IEnumerator InitializePresidentHealthEnumerator(string presidentId)
		{
			while ((Object)(object)TargetPlayerAnnouncingBehaviour.instance == (Object)null)
			{
				yield return (object)new WaitForSeconds(0.5f);
			}
			UpdatePresidentHealth(presidentId);
		}

		private static PlayerAvatar PickPresidentPlayer()
		{
			List<PlayerAvatar> list = SemiFunc.PlayerGetAll();
			return list[Random.RandomRangeInt(0, list.Count)];
		}

		private static void OnMetadataChanged(IDictionary<string, object> metadata)
		{
			RepoMutators.Logger.LogDebug((object)"President metadata has changed");
			UpdatePresidentHealth(metadata.Get<string>("presidentId"));
			MutatorManager instance = MutatorManager.Instance;
			instance.OnMetadataChanged = (Action<IDictionary<string, object>>)Delegate.Remove(instance.OnMetadataChanged, new Action<IDictionary<string, object>>(OnMetadataChanged));
		}
	}