Decompiled source of BCP Golmon v1.0.0

BrutalCompanyPlus.dll

Decompiled 9 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BrutalCompanyPlus.Api;
using BrutalCompanyPlus.Config;
using BrutalCompanyPlus.Events;
using BrutalCompanyPlus.Objects;
using BrutalCompanyPlus.Utils;
using DunGen;
using GameNetcodeStuff;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("BrutalCompanyPlus")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A CUSTOMIZABLE hardcore mod that randomizes events ranging between insanity and normal.")]
[assembly: AssemblyFileVersion("4.0.0.0")]
[assembly: AssemblyInformationalVersion("4.0.0")]
[assembly: AssemblyProduct("BrutalCompanyPlus")]
[assembly: AssemblyTitle("BrutalCompanyPlus")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
internal class <Module>
{
	static <Module>()
	{
	}
}
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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BrutalCompanyPlus
{
	[BepInPlugin("BrutalCompanyPlus", "BrutalCompanyPlus", "4.0.0")]
	[BepInProcess("Lethal Company.exe")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		internal static GameObject BCNetworkManagerPrefab;

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			PluginConfig.Bind(this);
			EventRegistry.AutoRegister((BaseUnityPlugin)(object)this);
			BcpUtils.InitializeNetcode();
			InitializeBCNetworkManager();
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			Logger.LogWarning((object)"BrutalCompanyPlus initialized...");
		}

		private static void InitializeBCNetworkManager()
		{
			Logger.LogWarning((object)"Initializing BCNetworkManager...");
			AssetBundle val = AssetBundle.LoadFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("BrutalCompanyPlus.Assets.brutalcompanyplus"));
			BCNetworkManagerPrefab = val.LoadAsset<GameObject>("Assets/BCNetworkManager.prefab");
			BCNetworkManagerPrefab.AddComponent<BCNetworkManager>();
			val.Unload(false);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "BrutalCompanyPlus";

		public const string PLUGIN_NAME = "BrutalCompanyPlus";

		public const string PLUGIN_VERSION = "4.0.0";
	}
}
namespace BrutalCompanyPlus.Utils
{
	public static class BcpUtils
	{
		internal static void InitializeNetcode()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			foreach (Type type in types)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array = methods;
				foreach (MethodInfo methodInfo in array)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (!customAttributes.IsEmpty())
					{
						Plugin.Logger.LogWarning((object)("Initializing RPCs for " + type.Name + "..."));
						methodInfo.Invoke(null, null);
					}
				}
			}
		}

		public static void AddCredits(this Terminal Terminal, int Amount)
		{
			Terminal.groupCredits += Amount;
			Terminal.SyncGroupCreditsServerRpc(Terminal.groupCredits, Terminal.numberOfItemsInDropship);
		}

		public static Vector3 GetNearbyLocation(Vector3 Location)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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)
			Vector3 val = Random.insideUnitSphere * 10f;
			return Location + val;
		}

		public static GameObject FindObjectPrefab<T>(this SelectableLevel Level) where T : MonoBehaviour
		{
			SpawnableMapObject[] spawnableMapObjects = Level.spawnableMapObjects;
			foreach (SpawnableMapObject val in spawnableMapObjects)
			{
				if (val.IsObjectTypeOf<T>(out var _))
				{
					return val.prefabToSpawn;
				}
			}
			throw new Exception("Unable to find prefab of type " + typeof(T).Name + " in level " + ((Object)Level).name + ".");
		}

		public static bool IsObjectTypeOf<T>(this SpawnableMapObject MapObject, out T Component)
		{
			Component = MapObject.prefabToSpawn.GetComponentInChildren<T>();
			return Component != null;
		}

		public static bool IntInRange(this IntRange Range, int Value)
		{
			if (Value >= Range.Min)
			{
				return Value <= Range.Max;
			}
			return false;
		}

		public static bool IsEmpty<T>(this IEnumerable<T> Collection)
		{
			return !Collection.Any();
		}

		public static List<T> TakeIf<T>(this List<T> List, Func<T, bool> Predicate)
		{
			List<T> result = List.Where(Predicate).ToList();
			List.RemoveAll((T E) => Predicate(E));
			return result;
		}

		public static bool Random<T>(this List<T> List, out T Value)
		{
			if (List.IsEmpty())
			{
				Value = default(T);
				return false;
			}
			Value = List[Random.Range(0, List.Count)];
			return true;
		}

		public static bool Random<T>(this T[] Array, out T Value)
		{
			if (Array.IsEmpty())
			{
				Value = default(T);
				return false;
			}
			Value = Array[Random.Range(0, Array.Length)];
			return true;
		}

		public static bool Random<T>(this IEnumerable<T> Enumerable, out T Value)
		{
			return Enumerable.ToList().Random(out Value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void ForEach<T, TResult>(this IEnumerable<T> Collection, Func<T, TResult> Action)
		{
			foreach (T item in Collection)
			{
				Action(item);
			}
		}
	}
	public static class ChatUtils
	{
		public static void Send(string Message, bool Clear = false)
		{
			if (Clear)
			{
				ChatUtils.Clear();
			}
			HUDManager.Instance.AddTextToChatOnServer(Message, -1);
		}

		public static void SendLocal(string Message, bool Clear = false)
		{
			if (Clear)
			{
				ChatUtils.Clear();
			}
			HUDManager.Instance.AddChatMessage(Message, "");
		}

		private static void Clear()
		{
			Send("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
		}

		internal static void NotifyError()
		{
			SendLocal("An error occurred in BrutalCompanyPlus. Check the console for more information.");
		}
	}
	public static class ConfigUtils
	{
		public static bool GetIfSet<T>(this ConfigEntry<T> Entry, out T Value) where T : notnull
		{
			T value = Entry.Value;
			if (value is int && (int)(object)/*isinst with value type is only supported in some contexts*/ == -1)
			{
				Value = default(T);
				return false;
			}
			Value = Entry.Value;
			return true;
		}

		internal static Dictionary<string, int> GetEnemyRarityValues(string LevelName)
		{
			string[] array = ((ConfigEntry<string>)(LevelName switch
			{
				"ExperimentationLevel" => PluginConfig.EnemyRarityValues.ExperimentationLevel, 
				"AssuranceLevel" => PluginConfig.EnemyRarityValues.AssuranceLevel, 
				"VowLevel" => PluginConfig.EnemyRarityValues.VowLevel, 
				"OffenseLevel" => PluginConfig.EnemyRarityValues.OffenseLevel, 
				"MarchLevel" => PluginConfig.EnemyRarityValues.MarchLevel, 
				"RendLevel" => PluginConfig.EnemyRarityValues.RendLevel, 
				"DineLevel" => PluginConfig.EnemyRarityValues.DineLevel, 
				"TitanLevel" => PluginConfig.EnemyRarityValues.TitanLevel, 
				_ => PluginConfig.EnemyRarityValues.CustomLevel, 
			})).Value.Split(',');
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			string[] array2 = array;
			foreach (string text in array2)
			{
				try
				{
					var (key, value) = ParseHelpers.ParseEnemyRarityEntry(text);
					dictionary.Add(key, value);
				}
				catch (ParseException arg)
				{
					Diagnostics.AddError($"Bad entry in enemy rarity values ({text}): {arg}");
				}
			}
			if (!dictionary.IsEmpty())
			{
				return dictionary;
			}
			Plugin.Logger.LogError((object)("Invalid enemy rarity values: " + PluginConfig.MoonHeat.HeatCurve.Value));
			return dictionary;
		}

		internal static (int, int, int, int) GetScrapValues(string LevelName)
		{
			string text = ((ConfigEntry<string>)(LevelName switch
			{
				"ExperimentationLevel" => PluginConfig.ScrapValues.ExperimentationLevel, 
				"AssuranceLevel" => PluginConfig.ScrapValues.AssuranceLevel, 
				"VowLevel" => PluginConfig.ScrapValues.VowLevel, 
				"OffenseLevel" => PluginConfig.ScrapValues.OffenseLevel, 
				"MarchLevel" => PluginConfig.ScrapValues.MarchLevel, 
				"RendLevel" => PluginConfig.ScrapValues.RendLevel, 
				"DineLevel" => PluginConfig.ScrapValues.DineLevel, 
				"TitanLevel" => PluginConfig.ScrapValues.TitanLevel, 
				_ => PluginConfig.ScrapValues.CustomLevel, 
			})).Value.Trim();
			if (text == "-1,-1,-1,-1")
			{
				Plugin.Logger.LogWarning((object)("Using default scrap values for " + LevelName));
				return (-1, -1, -1, -1);
			}
			try
			{
				return ParseHelpers.ParseScrapValues(text);
			}
			catch (ParseException arg)
			{
				Diagnostics.AddError($"Invalid scrap values ({text}): {arg}");
				return (-1, -1, -1, -1);
			}
		}

		internal static List<(int, int, LevelWeatherType)> GetMoonHeatCurve()
		{
			List<(int, int, LevelWeatherType)> list = new List<(int, int, LevelWeatherType)>();
			string[] array = PluginConfig.MoonHeat.HeatCurve.Value.Split(',');
			foreach (string text in array)
			{
				try
				{
					(int, int, LevelWeatherType) item = ParseHelpers.ParseHeatCurvePoint(text);
					list.Add(item);
				}
				catch (ParseException arg)
				{
					Diagnostics.AddError($"Bad point in moon heat curve ({text}): {arg}");
				}
			}
			if (!list.IsEmpty())
			{
				return list;
			}
			Plugin.Logger.LogError((object)("Invalid moon heat curve: " + PluginConfig.MoonHeat.HeatCurve.Value));
			Plugin.Logger.LogError((object)"Using fallback curve instead (0-100%: no weather)");
			list.Add((0, 101, (LevelWeatherType)(-1)));
			return list;
		}
	}
	internal static class Diagnostics
	{
		private static readonly List<string> Errors = new List<string>();

		internal static bool HasErrors => !Errors.IsEmpty();

		internal static void AddError(string Error)
		{
			Errors.Add(Error);
			Plugin.Logger.LogError((object)Error);
		}

		internal static string CollectErrors()
		{
			string result = string.Join("\n", Errors);
			Errors.Clear();
			return result;
		}
	}
	internal static class EnemyUtils
	{
		private static readonly Dictionary<string, EnemyType> InsideEnemyTypes = new Dictionary<string, EnemyType>();

		private static readonly Dictionary<string, EnemyType> OutsideEnemyTypes = new Dictionary<string, EnemyType>();

		internal static void SpawnInsideEnemy(RoundManager Instance, GameObject EnemyPrefab)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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)
			if (Instance.allEnemyVents.Random(out var Value))
			{
				Vector3 position = Value.floorNode.position;
				Quaternion val = Quaternion.Euler(0f, Value.floorNode.eulerAngles.y, 0f);
				GameObject val2 = Object.Instantiate<GameObject>(EnemyPrefab, position, val);
				val2.GetComponentInChildren<NetworkObject>().Spawn(true);
				EnemyAI component = val2.GetComponent<EnemyAI>();
				if (component.enemyType.isOutsideEnemy)
				{
					component.enemyType = SetOutsideEnemy(component.enemyType, IsOutside: false);
					BCNetworkManager.Instance.SyncEnemyTypeClientRpc(NetworkBehaviourReference.op_Implicit((NetworkBehaviour)(object)component), IsOutside: false);
				}
				Instance.SpawnedEnemies.Add(component);
			}
		}

		internal static void SpawnOutsideEnemy(RoundManager Instance, GameObject EnemyPrefab)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if (GameObject.FindGameObjectsWithTag("OutsideAINode").Random(out var Value))
			{
				GameObject val = Object.Instantiate<GameObject>(EnemyPrefab, Value.transform.position, Quaternion.identity);
				val.GetComponentInChildren<NetworkObject>().Spawn(true);
				EnemyAI component = val.GetComponent<EnemyAI>();
				if (!component.enemyType.isOutsideEnemy)
				{
					component.enemyType = SetOutsideEnemy(component.enemyType, IsOutside: true);
					BCNetworkManager.Instance.SyncEnemyTypeClientRpc(NetworkBehaviourReference.op_Implicit((NetworkBehaviour)(object)component), IsOutside: true);
				}
				Instance.SpawnedEnemies.Add(component);
			}
		}

		internal static EnemyType SetOutsideEnemy(EnemyType OriginalType, bool IsOutside)
		{
			EnemyType value2;
			if (IsOutside)
			{
				if (OutsideEnemyTypes.TryGetValue(OriginalType.enemyName, out var value))
				{
					return value;
				}
			}
			else if (InsideEnemyTypes.TryGetValue(OriginalType.enemyName, out value2))
			{
				return value2;
			}
			EnemyType val = Object.Instantiate<EnemyType>(OriginalType);
			val.isOutsideEnemy = IsOutside;
			if (IsOutside)
			{
				OutsideEnemyTypes.Add(OriginalType.enemyName, val);
			}
			else
			{
				InsideEnemyTypes.Add(OriginalType.enemyName, val);
			}
			return val;
		}
	}
	internal static class LevelDefaults
	{
		internal static readonly Dictionary<string, Dictionary<string, int>> DefaultEnemyRarityValues = new Dictionary<string, Dictionary<string, int>>
		{
			{
				"ExperimentationLevel",
				new Dictionary<string, int>
				{
					{ "Centipede", 50 },
					{ "Bunker Spider", 75 },
					{ "Hoarding bug", 80 },
					{ "Flowerman", 30 },
					{ "Crawler", 15 },
					{ "Blob", 25 },
					{ "Girl", 2 },
					{ "Puffer", 10 },
					{ "Nutcracker", 15 },
					{ "Spring", 5 },
					{ "Jester", 1 },
					{ "Masked", 1 },
					{ "Lasso", 1 }
				}
			},
			{
				"AssuranceLevel",
				new Dictionary<string, int>
				{
					{ "Centipede", 50 },
					{ "Bunker Spider", 40 },
					{ "Hoarding bug", 50 },
					{ "Flowerman", 30 },
					{ "Crawler", 15 },
					{ "Blob", 25 },
					{ "Girl", 2 },
					{ "Puffer", 40 },
					{ "Nutcracker", 15 },
					{ "Spring", 25 },
					{ "Jester", 3 },
					{ "Masked", 3 },
					{ "Lasso", 1 }
				}
			},
			{
				"VowLevel",
				new Dictionary<string, int>
				{
					{ "Centipede", 50 },
					{ "Bunker Spider", 40 },
					{ "Hoarding bug", 50 },
					{ "Flowerman", 30 },
					{ "Crawler", 20 },
					{ "Blob", 25 },
					{ "Girl", 5 },
					{ "Puffer", 40 },
					{ "Nutcracker", 20 },
					{ "Spring", 40 },
					{ "Jester", 15 },
					{ "Masked", 10 },
					{ "Lasso", 0 }
				}
			},
			{
				"OffenseLevel",
				new Dictionary<string, int>
				{
					{ "Centipede", 50 },
					{ "Bunker Spider", 40 },
					{ "Hoarding bug", 50 },
					{ "Flowerman", 30 },
					{ "Crawler", 20 },
					{ "Blob", 25 },
					{ "Girl", 5 },
					{ "Puffer", 40 },
					{ "Nutcracker", 20 },
					{ "Spring", 40 },
					{ "Jester", 15 },
					{ "Masked", 10 },
					{ "Lasso", 0 }
				}
			},
			{
				"MarchLevel",
				new Dictionary<string, int>
				{
					{ "Centipede", 50 },
					{ "Bunker Spider", 40 },
					{ "Hoarding bug", 50 },
					{ "Flowerman", 30 },
					{ "Crawler", 20 },
					{ "Blob", 25 },
					{ "Girl", 10 },
					{ "Puffer", 40 },
					{ "Nutcracker", 20 },
					{ "Spring", 40 },
					{ "Jester", 15 },
					{ "Masked", 10 },
					{ "Lasso", 0 }
				}
			},
			{
				"RendLevel",
				new Dictionary<string, int>
				{
					{ "Centipede", 35 },
					{ "Bunker Spider", 25 },
					{ "Hoarding bug", 30 },
					{ "Flowerman", 56 },
					{ "Crawler", 50 },
					{ "Blob", 40 },
					{ "Girl", 25 },
					{ "Puffer", 40 },
					{ "Nutcracker", 30 },
					{ "Spring", 58 },
					{ "Jester", 40 },
					{ "Masked", 10 },
					{ "Lasso", 2 }
				}
			},
			{
				"DineLevel",
				new Dictionary<string, int>
				{
					{ "Centipede", 35 },
					{ "Bunker Spider", 25 },
					{ "Hoarding bug", 30 },
					{ "Flowerman", 56 },
					{ "Crawler", 50 },
					{ "Blob", 40 },
					{ "Girl", 25 },
					{ "Puffer", 40 },
					{ "Nutcracker", 30 },
					{ "Spring", 58 },
					{ "Jester", 40 },
					{ "Masked", 10 },
					{ "Lasso", 2 }
				}
			},
			{
				"TitanLevel",
				new Dictionary<string, int>
				{
					{ "Centipede", 35 },
					{ "Bunker Spider", 25 },
					{ "Hoarding bug", 30 },
					{ "Flowerman", 56 },
					{ "Crawler", 60 },
					{ "Blob", 40 },
					{ "Girl", 25 },
					{ "Puffer", 40 },
					{ "Nutcracker", 30 },
					{ "Spring", 58 },
					{ "Jester", 40 },
					{ "Masked", 10 },
					{ "Lasso", 2 }
				}
			},
			{
				"???_custom_???",
				new Dictionary<string, int>
				{
					{ "Centipede", 35 },
					{ "Bunker Spider", 25 },
					{ "Hoarding bug", 30 },
					{ "Flowerman", 56 },
					{ "Crawler", 60 },
					{ "Blob", 40 },
					{ "Girl", 25 },
					{ "Puffer", 40 },
					{ "Nutcracker", 30 },
					{ "Spring", 58 },
					{ "Jester", 40 },
					{ "Masked", 10 },
					{ "Lasso", 2 }
				}
			}
		};
	}
	public static class LevelNames
	{
		public const string CompanyBuilding = "CompanyBuildingLevel";

		public const string Experimentation = "ExperimentationLevel";

		public const string Assurance = "AssuranceLevel";

		public const string Vow = "VowLevel";

		public const string Offense = "OffenseLevel";

		public const string March = "MarchLevel";

		public const string Rend = "RendLevel";

		public const string Dine = "DineLevel";

		public const string Titan = "TitanLevel";

		internal const string Custom = "???_custom_???";

		public static readonly string[] All = new string[8] { "ExperimentationLevel", "AssuranceLevel", "VowLevel", "OffenseLevel", "MarchLevel", "RendLevel", "DineLevel", "TitanLevel" };

		internal static readonly string[] AllCustom = All.Concat(new string[1] { "???_custom_???" }).ToArray();

		public static bool IsCustom(string LevelName)
		{
			return !All.Contains(LevelName);
		}
	}
	internal static class ParseHelpers
	{
		private static readonly string RangeError = $"must be between {MoonHeatManager.MoonHeatRange.Min} and {MoonHeatManager.MoonHeatRange.Max}";

		internal static (int, int, LevelWeatherType) ParseHeatCurvePoint(string Point)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			string[] array = Point.Split(':');
			if (array.Length != 3)
			{
				throw new ParseException("invalid format");
			}
			if (!int.TryParse(array[0], out var result))
			{
				throw new ParseException("invalid start value");
			}
			if (!MoonHeatManager.MoonHeatRange.IntInRange(result))
			{
				throw new ParseException("start value out of range, " + RangeError);
			}
			if (!int.TryParse(array[1], out var result2))
			{
				throw new ParseException("invalid end value");
			}
			if (!MoonHeatManager.MoonHeatRange.IntInRange(Math.Max(0, result2 - 1)))
			{
				throw new ParseException("end value out of range, " + RangeError);
			}
			if (!Enum.TryParse<LevelWeatherType>(array[2], out LevelWeatherType result3))
			{
				throw new ParseException("invalid weather type");
			}
			return (result, result2, result3);
		}

		internal static (int, int, int, int) ParseScrapValues(string Entries)
		{
			string[] array = Entries.Split(',');
			if (array.Length != 4)
			{
				throw new ParseException("invalid format");
			}
			if (!int.TryParse(array[0], out var result))
			{
				throw new ParseException("invalid minScrap value");
			}
			if (!int.TryParse(array[1], out var result2))
			{
				throw new ParseException("invalid maxScrap value");
			}
			if (!int.TryParse(array[2], out var result3))
			{
				throw new ParseException("invalid minTotalScrapValue value");
			}
			if (!int.TryParse(array[3], out var result4))
			{
				throw new ParseException("invalid maxTotalScrapValue value");
			}
			return (result, result2, result3, result4);
		}

		internal static (string, int) ParseEnemyRarityEntry(string Entry)
		{
			string[] array = Entry.Split(':');
			if (array.Length != 2)
			{
				throw new ParseException("invalid format");
			}
			string item;
			if (string.IsNullOrEmpty(item = array[0]))
			{
				throw new ParseException("invalid enemy name");
			}
			if (!int.TryParse(array[1], out var result))
			{
				throw new ParseException("invalid rarity value");
			}
			return (item, result);
		}
	}
	internal class ParseException : Exception
	{
		public ParseException(string Message)
			: base(Message)
		{
		}

		public override string ToString()
		{
			return Message;
		}
	}
	public static class PlayerUtils
	{
		public static IEnumerable<PlayerControllerB> AllPlayers => StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB Player) => Player.isPlayerControlled);

		public static IEnumerable<PlayerControllerB> AlivePlayers => AllPlayers.Where((PlayerControllerB Player) => !Player.isPlayerDead);

		public static IEnumerable<PlayerControllerB> OutsidePlayers => AlivePlayers.Where((PlayerControllerB Player) => !Player.isInHangarShipRoom && !Player.isInsideFactory);
	}
	public static class Singleton
	{
		public static Terminal Terminal => Object.FindObjectOfType<Terminal>();
	}
}
namespace BrutalCompanyPlus.Patches
{
	[HarmonyPatch]
	internal static class EnemyPatches
	{
		private const string Tag = "[EnemyPatches]";

		[HarmonyPrefix]
		[HarmonyPatch(typeof(RoundManager), "BeginEnemySpawning")]
		private static void SpawnPendingEnemiesImmediately(ref RoundManager __instance)
		{
			if (EnemySpawnManager.PendingSpawns.IsEmpty())
			{
				return;
			}
			foreach (var (val, spawnInfo) in EnemySpawnManager.PendingSpawns.TakeIf(((EnemyType EnemyType, EnemySpawnManager.SpawnInfo SpawnInfo) si) => si.SpawnInfo.Immediate))
			{
				Plugin.Logger.LogInfo((object)string.Format("{0} Spawning {1} {2} (outside: {3}) enemies... (immediate)", "[EnemyPatches]", spawnInfo.Amount, val.enemyName, spawnInfo.Outside));
				for (int i = 0; i < spawnInfo.Amount; i++)
				{
					if (spawnInfo.Outside)
					{
						EnemyUtils.SpawnOutsideEnemy(__instance, val.enemyPrefab);
					}
					else
					{
						EnemyUtils.SpawnInsideEnemy(__instance, val.enemyPrefab);
					}
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(RoundManager), "SpawnInsideEnemiesFromVentsIfReady")]
		private static void SpawnPendingEnemiesDelayed(ref RoundManager __instance)
		{
			if (EnemySpawnManager.PendingSpawns.IsEmpty() || !StartOfRound.Instance.allPlayerScripts.Any((PlayerControllerB player) => player.isInsideFactory))
			{
				return;
			}
			foreach (var (val, spawnInfo) in EnemySpawnManager.PendingSpawns.TakeIf(((EnemyType EnemyType, EnemySpawnManager.SpawnInfo SpawnInfo) si) => !si.SpawnInfo.Immediate))
			{
				Plugin.Logger.LogInfo((object)string.Format("{0} Spawning {1} {2} (outside: {3}) enemies... (delayed)", "[EnemyPatches]", spawnInfo.Amount, val.enemyName, spawnInfo.Outside));
				for (int i = 0; i < spawnInfo.Amount; i++)
				{
					if (spawnInfo.Outside)
					{
						EnemyUtils.SpawnOutsideEnemy(__instance, val.enemyPrefab);
					}
					else
					{
						EnemyUtils.SpawnInsideEnemy(__instance, val.enemyPrefab);
					}
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class LevelPatches
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		[HarmonyPatch(typeof(StartOfRound), "Start")]
		private static void ModifyLevelsPatch(ref StartOfRound __instance)
		{
			if (!((NetworkBehaviour)__instance).IsHost)
			{
				return;
			}
			LevelManager.AddAllEnemiesToAllLevels(__instance.levels);
			SelectableLevel[] levels = __instance.levels;
			foreach (SelectableLevel val in levels)
			{
				if (!(((Object)val).name == "CompanyBuildingLevel"))
				{
					MoonHeatManager.InitializeFor(val);
					LevelManager.ApplyEnemyRarityValues(val);
					LevelManager.ApplyEnemySpawnChances(val);
					LevelManager.ApplyEnemySpawnRates(val);
					LevelManager.ApplyLevelProperties(val);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPriority(0)]
		[HarmonyPatch(typeof(RoundManager), "LoadNewLevel")]
		private static void SelectLevelEventPatch(ref RoundManager __instance, ref SelectableLevel newLevel)
		{
			if (((NetworkBehaviour)__instance).IsHost)
			{
				if (((Object)newLevel).name == "CompanyBuildingLevel")
				{
					Plugin.Logger.LogWarning((object)"Landed at the Company Building, forcing no event...");
					ChatUtils.Send("<color=green>Welcome to the Company Building!</color>", Clear: true);
				}
				else
				{
					MoonHeatManager.AdjustHeatValues(newLevel);
					EventManager.StartEventServer(newLevel);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(RoundManager), "DespawnPropsAtEndOfRound")]
		private static void HandleLevelEventEndPatch(ref RoundManager __instance)
		{
			if (((NetworkBehaviour)__instance).IsHost)
			{
				EventManager.EndEventServer(__instance.currentLevel);
			}
		}
	}
	[HarmonyPatch]
	internal static class MoneyPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(TimeOfDay), "Awake")]
		private static void AdjustQuotaValues(ref TimeOfDay __instance)
		{
			Plugin.Logger.LogWarning((object)"Adjusting starting quota values...");
			if (PluginConfig.QuotaAdjustments.DeadlineDays.GetIfSet<int>(out var Value))
			{
				__instance.quotaVariables.deadlineDaysAmount = Value;
			}
			if (PluginConfig.QuotaAdjustments.StartingCredits.GetIfSet<int>(out Value))
			{
				__instance.quotaVariables.startingCredits = Value;
			}
			if (PluginConfig.QuotaAdjustments.StartingQuota.GetIfSet<int>(out Value))
			{
				__instance.quotaVariables.startingQuota = Value;
			}
			if (PluginConfig.QuotaAdjustments.BaseIncrease.GetIfSet<int>(out Value))
			{
				__instance.quotaVariables.baseIncrease = Value;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(RoundManager), "DetectElevatorIsRunning")]
		private static void CompensatePlayersPatch(ref RoundManager __instance)
		{
			if (((NetworkBehaviour)__instance).IsServer)
			{
				if (StartOfRound.Instance.allPlayersDead)
				{
					ChatUtils.Send("<size=10><color=red>That was brutal! No compensation today :c</color></size>", Clear: true);
					return;
				}
				int value = PluginConfig.CreditsAdjustments.FreeMoneyAmount.Value;
				Singleton.Terminal.AddCredits(value);
				ChatUtils.Send("<size=10><color=green>You survived another day! Here's your compensation :)\n" + $"<color=orange>+{value} credits</color></size>", Clear: true);
			}
		}
	}
	[HarmonyPatch]
	internal static class NetcodePatches
	{
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		[HarmonyPostfix]
		private static void InjectNetworkManager()
		{
			NetworkManager.Singleton.AddNetworkPrefab(Plugin.BCNetworkManagerPrefab);
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPostfix]
		private static void SpawnNetworkManager()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				Object.Instantiate<GameObject>(Plugin.BCNetworkManagerPrefab, Vector3.zero, Quaternion.identity).GetComponent<NetworkObject>().Spawn(false);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal static class PlayerPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void ShowDiagnosticsPatch(PlayerControllerB __instance)
		{
			__instance.movementAudio.priority = 127;
		}
	}
	[HarmonyPatch]
	internal class SharedEnemyAIPatches
	{
		private static Vector3 ShipLocation => StartOfRound.Instance.playerSpawnPositions[0].position;

		[HarmonyPrefix]
		[HarmonyPriority(800)]
		[HarmonyPatch(typeof(EnemyAI), "StartSearch")]
		private static void SpringManSearchFromShipPatch(ref EnemyAI __instance, ref Vector3 startOfSearch)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (__instance is SpringManAI && __instance.isOutside)
			{
				startOfSearch = BcpUtils.GetNearbyLocation(ShipLocation);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FlowermanAI), "Start")]
		private static void FlowermanOutsideFavoritePositionPatch(ref FlowermanAI __instance)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (((EnemyAI)__instance).isOutside)
			{
				__instance.mainEntrancePosition = ShipLocation;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(BlobAI), "HitEnemy")]
		private static bool BlobDamageLagPatch(ref PlayerControllerB playerWhoHit)
		{
			return (Object)(object)playerWhoHit != (Object)null;
		}
	}
	[HarmonyPatch(typeof(MenuManager))]
	internal static class UIPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void ShowDiagnosticsPatch(MenuManager __instance)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			if (!__instance.isInitScene && Diagnostics.HasErrors)
			{
				__instance.DisplayMenuNotification("[BrutalCompanyPlus]\nOne or more errors occurred during startup:\n" + Diagnostics.CollectErrors() + "\n\n", "[ Quit ]");
				((UnityEvent)__instance.menuNotification.GetComponentInChildren<Button>().onClick).AddListener(new UnityAction(__instance.ClickQuitButton));
			}
		}
	}
}
namespace BrutalCompanyPlus.Objects
{
	public class BCNetworkManager : NetworkBehaviour
	{
		private const string Tag = "[BCNetworkManager]";

		private const string DisconnectMessage = "BrutalCompanyPlus\nServer sent invalid enemy reference!\nThis is a bug, please report it!";

		public static BCNetworkManager Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			Log("BCNetworkManager initialized!");
		}

		private void Update()
		{
			if (((NetworkBehaviour)this).IsServer && ((NetworkBehaviour)this).IsHost && EventManager.CurrentEvent != null)
			{
				EventManager.CurrentEvent.UpdateServer();
			}
		}

		[ClientRpc]
		public void SyncEnemyTypeClientRpc(NetworkBehaviourReference Reference, bool IsOutside)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2971397334u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkBehaviourReference>(ref Reference, default(ForNetworkSerializable));
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref IsOutside, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2971397334u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost) || ((NetworkBehaviour)this).IsServer || ((NetworkBehaviour)this).IsHost)
			{
				return;
			}
			Log($"Syncing enemy type (outside: {IsOutside})... (client)");
			EnemyAI val3 = default(EnemyAI);
			if (!((NetworkBehaviourReference)(ref Reference)).TryGet<EnemyAI>(ref val3, (NetworkManager)null))
			{
				Log("Bad enemy received from server! Disconnecting client to prevent further issues... (client)");
				GameNetworkManager.Instance.disconnectionReasonMessage = "BrutalCompanyPlus\nServer sent invalid enemy reference!\nThis is a bug, please report it!";
				GameNetworkManager.Instance.Disconnect();
				return;
			}
			val3.enemyType = EnemyUtils.SetOutsideEnemy(val3.enemyType, IsOutside);
			if (val3.path1 != null)
			{
				Plugin.Logger.LogWarning((object)("Received SyncEnemyType RPC for " + ((Object)val3).name + " too late, catching up..."));
				val3.isOutside = IsOutside;
				val3.allAINodes = GameObject.FindGameObjectsWithTag(IsOutside ? "OutsideAINode" : "AINode");
				if ((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null)
				{
					val3.EnableEnemyMesh(!StartOfRound.Instance.hangarDoorsClosed || !GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom, false);
				}
			}
		}

		[ClientRpc]
		public void StartEventClientRpc(int EventId, int LevelId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(554658467u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, EventId);
				BytePacker.WriteValueBitPacked(val2, LevelId);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 554658467u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost) || ((NetworkBehaviour)this).IsServer || ((NetworkBehaviour)this).IsHost)
			{
				return;
			}
			Log($"Received start event request: eid = {EventId}, lid = {LevelId}");
			IEvent @event = EventRegistry.GetEvent(EventId);
			if (@event == null)
			{
				Log($"Bad event id {EventId} received from server.");
				return;
			}
			SelectableLevel val3 = StartOfRound.Instance.levels.ElementAtOrDefault(LevelId);
			if ((Object)(object)val3 == (Object)null)
			{
				Log($"Bad level id {LevelId} received from server.");
			}
			else
			{
				EventManager.StartEventClient(val3, @event);
			}
		}

		[ClientRpc]
		public void EndEventClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3012541483u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3012541483u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !((NetworkBehaviour)this).IsServer && !((NetworkBehaviour)this).IsHost)
				{
					Log("Received end event request... (client)");
					EventManager.EndEventClient(RoundManager.Instance.currentLevel);
				}
			}
		}

		[ClientRpc]
		public void SyncWeatherClientRpc(int LevelId, LevelWeatherType WeatherType)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4219652153u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, LevelId);
				((FastBufferWriter)(ref val2)).WriteValueSafe<LevelWeatherType>(ref WeatherType, default(ForEnums));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4219652153u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				Log($"Syncing weather type {WeatherType} on level {LevelId}...");
				SelectableLevel val3 = StartOfRound.Instance.levels.ElementAtOrDefault(LevelId);
				if ((Object)(object)val3 == (Object)null)
				{
					Log($"Bad level id {LevelId} received from server.");
				}
				else
				{
					val3.currentWeather = WeatherType;
				}
			}
		}

		private static void Log(string Message)
		{
			Plugin.Logger.LogWarning((object)("[BCNetworkManager] " + Message));
		}

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

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_BCNetworkManager()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(2971397334u, new RpcReceiveHandler(__rpc_handler_2971397334));
			NetworkManager.__rpc_func_table.Add(554658467u, new RpcReceiveHandler(__rpc_handler_554658467));
			NetworkManager.__rpc_func_table.Add(3012541483u, new RpcReceiveHandler(__rpc_handler_3012541483));
			NetworkManager.__rpc_func_table.Add(4219652153u, new RpcReceiveHandler(__rpc_handler_4219652153));
		}

		private static void __rpc_handler_2971397334(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				NetworkBehaviourReference reference = default(NetworkBehaviourReference);
				((FastBufferReader)(ref reader)).ReadValueSafe<NetworkBehaviourReference>(ref reference, default(ForNetworkSerializable));
				bool isOutside = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref isOutside, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((BCNetworkManager)(object)target).SyncEnemyTypeClientRpc(reference, isOutside);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_554658467(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int eventId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref eventId);
				int levelId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref levelId);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((BCNetworkManager)(object)target).StartEventClientRpc(eventId, levelId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3012541483(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((BCNetworkManager)(object)target).EndEventClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_4219652153(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int levelId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref levelId);
				LevelWeatherType weatherType = default(LevelWeatherType);
				((FastBufferReader)(ref reader)).ReadValueSafe<LevelWeatherType>(ref weatherType, default(ForEnums));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((BCNetworkManager)(object)target).SyncWeatherClientRpc(levelId, weatherType);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "BCNetworkManager";
		}
	}
	public static class EnemySpawnManager
	{
		public readonly struct SpawnInfo
		{
			public readonly int Amount;

			public readonly bool Outside;

			public readonly bool Immediate;

			public SpawnInfo(int Amount, bool Outside = false, bool Immediate = true)
			{
				this.Amount = Amount;
				this.Outside = Outside;
				this.Immediate = Immediate;
			}
		}

		internal static readonly List<(EnemyType EnemyType, SpawnInfo SpawnInfo)> PendingSpawns = new List<(EnemyType, SpawnInfo)>();

		public static void DraftEnemySpawn<T>(SpawnInfo Info) where T : EnemyAI
		{
			if (!LevelManager.TryGetEnemy<T>(out var EnemyType))
			{
				throw new ArgumentException("Failed to get EnemyType for " + typeof(T).Name + "!");
			}
			PendingSpawns.Add((EnemyType, Info));
		}

		public static void DraftEnemySpawn(EnemyType Type, SpawnInfo Info)
		{
			PendingSpawns.Add((Type, Info));
		}
	}
	public static class EventManager
	{
		internal static IEvent CurrentEvent;

		public static bool IsActive<T>() where T : IEvent
		{
			return CurrentEvent is T;
		}

		public static void StartEventServer(SelectableLevel Level)
		{
			if (CurrentEvent != null)
			{
				Plugin.Logger.LogError((object)"StartEventServer called twice, this shouldn't happen! (do you have LE installed?)");
				return;
			}
			IEvent @event = SelectRandomEvent(Level);
			if (@event != null)
			{
				Plugin.Logger.LogWarning((object)("Starting event " + @event.Name + "... (server)"));
				BCNetworkManager.Instance.StartEventClientRpc(@event.GetId(), Level.levelID);
				@event.ExecuteServer(Level);
				NotifyEventStarted(@event);
				CurrentEvent = @event;
			}
		}

		public static void EndEventServer(SelectableLevel Level)
		{
			if (CurrentEvent == null)
			{
				Plugin.Logger.LogError((object)"EndEventServer called without an active event, please report this!");
				ChatUtils.NotifyError();
				return;
			}
			Plugin.Logger.LogWarning((object)("Ending event " + CurrentEvent.Name + "... (server)"));
			BCNetworkManager.Instance.EndEventClientRpc();
			CurrentEvent.OnEnd(Level);
			LevelManager.UndoLevelPropertyChanges();
			CurrentEvent = null;
		}

		public static void StartEventClient(SelectableLevel Level, IEvent Event)
		{
			if (CurrentEvent != null)
			{
				Plugin.Logger.LogError((object)"StartEventClient called twice, this shouldn't happen! (did the server start an event twice?)");
				ChatUtils.NotifyError();
			}
			else
			{
				Plugin.Logger.LogWarning((object)("Starting event " + Event.Name + "... (client)"));
				Event.ExecuteClient(Level);
				CurrentEvent = Event;
			}
		}

		public static void EndEventClient(SelectableLevel Level)
		{
			if (CurrentEvent == null)
			{
				Plugin.Logger.LogError((object)"EndEventClient called without an active event, please report this!");
				ChatUtils.NotifyError();
			}
			else
			{
				Plugin.Logger.LogWarning((object)("Ending event " + CurrentEvent.Name + "... (client)"));
				CurrentEvent.OnEnd(Level);
				CurrentEvent = null;
			}
		}

		private static IEvent SelectRandomEvent(SelectableLevel Level)
		{
			int num = 0;
			while (true)
			{
				int num2 = Random.Range(0, 101);
				object obj;
				if (num2 <= PluginConfig.EventSettings.GlobalChance.Value)
				{
					obj = (PluginConfig.EventSettings.EqualChance.Value ? EventRegistry.GetRandomEventWithoutRarity() : EventRegistry.GetRandomEvent());
				}
				else
				{
					IEvent @event = EventRegistry.GetEvent<NoneEvent>();
					obj = @event;
				}
				IEvent event2 = (IEvent)obj;
				if (event2.CanRun(Level))
				{
					return event2;
				}
				if (++num > 20)
				{
					break;
				}
				Plugin.Logger.LogWarning((object)$"Event {event2.Name} cannot be ran, rerolling... (attempt {num} / {20})");
			}
			Plugin.Logger.LogWarning((object)$"Failed to select an event ({num} > {20}), forcing no event...");
			return EventRegistry.GetEvent<NoneEvent>();
		}

		private static void NotifyEventStarted(IEvent Event)
		{
			string text = Event.Positivity switch
			{
				EventPositivity.Positive => "green", 
				EventPositivity.Neutral => "white", 
				EventPositivity.Negative => "red", 
				EventPositivity.Golden => "orange", 
				_ => "white", 
			};
			ChatUtils.Send("<color=yellow>EVENT<color=white>:</color></color>\n<color=" + text + ">" + Event.Name + "</color>\n<color=white><size=70%>" + Event.Description + "</size></color>");
		}
	}
	internal static class LevelManager
	{
		private static readonly Dictionary<string, Action> UndoPropertyCallbacks = new Dictionary<string, Action>();

		public static List<SpawnableEnemyWithRarity> AllInsideEnemies;

		public static List<SpawnableEnemyWithRarity> AllOutsideEnemies;

		public static List<SpawnableEnemyWithRarity> AllDaytimeEnemies;

		public static IEnumerable<SpawnableEnemyWithRarity> AllEnemies => AllInsideEnemies.Concat(AllOutsideEnemies).Concat(AllDaytimeEnemies);

		public static bool TryGetEnemy<T>(out EnemyType EnemyType) where T : EnemyAI
		{
			EnemyType = AllEnemies.FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity Enemy) => (Object)(object)Enemy.enemyType.enemyPrefab.GetComponent<T>() != (Object)null))?.enemyType;
			return (Object)(object)EnemyType != (Object)null;
		}

		public static void ModifyLevelProperties(SelectableLevel Level, Action<SelectableLevel> Effect, params string[] Dependencies)
		{
			Dictionary<string, object> dictionary = new Dictionary<string, object>();
			foreach (string text in Dependencies)
			{
				FieldInfo field = ((object)Level).GetType().GetField(text);
				if (!dictionary.TryAdd(text, field.GetValue(Level)))
				{
					throw new Exception("Property '" + text + "' mentioned twice in dependencies array!");
				}
			}
			Effect(Level);
			foreach (string text2 in Dependencies)
			{
				FieldInfo property = ((object)Level).GetType().GetField(text2);
				object originalValue = dictionary[text2];
				object value = property.GetValue(Level);
				if (!originalValue.Equals(value) && !UndoPropertyCallbacks.TryAdd(text2, delegate
				{
					property.SetValue(Level, originalValue);
				}))
				{
					throw new Exception("Property '" + text2 + "' already contains an undo callback! Did you call ModifyLevelProperties twice on the same property?");
				}
			}
		}

		public static void SpawnMapObject(GameObject Prefab, Vector3 Position, Quaternion Rotation)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Object.Instantiate<GameObject>(Prefab, Position, Rotation, RoundManager.Instance.mapPropsContainer.transform).GetComponent<NetworkObject>().Spawn(true);
		}

		public static T SpawnMapObject<T>(GameObject Prefab, Vector3 Position, Quaternion Rotation)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(Prefab, Position, Rotation, RoundManager.Instance.mapPropsContainer.transform);
			val.GetComponent<NetworkObject>().Spawn(true);
			return val.GetComponentInChildren<T>();
		}

		internal static void UndoLevelPropertyChanges()
		{
			Plugin.Logger.LogDebug((object)"Undoing level property changes... (server)");
			foreach (Action value in UndoPropertyCallbacks.Values)
			{
				value();
			}
			UndoPropertyCallbacks.Clear();
		}

		internal static void AddAllEnemiesToAllLevels(SelectableLevel[] Levels)
		{
			AllInsideEnemies = Levels.SelectMany((SelectableLevel Level) => Level.Enemies).SortEnemies();
			AllOutsideEnemies = Levels.SelectMany((SelectableLevel Level) => Level.OutsideEnemies).SortEnemies();
			AllDaytimeEnemies = Levels.SelectMany((SelectableLevel Level) => Level.DaytimeEnemies).SortEnemies();
			if (!PluginConfig.EnemyAdjustments.SpawnOnAllMoons.Value)
			{
				return;
			}
			foreach (SelectableLevel level in Levels)
			{
				level.Enemies.AddRange(AllInsideEnemies.Where((SpawnableEnemyWithRarity InsideEnemy) => level.Enemies.All((SpawnableEnemyWithRarity Enemy) => Enemy.enemyType.enemyName != InsideEnemy.enemyType.enemyName)));
			}
		}

		internal static void ApplyEnemyRarityValues(SelectableLevel Level)
		{
			if (!PluginConfig.EnemyRarityValues.Enabled.Value)
			{
				return;
			}
			Dictionary<string, int> enemyRarityValues = ConfigUtils.GetEnemyRarityValues(((Object)Level).name);
			string text = ((Object)Level).name;
			if (LevelNames.IsCustom(text))
			{
				text = "???_custom_???";
			}
			if (!LevelDefaults.DefaultEnemyRarityValues.TryGetValue(text, out var value))
			{
				Plugin.Logger.LogError((object)("No default rarity values found for level: " + ((Object)Level).name));
				return;
			}
			foreach (SpawnableEnemyWithRarity enemy in Level.Enemies)
			{
				string enemyName = enemy.enemyType.enemyName;
				if ((!enemyRarityValues.TryGetValue(enemyName, out var value2) || value2 == -1) && !value.TryGetValue(enemyName, out value2))
				{
					Plugin.Logger.LogError((object)("No default rarity value found for enemy: " + enemyName));
				}
				else
				{
					enemy.rarity = value2;
				}
			}
		}

		internal static void ApplyEnemySpawnChances(SelectableLevel Level)
		{
			MultiplyCurvePoints(ref Level.enemySpawnChanceThroughoutDay, 3, PositiveOnly: true);
			MultiplyCurvePoints(ref Level.outsideEnemySpawnChanceThroughDay, 3, PositiveOnly: true);
		}

		internal static void ApplyEnemySpawnRates(SelectableLevel Level)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_008f: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			SpawnableMapObject[] spawnableMapObjects = Level.spawnableMapObjects;
			foreach (SpawnableMapObject val in spawnableMapObjects)
			{
				if (val.IsObjectTypeOf<Turret>(out var _) && PluginConfig.MapHazards.TurretSpawnRate.GetIfSet<int>(out var Value))
				{
					val.numberToSpawn = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
					{
						new Keyframe(0f, 0f),
						new Keyframe(1f, (float)Value)
					});
				}
				if (val.IsObjectTypeOf<Landmine>(out var _) && PluginConfig.MapHazards.LandmineSpawnRate.GetIfSet<int>(out Value))
				{
					val.numberToSpawn = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
					{
						new Keyframe(0f, 0f),
						new Keyframe(1f, (float)Value)
					});
				}
			}
		}

		internal static void ApplyLevelProperties(SelectableLevel Level)
		{
			var (newValue, newValue2, newValue3, newValue4) = ConfigUtils.GetScrapValues(((Object)Level).name);
			ApplyIfSet(ref Level.minScrap, newValue);
			ApplyIfSet(ref Level.maxScrap, newValue2);
			ApplyIfSet(ref Level.minTotalScrapValue, newValue3);
			ApplyIfSet(ref Level.maxTotalScrapValue, newValue4);
			Level.maxEnemyPowerCount += 150;
			Level.maxOutsideEnemyPowerCount += 10;
			Level.maxDaytimeEnemyPowerCount += 150;
		}

		private static void ApplyIfSet(ref int Value, int NewValue)
		{
			if (NewValue != -1)
			{
				Value = NewValue;
			}
		}

		private static void MultiplyCurvePoints(ref AnimationCurve Curve, int Multiplier, bool PositiveOnly = false)
		{
			Keyframe[] keys = Curve.keys;
			for (int i = 0; i < keys.Length; i++)
			{
				if (!PositiveOnly || !(((Keyframe)(ref keys[i])).value < 0f))
				{
					ref Keyframe reference = ref keys[i];
					((Keyframe)(ref reference)).value = ((Keyframe)(ref reference)).value * (float)Multiplier;
				}
			}
			Curve.keys = keys;
		}

		private static List<SpawnableEnemyWithRarity> SortEnemies(this IEnumerable<SpawnableEnemyWithRarity> Enemies)
		{
			return (from Enemy in Enemies
				orderby Enemy.rarity descending
				group Enemy by Enemy.enemyType.enemyName into Group
				select Group.First()).ToList();
		}
	}
	public static class MoonHeatManager
	{
		public static readonly IntRange MoonHeatRange = new IntRange(0, 100);

		private static readonly Dictionary<SelectableLevel, float> LevelHeatValues = new Dictionary<SelectableLevel, float>();

		public static void InitializeFor(SelectableLevel Level)
		{
			LevelHeatValues.TryAdd(Level, 0f);
		}

		public static void ResetHeatValues()
		{
			foreach (SelectableLevel item in LevelHeatValues.Keys.ToList())
			{
				LevelHeatValues[item] = 0f;
			}
		}

		public static void AdjustHeatValues(SelectableLevel CurrentLevel)
		{
			float heat = IncreaseHeatValueOf(CurrentLevel);
			foreach (SelectableLevel item in LevelHeatValues.Keys.ToList())
			{
				if (!((Object)(object)CurrentLevel == (Object)(object)item))
				{
					DecreaseHeatValueOf(item);
				}
			}
			NotifyPlayersAndSetWeather(CurrentLevel, heat);
		}

		private static float IncreaseHeatValueOf(SelectableLevel Level)
		{
			if (!LevelHeatValues.TryGetValue(Level, out var value))
			{
				return 0f;
			}
			LevelHeatValues[Level] = Mathf.Clamp(value + PluginConfig.MoonHeat.IncreaseRate.Value, (float)MoonHeatRange.Min, (float)MoonHeatRange.Max);
			return value;
		}

		private static void DecreaseHeatValueOf(SelectableLevel Level)
		{
			if (LevelHeatValues.TryGetValue(Level, out var value))
			{
				LevelHeatValues[Level] = Mathf.Clamp(value - PluginConfig.MoonHeat.DecreaseRate.Value, (float)MoonHeatRange.Min, (float)MoonHeatRange.Max);
			}
		}

		private static void NotifyPlayersAndSetWeather(SelectableLevel CurrentLevel, float Heat)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected I4, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected I4, but got Unknown
			ChatUtils.Send("<color=orange>MOON IS AT " + Heat + "% HEAT</color>", Clear: true);
			foreach (var (num, num2, val) in ConfigUtils.GetMoonHeatCurve())
			{
				if (!(Heat < (float)num) && !(Heat >= (float)num2))
				{
					BCNetworkManager.Instance.SyncWeatherClientRpc(CurrentLevel.levelID, val);
					NotifyChat((val - 1) switch
					{
						0 => "blue", 
						2 => "purple", 
						3 => "yellow", 
						1 => "orange", 
						4 => "red", 
						_ => "white", 
					}, (val - 1) switch
					{
						0 => "Heat is rising and caused it to rain...", 
						2 => "Heat is rising, causing a layer of fog...", 
						3 => "Moon is getting hot, causing a flood...", 
						1 => "Extreme heat is causing a dangerous weather...", 
						4 => "Moon is at max heat, causing hostile creatures to roam it...", 
						_ => "Heat is rising...", 
					});
					break;
				}
			}
		}

		private static void NotifyChat(string Color, string Title)
		{
			ChatUtils.Send("<size=11><color=" + Color + ">" + Title + "</color>\n<color=white>Visit other moons to decrease the heat!</color></size>");
		}
	}
}
namespace BrutalCompanyPlus.Events
{
	[UsedImplicitly]
	[HarmonyPatch]
	public class BlobEvolutionEvent : IEvent
	{
		private const float NormalSpeed = 3.8f;

		private const float OpenDoorSpeedMultiplier = 1.5f;

		public string Name => "They are EVOLVING?!";

		public string Description => "Here I was, thinking that Pokémon was the only game with evolutions.";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Uncommon;

		public void ExecuteServer(SelectableLevel Level)
		{
			SetBlobEnemyTag();
			EnemySpawnManager.DraftEnemySpawn<BlobAI>(new EnemySpawnManager.SpawnInfo(3));
			EnemySpawnManager.DraftEnemySpawn<BlobAI>(new EnemySpawnManager.SpawnInfo(1, Outside: true));
		}

		public void ExecuteClient(SelectableLevel Level)
		{
			SetBlobEnemyTag();
		}

		public void OnEnd(SelectableLevel Level)
		{
			SetBlobEnemyTag(Unset: true);
		}

		private static void SetBlobEnemyTag(bool Unset = false)
		{
			if (LevelManager.TryGetEnemy<BlobAI>(out EnemyType EnemyType))
			{
				string tag = (Unset ? "Untagged" : "Enemy");
				Transform val = EnemyType.enemyPrefab.transform.Find("Armature");
				((Component)val).gameObject.tag = tag;
				EnemyAICollisionDetect[] componentsInChildren = ((Component)val).GetComponentsInChildren<EnemyAICollisionDetect>();
				foreach (EnemyAICollisionDetect val2 in componentsInChildren)
				{
					((Component)val2).gameObject.tag = tag;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(BlobAI), "Update")]
		private static void EnemyAIPatch(ref BlobAI __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner && EventManager.IsActive<BlobEvolutionEvent>())
			{
				((EnemyAI)__instance).agent.speed = 3.8f;
				((EnemyAI)__instance).openDoorSpeedMultiplier = 1.5f;
			}
		}
	}
	[UsedImplicitly]
	public class DeliveryEvent : IEvent
	{
		private const int MinItems = 2;

		private const int MaxItems = 9;

		public string Name => "ICE SCREAM!!!";

		public string Description => "Mommy, the ice cream truck is here!";

		public EventPositivity Positivity => EventPositivity.Positive;

		public EventRarity DefaultRarity => EventRarity.Rare;

		public void ExecuteServer(SelectableLevel Level)
		{
			int num = Singleton.Terminal.buyableItemsList.Length;
			int num2 = Random.Range(2, 9);
			for (int i = 0; i < num2; i++)
			{
				Singleton.Terminal.orderedItemsFromTerminal.Add(Random.Range(0, num));
			}
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}
	}
	[UsedImplicitly]
	public class FaceHuggersEvent : IEvent
	{
		public string Name => "Bring a shovel!";

		public string Description => "They just want a hug...";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Uncommon;

		public void ExecuteServer(SelectableLevel Level)
		{
			EnemySpawnManager.DraftEnemySpawn<CentipedeAI>(new EnemySpawnManager.SpawnInfo(15, Outside: false, Immediate: false));
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}
	}
	[UsedImplicitly]
	public class GuardsEvent : IEvent
	{
		public string Name => "They guard this place!";

		public string Description => "Better not get kicked out again...";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Uncommon;

		public void ExecuteServer(SelectableLevel Level)
		{
			EnemySpawnManager.DraftEnemySpawn<NutcrackerEnemyAI>(new EnemySpawnManager.SpawnInfo(4, Outside: true));
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}
	}
	[UsedImplicitly]
	public class HideAndSeekEvent : IEvent
	{
		public string Name => "Hide and Seek";

		public string Description => "She's gonna find you...";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Uncommon;

		public void ExecuteServer(SelectableLevel Level)
		{
			EnemySpawnManager.DraftEnemySpawn<DressGirlAI>(new EnemySpawnManager.SpawnInfo(5));
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}
	}
	[UsedImplicitly]
	public class HoarderTownEvent : IEvent
	{
		public string Name => "Hoarder Town";

		public string Description => "Come on, those are mine!";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Rare;

		public void ExecuteServer(SelectableLevel Level)
		{
			EnemySpawnManager.DraftEnemySpawn<HoarderBugAI>(new EnemySpawnManager.SpawnInfo(6));
			EnemySpawnManager.DraftEnemySpawn<HoarderBugAI>(new EnemySpawnManager.SpawnInfo(3, Outside: true));
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}
	}
	[UsedImplicitly]
	public class HungerGamesEvent : IEvent
	{
		private PlayerControllerB _currentTarget;

		private bool _playerKilled;

		public string Name => "The Hunger Games";

		public string Description => "May the odds be ever in your favor.";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Rare;

		public bool CanRun(SelectableLevel Level)
		{
			return StartOfRound.Instance.connectedPlayersAmount > 0;
		}

		public void ExecuteServer(SelectableLevel Level)
		{
			PickNewTarget();
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}

		public void UpdateServer()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (!_playerKilled && !((Object)(object)_currentTarget == (Object)null))
			{
				if (_currentTarget.isPlayerDead && !StartOfRound.Instance.allPlayersDead)
				{
					PickNewTarget();
				}
				if (_currentTarget.isInsideFactory)
				{
					_playerKilled = true;
					_currentTarget.DamagePlayerFromOtherClientServerRpc(_currentTarget.health, default(Vector3), (int)_currentTarget.playerClientId);
					ChatUtils.Send("<color=purple>" + _currentTarget.playerUsername + "</color> <color=orange>volunteered as Tribute!</color>");
				}
			}
		}

		public void OnEnd(SelectableLevel Level)
		{
			_currentTarget = null;
			_playerKilled = false;
		}

		private void PickNewTarget()
		{
			if (PlayerUtils.AlivePlayers.Random(out _currentTarget))
			{
				this.Log("New target chosen: " + _currentTarget.playerUsername);
			}
		}
	}
	[UsedImplicitly]
	[HarmonyPatch]
	public class InstaJesterEvent : IEvent
	{
		private const float MinTimer = 1f;

		private const float MaxTimer = 5f;

		public string Name => "Pop goes the.. HOLY FUC-";

		public string Description => "Lord have mercy on your soul.";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Rare;

		public void ExecuteServer(SelectableLevel Level)
		{
			EnemySpawnManager.DraftEnemySpawn<JesterAI>(new EnemySpawnManager.SpawnInfo(2));
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(JesterAI), "SetJesterInitialValues")]
		private static void EnemyAIPatch(ref JesterAI __instance)
		{
			if (EventManager.IsActive<InstaJesterEvent>())
			{
				__instance.popUpTimer = Random.Range(1f, 5f);
			}
		}
	}
	[UsedImplicitly]
	public class NoneEvent : IEvent
	{
		public string Name => "Nothing happened today!";

		public string Description => "Just another Tuesday.";

		public EventPositivity Positivity => EventPositivity.Positive;

		public EventRarity DefaultRarity => EventRarity.Uncommon;

		public void ExecuteServer(SelectableLevel Level)
		{
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}
	}
	[UsedImplicitly]
	[HarmonyPatch]
	public class OutsideTheBoxEvent : IEvent
	{
		public string Name => "Outside the box!";

		public string Description => "Creepy...";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Rare;

		public void ExecuteServer(SelectableLevel Level)
		{
			EnemySpawnManager.DraftEnemySpawn<JesterAI>(new EnemySpawnManager.SpawnInfo(2, Outside: true));
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}

		private static bool HookResetFlag(PlayerControllerB player, EnemyAI Instance)
		{
			if (EventManager.IsActive<OutsideTheBoxEvent>() && Instance.isOutside)
			{
				return !player.isInsideFactory;
			}
			return player.isInsideFactory;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(JesterAI), "Update")]
		private static IEnumerable<CodeInstruction> EnemyAIPatch(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerControllerB), "isInsideFactory");
			MethodInfo methodInfo = AccessTools.Method(typeof(OutsideTheBoxEvent), "HookResetFlag", (Type[])null, (Type[])null);
			bool flag = false;
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 1; i < list.Count; i++)
			{
				if (CodeInstructionExtensions.LoadsField(list[i - 1], fieldInfo, false) && !(list[i].opcode != OpCodes.Brfalse))
				{
					list[i - 1] = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
					list.Insert(i, new CodeInstruction(OpCodes.Call, (object)methodInfo));
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				Diagnostics.AddError("Failed to patch JesterAI.Update()! (event: OutsideTheBoxEvent, ver: 4.0.0)");
			}
			return list.AsEnumerable();
		}
	}
	[UsedImplicitly]
	public class ResetHeatEvent : IEvent
	{
		public string Name => "All moon heat has been reset!";

		public string Description => "Seems like Pluto just passed by.";

		public EventPositivity Positivity => EventPositivity.Positive;

		public EventRarity DefaultRarity => EventRarity.Uncommon;

		public void ExecuteServer(SelectableLevel Level)
		{
			MoonHeatManager.ResetHeatValues();
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}
	}
	[UsedImplicitly]
	public class ShadowRealmEvent : IEvent
	{
		public string Name => "The shadows are roaming";

		public string Description => "Did you hear that?";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Rare;

		public void ExecuteServer(SelectableLevel Level)
		{
			EnemySpawnManager.DraftEnemySpawn<FlowermanAI>(new EnemySpawnManager.SpawnInfo(6, Outside: true));
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}
	}
	[UsedImplicitly]
	public class ShipTurretEvent : IEvent
	{
		private static readonly Vector3 TurretPosition = new Vector3(3.87f, 0.84f, -14.23f);

		private GameObject _prefab;

		private GameObject _turret;

		private bool _shouldSpawn;

		private bool _spawned;

		public string Name => "When did we get this installed?!";

		public string Description => "I'm innocent, I swear!";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Uncommon;

		public void ExecuteServer(SelectableLevel Level)
		{
			if (_prefab == null)
			{
				_prefab = Level.FindObjectPrefab<Turret>();
			}
			_shouldSpawn = true;
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}

		public void UpdateServer()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (_shouldSpawn)
			{
				_shouldSpawn = false;
				_spawned = true;
				_turret = Object.Instantiate<GameObject>(_prefab, TurretPosition, Quaternion.identity);
				_turret.transform.forward = new Vector3(1f, 0f, 0f);
				_turret.GetComponent<NetworkObject>().Spawn(true);
			}
			else if (_spawned && StartOfRound.Instance.shipIsLeaving)
			{
				_spawned = false;
				_turret.GetComponent<NetworkObject>().Despawn(true);
				ChatUtils.Send("<color=green>Turret removal procedure complete.</color>");
			}
		}

		public void OnEnd(SelectableLevel Level)
		{
			_shouldSpawn = false;
			_spawned = false;
		}
	}
	[UsedImplicitly]
	public class SpringbreakEvent : IEvent
	{
		public string Name => "Springbreak";

		public string Description => "Don't get a concussion!";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Rare;

		public void ExecuteServer(SelectableLevel Level)
		{
			EnemySpawnManager.DraftEnemySpawn<SpringManAI>(new EnemySpawnManager.SpawnInfo(3, Outside: true));
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}
	}
	[UsedImplicitly]
	public class SurfaceExplosionEvent : IEvent
	{
		private static readonly Vector3 MineDistance = new Vector3(9.33f, 5.2f, 1021f);

		private const int StartSpawnInterval = 10;

		private const int MinSpawnInterval = 1;

		private const int MaxSpawnInterval = 4;

		private GameObject _prefab;

		private float _spawnTimer;

		public string Name => "The surface is explosive!";

		public string Description => "EXPLOSION!!!";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Uncommon;

		public void ExecuteServer(SelectableLevel Level)
		{
			_spawnTimer = 10f;
			if (_prefab == null)
			{
				_prefab = Level.FindObjectPrefab<Landmine>();
			}
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}

		public void UpdateServer()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if (StartOfRound.Instance.allPlayersDead)
			{
				return;
			}
			if (_spawnTimer >= 0f)
			{
				_spawnTimer -= Time.deltaTime;
				return;
			}
			_spawnTimer = Random.Range(1, 4);
			if (PlayerUtils.OutsidePlayers.Random(out var Value))
			{
				Vector3 position = ((Component)Value).transform.position;
				if (Vector3.Distance(position, MineDistance) < 1f)
				{
					_spawnTimer = -1f;
				}
				else
				{
					LevelManager.SpawnMapObject<Landmine>(_prefab, position, Quaternion.identity).TriggerMineOnLocalClientByExiting();
				}
			}
		}
	}
	[UsedImplicitly]
	public class TheBeastsInsideEvent : IEvent
	{
		public string Name => "The Beasts Inside";

		public string Description => "Ssshhhh...";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Uncommon;

		public void ExecuteServer(SelectableLevel Level)
		{
			EnemySpawnManager.DraftEnemySpawn<MouthDogAI>(new EnemySpawnManager.SpawnInfo(((Object)Level).name switch
			{
				"ExperimentationLevel" => 2, 
				"AssuranceLevel" => 2, 
				"VowLevel" => 2, 
				"OffenseLevel" => 3, 
				"MarchLevel" => 3, 
				"RendLevel" => 4, 
				"DineLevel" => 4, 
				"TitanLevel" => 6, 
				_ => 4, 
			}));
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}
	}
	[UsedImplicitly]
	[HarmonyPatch]
	public class TheRumblingEvent : IEvent
	{
		private const float NormalSpeed = 6f;

		public string Name => "The Rumbling";

		public string Description => "Fix the Barricades!";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Uncommon;

		public void ExecuteServer(SelectableLevel Level)
		{
			EnemySpawnManager.DraftEnemySpawn<ForestGiantAI>(new EnemySpawnManager.SpawnInfo(((Object)Level).name switch
			{
				"ExperimentationLevel" => 6, 
				"AssuranceLevel" => 8, 
				"VowLevel" => 8, 
				"OffenseLevel" => 8, 
				"MarchLevel" => 8, 
				"RendLevel" => 10, 
				"DineLevel" => 10, 
				"TitanLevel" => 8, 
				_ => 8, 
			}, Outside: true));
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ForestGiantAI), "Update")]
		private static void EnemyAIPatch(ref ForestGiantAI __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner && EventManager.IsActive<TheRumblingEvent>() && ((EnemyAI)__instance).currentBehaviourStateIndex == 1 && !__instance.inEatingPlayerAnimation)
			{
				((EnemyAI)__instance).agent.speed = 6f;
			}
		}
	}
	[UsedImplicitly]
	public class TheyAreShyEvent : IEvent
	{
		public string Name => "Don't look... away?";

		public string Description => "Instructions unclear.";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.Rare;

		public void ExecuteServer(SelectableLevel Level)
		{
			EnemySpawnManager.DraftEnemySpawn<SpringManAI>(new EnemySpawnManager.SpawnInfo(3));
			EnemySpawnManager.DraftEnemySpawn<FlowermanAI>(new EnemySpawnManager.SpawnInfo(3));
			EnemySpawnManager.DraftEnemySpawn<SpringManAI>(new EnemySpawnManager.SpawnInfo(2, Outside: true));
			EnemySpawnManager.DraftEnemySpawn<FlowermanAI>(new EnemySpawnManager.SpawnInfo(3, Outside: true));
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}
	}
	[UsedImplicitly]
	public class UnfairCompanyEvent : IEvent
	{
		private const int OutsideEnemyCount = 3;

		public string Name => "Unfair Company";

		public string Description => "Sometimes, life just ain't fair.";

		public EventPositivity Positivity => EventPositivity.Negative;

		public EventRarity DefaultRarity => EventRarity.VeryRare;

		public void ExecuteServer(SelectableLevel Level)
		{
			for (int i = 0; i < 3; i++)
			{
				if (LevelManager.AllOutsideEnemies.Random(out var Value))
				{
					EnemySpawnManager.DraftEnemySpawn(Value.enemyType, new EnemySpawnManager.SpawnInfo(1, Outside: true));
				}
			}
			LevelManager.ModifyLevelProperties(Level, delegate(SelectableLevel Level)
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Expected O, but got Unknown
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Expected O, but got Unknown
				Level.outsideEnemySpawnChanceThroughDay = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
				{
					new Keyframe(0f, 999f),
					new Keyframe(1f, 999f)
				});
				Level.enemySpawnChanceThroughoutDay = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
				{
					new Keyframe(0f, 500f),
					new Keyframe(1f, 500f)
				});
			}, "outsideEnemySpawnChanceThroughDay", "enemySpawnChanceThroughoutDay");
		}

		public void ExecuteClient(SelectableLevel Level)
		{
		}
	}
}
namespace BrutalCompanyPlus.Config
{
	[AttributeUsage(AttributeTargets.Class)]
	public class ConfigCategory : Attribute
	{
		public readonly string Name;

		public ConfigCategory(string Name)
		{
			this.Name = Name;
		}
	}
	[AttributeUsage(AttributeTargets.Class)]
	public class SharedDescription : Attribute
	{
		public readonly string Template;

		public SharedDescription(string Template)
		{
			this.Template = Template;
		}
	}
	[AttributeUsage(AttributeTargets.Property)]
	public class Configuration : Attribute
	{
		public readonly object DefaultValue;

		internal readonly bool ExcludeFromShared;

		public string Name { get; internal set; }

		public ConfigDescription Description { get; internal set; }

		private Configuration(string Name, ConfigDescription Description, object DefaultValue, bool ExcludeFromShared)
		{
			this.Name = Name;
			this.Description = Description;
			this.DefaultValue = DefaultValue;
			this.ExcludeFromShared = ExcludeFromShared;
		}

		public Configuration(string Description, object DefaultValue, bool ExcludeFromShared = false)
			: this(null, new ConfigDescription(Description, (AcceptableValueBase)null, Array.Empty<object>()), DefaultValue, ExcludeFromShared)
		{
		}//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Expected O, but got Unknown


		public Configuration(string Description, int DefaultValue, int MinValue, int MaxValue, bool ExcludeFromShared = false)
			: this(null, new ConfigDescription(Description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(MinValue, MaxValue), Array.Empty<object>()), DefaultValue, ExcludeFromShared)
		{
		}//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown


		public override string ToString()
		{
			return $"(name: {Name}, description: {Description.Description}, default: {DefaultValue})";
		}
	}
	public static class ConfigLoader
	{
		public static void Bind(Plugin Plugin)
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			foreach (Type type in types)
			{
				if (!type.TryGetAttribute<ConfigCategory>(out var Attribute))
				{
					continue;
				}
				Plugin.Logger.LogDebug((object)("Binding config for " + type.Name + "..."));
				PropertyInfo[] properties = type.GetProperties(BindingFlags.Static | BindingFlags.Public);
				Plugin.Logger.LogDebug((object)$"Found {properties.Length} properties...");
				PropertyInfo[] array = properties;
				foreach (PropertyInfo propertyInfo in array)
				{
					if (!propertyInfo.TryGetAttribute<Configuration>(out var Attribute2))
					{
						continue;
					}
					Plugin.Logger.LogDebug((object)("Binding config for " + propertyInfo.Name + "..."));
					if (string.IsNullOrEmpty(Attribute2.Name))
					{
						Attribute2.Name = propertyInfo.Name;
					}
					if (!Attribute2.ExcludeFromShared && type.TryGetAttribute<SharedDescription>(out var Attribute3))
					{
						Attribute2.Description = new ConfigDescription(Attribute3.Template.Replace("{}", Attribute2.Description.Description), Attribute2.Description.AcceptableValues, Attribute2.Description.Tags);
					}
					if (propertyInfo.TryGetEntryType(out var Type))
					{
						object obj = Convert.ChangeType(Attribute2.DefaultValue, Type);
						Plugin.Logger.LogDebug((object)$"Binding config for {type.Name}/{propertyInfo.Name}: {Attribute2}");
						object value = typeof(ConfigFile).GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo M) => M.Name == "Bind" && M.GetParameters().Length == 4 && M.GetParameters()[3].ParameterType == typeof(ConfigDescription)).MakeGenericMethod(Type)
							.Invoke(((BaseUnityPlugin)Plugin).Config, new object[4] { Attribute.Name, Attribute2.Name, obj, Attribute2.Description });
						propertyInfo.SetValue(null, value);
					}
				}
			}
		}

		private static bool TryGetAttribute<T>(this MemberInfo Member, out T Attribute) where T : Attribute
		{
			object[] customAttributes = Member.GetCustomAttributes(typeof(T), inherit: false);
			if (customAttributes.IsEmpty())
			{
				Attribute = null;
				return false;
			}
			Attribute = (T)customAttributes[0];
			return true;
		}

		private static bool TryGetEntryType(this PropertyInfo Info, out Type Type)
		{
			if (!Info.PropertyType.IsGenericType || Info.PropertyType.GetGenericTypeDefinition() != typeof(ConfigEntry<>))
			{
				Type = null;
				return false;
			}
			Type[] genericArguments = Info.PropertyType.GetGenericArguments();
			if (genericArguments.Length != 1)
			{
				Type = null;
				return false;
			}
			Type = genericArguments[0];
			return true;
		}
	}
	internal static class EventConfig
	{
		private const string Category = "Event Rarities";

		internal static void RegisterWith(BaseUnityPlugin FromPlugin, ref List<IEvent> Events)
		{
			foreach (IEvent Event in Events)
			{
				try
				{
					string text = Event.Name.Replace("'", "");
					EventRegistry.EventRarityValues[Event] = FromPlugin.Config.Bind<EventRarity>("Event Rarities", text, Event.DefaultRarity, Event.Description).Value;
				}
				catch (Exception ex)
				{
					Plugin.Logger.LogError((object)ex.ToString());
					string text2 = ((FromPlugin.Info.Metadata.GUID != "BrutalCompanyPlus") ? (" from " + FromPlugin.Info.Metadata.Name) : "");
					Diagnostics.AddError("Failed to register event \"" + Event.Name + "\"" + text2 + "! See console for details.");
					EventRegistry.EventRarityValues[Event] = Event.DefaultRarity;
				}
			}
		}
	}
	internal static class PluginConfig
	{
		[ConfigCategory("Custom Scrap Values")]
		[SharedDescription("Define min/max scrap pieces and min/max total scrap value for {} (for vanilla, use: -1,-1,-1,-1)")]
		public static class ScrapValues
		{
			public const string DefaultValues = "-1,-1,-1,-1";

			[Configuration("Experimentation", "6,25,400,1500", false)]
			public static ConfigEntry<string> ExperimentationLevel { get; set; }

			[Configuration("Assurance", "10,25,600,2500", false)]
			public static ConfigEntry<string> AssuranceLevel { get; set; }

			[Configuration("Vow", "12,35,600,2500", false)]
			public static ConfigEntry<string> VowLevel { get; set; }

			[Configuration("Offense", "15,35,800,3500", false)]
			public static ConfigEntry<string> OffenseLevel { get; set; }

			[Configuration("March", "15,35,800,3500", false)]
			public static ConfigEntry<string> MarchLevel { get; set; }

			[Configuration("Rend", "20,60,1500,5000", false)]
			public static ConfigEntry<string> RendLevel { get; set; }

			[Configuration("Dine", "20,60,1500,5000", false)]
			public static ConfigEntry<string> DineLevel { get; set; }

			[Configuration("Titan", "20,60,2000,6000", false)]
			public static ConfigEntry<string> TitanLevel { get; set; }

			[Configuration("any custom levels", "20,60,2000,6000", false)]
			public static ConfigEntry<string> CustomLevel { get; set; }
		}

		[ConfigCategory("Moon Heat")]
		public static class MoonHeat
		{
			[Configuration("Rate at which the moon heat increases by when landing back on the same planet", 20f, false)]
			public static ConfigEntry<float> IncreaseRate { get; set; }

			[Configuration("Rate at which the moon heat decreases by when not visiting the planet", 10f, false)]
			public static ConfigEntry<float> DecreaseRate { get; set; }

			[Configuration("Defines how moon heat affects the weather (format: `start:end:type`, start is inclusive and end is exclusive)", "20:40:Rainy,40:60:Foggy,60:80:Flooded,80:100:Stormy,100:101:Eclipsed", false)]
			public static ConfigEntry<string> HeatCurve { get; set; }
		}

		[ConfigCategory("Map Hazard Adjustments")]
		public static class MapHazards
		{
			[Configuration("Amount of turrets that should be spawned (for vanilla, use: -1)", 8, false)]
			public static ConfigEntry<int> TurretSpawnRate { get; set; }

			[Configuration("Amount of landmines that should be spawned (for vanilla, use: -1)", 30, false)]
			public static ConfigEntry<int> LandmineSpawnRate { get; set; }
		}

		[ConfigCategory("Enemy Rarity Values")]
		[SharedDescription("Define custom enemy rarity values for {} (no spawn: 0, max chance: 100, BCP default: -1)")]
		public static class EnemyRarityValues
		{
			private const string DefaultRarity = "Centipede:-1,Bunker Spider:-1,Hoarding bug:-1,Flowerman:-1,Crawler:-1,Blob:-1,Girl:-1,Puffer:-1,Nutcracker:-1,Spring:-1,Jester:-1,Masked:-1,Lasso:-1";

			[Configuration("Set this to `false` if you want vanilla spawning behavior.", true, true)]
			public static ConfigEntry<bool> Enabled { get; set; }

			[Configuration("Experimentation", "Centipede:-1,Bunker Spider:-1,Hoarding bug:-1,Flowerman:-1,Crawler:-1,Blob:-1,Girl:-1,Puffer:-1,Nutcracker:-1,Spring:-1,Jester:-1,Masked:-1,Lasso:-1", false)]
			public static ConfigEntry<string> ExperimentationLevel { get; set; }

			[Configuration("Assurance", "Centipede:-1,Bunker Spider:-1,Hoarding bug:-1,Flowerman:-1,Crawler:-1,Blob:-1,Girl:-1,Puffer:-1,Nutcracker:-1,Spring:-1,Jester:-1,Masked:-1,Lasso:-1", false)]
			public static ConfigEntry<string> AssuranceLevel { get; set; }

			[Configuration("Vow", "Centipede:-1,Bunker Spider:-1,Hoarding bug:-1,Flowerman:-1,Crawler:-1,Blob:-1,Girl:-1,Puffer:-1,Nutcracker:-1,Spring:-1,Jester:-1,Masked:-1,Lasso:-1", false)]
			public static ConfigEntry<string> VowLevel { get; set; }

			[Configuration("Offense", "Centipede:-1,Bunker Spider:-1,Hoarding bug:-1,Flowerman:-1,Crawler:-1,Blob:-1,Girl:-1,Puffer:-1,Nutcracker:-1,Spring:-1,Jester:-1,Masked:-1,Lasso:-1", false)]
			public static ConfigEntry<string> OffenseLevel { get; set; }

			[Configuration("March", "Centipede:-1,Bunker Spider:-1,Hoarding bug:-1,Flowerman:-1,Crawler:-1,Blob:-1,Girl:-1,Puffer:-1,Nutcracker:-1,Spring:-1,Jester:-1,Masked:-1,Lasso:-1", false)]
			public static ConfigEntry<string> MarchLevel { get; set; }

			[Configuration("Rend", "Centipede:-1,Bunker Spider:-1,Hoarding bug:-1,Flowerman:-1,Crawler:-1,Blob:-1,Girl:-1,Puffer:-1,Nutcracker:-1,Spring:-1,Jester:-1,Masked:-1,Lasso:-1", false)]
			public static ConfigEntry<string> RendLevel { get; set; }

			[Configuration("Dine", "Centipede:-1,Bunker Spider:-1,Hoarding bug:-1,Flowerman:-1,Crawler:-1,Blob:-1,Girl:-1,Puffer:-1,Nutcracker:-1,Spring:-1,Jester:-1,Masked:-1,Lasso:-1", false)]
			public static ConfigEntry<string> DineLevel { get; set; }

			[Configuration("Titan", "Centipede:-1,Bunker Spider:-1,Hoarding bug:-1,Flowerman:-1,Crawler:-1,Blob:-1,Girl:-1,Puffer:-1,Nutcracker:-1,Spring:-1,Jester:-1,Masked:-1,Lasso:-1", false)]
			public static ConfigEntry<string> TitanLevel { get; set; }

			[Configuration("any custom levels", "Centipede:-1,Bunker Spider:-1,Hoarding bug:-1,Flowerman:-1,Crawler:-1,Blob:-1,Girl:-1,Puffer:-1,Nutcracker:-1,Spring:-1,Jester:-1,Masked:-1,Lasso:-1", false)]
			public static ConfigEntry<string> CustomLevel { get; set; }
		}

		[ConfigCategory("Credits-related Adjustments")]
		public static class CreditsAdjustments
		{
			[Configuration("Amount of money to give when a player leaves a moon alive (to disable, use: -1)", 150, false)]
			public static ConfigEntry<int> FreeMoneyAmount { get; set; }
		}

		[ConfigCategory("Enemy-related Adjustments")]
		public static class EnemyAdjustments
		{
			[Configuration("Whether all enemies should be nominated for spawning on all moons (vanilla: false)", true, false)]
			public static ConfigEntry<bool> SpawnOnAllMoons { get; set; }
		}

		[ConfigCategory("Quota-related Adjustments")]
		public static class QuotaAdjustments
		{
			[Configuration("Days available before deadline (for vanilla, use: -1)", 4, false)]
			public static ConfigEntry<int> DeadlineDays { get; set; }

			[Configuration("Amount of credits everyone gets at the start of a new session (for vanilla, use: -1)", 200, false)]
			public static ConfigEntry<int> StartingCredits { get; set; }

			[Configuration("Quota you begin with at the start of a new session (for vanilla, use: -1)", 400, false)]
			public static ConfigEntry<int> StartingQuota { get; set; }

			[Configuration("Rate at which the quota increases by when it's met (for vanilla, use: -1)", 275, false)]
			public static ConfigEntry<int> BaseIncrease { get; set; }
		}

		[ConfigCategory("Event Settings")]
		public static class EventSettings
		{
			[Configuration("Chance between 0 and 100 for an event to occur (this is separate from event rarity and no events may still occur even if the chance is met!)", 100, 0, 100, false)]
			public static ConfigEntry<int> GlobalChance { get; set; }

			[Configuration("Whether all events have equal chance to happen (disables event rarity altogether!)", false, false)]
			public static ConfigEntry<bool> EqualChance { get; set; }
		}

		internal static void Bind(Plugin Plugin)
		{
			ConfigLoader.Bind(Plugin);
			Validate();
		}

		private static void Validate()
		{
			LevelNames.AllCustom.ForEach(ConfigUtils.GetEnemyRarityValues);
			LevelNames.AllCustom.ForEach(ConfigUtils.GetScrapValues);
			ConfigUtils.GetMoonHeatCurve();
		}
	}
}
namespace BrutalCompanyPlus.Api
{
	public static class EventRegistry
	{
		private static readonly List<IEvent> RegisteredEvents = new List<IEvent>();

		internal static readonly Dictionary<IEvent, EventRarity> EventRarityValues = new Dictionary<IEvent, EventRarity>();

		[UsedImplicitly]
		public static void RegisterEvents(BaseUnityPlugin FromPlugin, List<IEvent> Events)
		{
			EventConfig.RegisterWith(FromPlugin, ref Events);
			RegisteredEvents.AddRange(Events);
			Plugin.Logger.LogWarning((object)$"Registered {Events.Count} events from {FromPlugin.Info.Metadata.Name}:");
			foreach (IEvent Event in Events)
			{
				Plugin.Logger.LogWarning((object)$"Registered event: {Event.Name} (rarity: {Event.GetRarity()}, description: {Event.Description})");
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void AutoRegister(BaseUnityPlugin FromPlugin)
		{
			IEnumerable<IEvent> source = from type in Assembly.GetCallingAssembly().GetTypes()
				where type.IsClass && typeof(IEvent).IsAssignableFrom(type)
				select (IEvent)Activator.CreateInstance(type);
			RegisterEvents(FromPlugin, source.ToList());
		}

		public static T GetEvent<T>() where T : IEvent
		{
			return (T)(RegisteredEvents.FirstOrDefault((IEvent Event) => Event is T) ?? ((object)default(T)));
		}

		public static IEvent GetEvent(int EventId)
		{
			return RegisteredEvents.ElementAtOrDefault(EventId);
		}

		private static EventRarity GetRarity(this IEvent Event)
		{
			return EventRarityValues[Event];
		}

		public static int GetId(this IEvent Event)
		{
			return RegisteredEvents.IndexOf(Event);
		}

		public static bool IsActive(this IEvent Event)
		{
			return EventManager.CurrentEvent == Event;
		}

		internal static IEvent GetRandomEvent()
		{
			int num = RegisteredEvents.Sum((IEvent Event) => (int)Event.GetRarity());
			int num2 = Random.Range(0, num);
			foreach (IEvent registeredEvent in RegisteredEvents)
			{
				num2 = (int)(num2 - registeredEvent.GetRarity());
				if (num2 <= 0)
				{
					return registeredEvent;
				}
			}
			Plugin.Logger.LogFatal((object)$"Failed to get random event! (totalRarity: {num}, random: {num2})");
			return GetEvent<NoneEvent>();
		}

		internal static IEvent GetRandomEventWithoutRarity()
		{
			if (RegisteredEvents.Where((IEvent Event) => Event.GetRarity() != EventRarity.Disabled).Random(out var Value))
			{
				return Value;
			}
			Plugin.Logger.LogFatal((object)"Failed to get random event! (without rarity)");
			return GetEvent<NoneEvent>();
		}
	}
	public interface IEvent
	{
		string Name { get; }

		string Description { get; }

		EventPositivity Positivity { get; }

		EventRarity DefaultRarity { get; }

		bool CanRun([UsedImplicitly] SelectableLevel Level)
		{
			return true;
		}

		void ExecuteServer([UsedImplicitly] SelectableLevel Level);

		void ExecuteClient([UsedImplicitly] SelectableLevel Level);

		void UpdateServer()
		{
		}

		void OnEnd([UsedImplicitly] SelectableLevel Level)
		{
		}
	}
	public enum EventPositivity
	{
		Positive,
		Neutral,
		Negative,
		Golden
	}
	public enum EventRarity
	{
		[Obsolete("For configuration purposes only. Do not use.")]
		Disabled = 0,
		Common = 100,
		Uncommon = 85,
		Rare = 60,
		VeryRare = 40,
		UltraRare = 20
	}
	public static class EventExtensions
	{
		public static void Log(this IEvent Event, string Message)
		{
			Plugin.Logger.LogInfo((object)("[Event (" + Event.Name + ")] " + Message));
		}
	}
}