Decompiled source of HullBreaker Company Ambigous Fork v2.1.0

BepInEx/plugins/HullBreakerCompany.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using FacilityMeltdown.API;
using GameNetcodeStuff;
using HarmonyLib;
using HullBreakerCompany.Events;
using HullBreakerCompany.Events.Enemy;
using HullBreakerCompany.Events.Misc;
using HullBreakerCompany.Events.Scrap;
using HullBreakerCompany.Hull;
using LethalQuantities.Objects;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HullBreakerCompany")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Making it more challenging to work for the company")]
[assembly: AssemblyFileVersion("2.1.0.0")]
[assembly: AssemblyInformationalVersion("2.1.0+baa2b2bc924e5b00208c5b4de959e896c1369533")]
[assembly: AssemblyProduct("HullBreakerCompany")]
[assembly: AssemblyTitle("HullBreakerCompany")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HullBreakerCompany
{
	public class LevelModifier
	{
		private SelectableLevel targetLevel;

		private readonly Dictionary<string, int> enemyComponentRarityModifications;

		private readonly Dictionary<string, int> enemyComponentRarityBackups;

		private readonly Dictionary<string, int> enemyComponentMaxCountModifications;

		private readonly Dictionary<string, int> enemyComponentMaxCountBackups;

		private readonly Dictionary<string, int> enemyComponentPowerModifications;

		private readonly Dictionary<string, int> enemyComponentPowerBackups;

		private int targetLevelEnemyRarityTotal;

		private readonly Dictionary<string, int> outsideEnemyComponentRarityModifications;

		private readonly Dictionary<string, int> outsideEnemyComponentRarityBackups;

		private readonly Dictionary<string, int> daytimeEnemyComponentRarityModifications;

		private readonly Dictionary<string, int> daytimeEnemyComponentRarityBackups;

		private readonly Dictionary<string, int> spawnableScrapRarityModifications;

		private readonly Dictionary<string, int> spawnableScrapRarityBackups;

		private int targetLevelScrapRarityTotal;

		private int maxEnemyPower;

		private int maxOutsideEnemyPower;

		private int maxDaytimeEnemyPower;

		private int enemySpawnChanceThroughoutDay;

		private AnimationCurve enemySpawnChanceThroghoutDayBackup;

		private int outsideEnemySpawnChanceThroughoutDay;

		private AnimationCurve outsideEnemySpawnChanceThroghoutDayBackup;

		private int daytimeEnemySpawnChanceThroughoutDay;

		private AnimationCurve daytimeEnemySpawnChanceThroghoutDayBackup;

		private float landmines;

		private AnimationCurve landminesBackup;

		private float turrets;

		private AnimationCurve turretsBackup;

		private float timeScale;

		public LevelModifier(SelectableLevel level)
		{
			targetLevel = level;
			enemyComponentRarityModifications = new Dictionary<string, int>();
			enemyComponentRarityBackups = new Dictionary<string, int>();
			enemyComponentMaxCountModifications = new Dictionary<string, int>();
			enemyComponentMaxCountBackups = new Dictionary<string, int>();
			enemyComponentPowerModifications = new Dictionary<string, int>();
			enemyComponentPowerBackups = new Dictionary<string, int>();
			targetLevelEnemyRarityTotal = 0;
			outsideEnemyComponentRarityModifications = new Dictionary<string, int>();
			outsideEnemyComponentRarityBackups = new Dictionary<string, int>();
			daytimeEnemyComponentRarityModifications = new Dictionary<string, int>();
			daytimeEnemyComponentRarityBackups = new Dictionary<string, int>();
			spawnableScrapRarityModifications = new Dictionary<string, int>();
			spawnableScrapRarityBackups = new Dictionary<string, int>();
			targetLevelScrapRarityTotal = 0;
			timeScale = 0f;
			base..ctor();
		}

		private void OnSceneUnloaded(Scene scene)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Mls.LogInfo((object)("Unloading scene: " + ((Scene)(ref scene)).name));
			SelectableLevel currentLevel = RoundManager.Instance.currentLevel;
			if ((Object)(object)currentLevel == (Object)null)
			{
				Plugin.Mls.LogInfo((object)"Scene does not contain a level!");
				return;
			}
			if (currentLevel.levelID == 3)
			{
				Plugin.Mls.LogInfo((object)"Scene contains company building level!");
				return;
			}
			if ((Object)(object)currentLevel != (Object)(object)targetLevel)
			{
				Plugin.Mls.LogWarning((object)("currentLevel (" + currentLevel.PlanetName + ") levelModifier (" + targetLevel.PlanetName + ") mismatch!"));
				return;
			}
			List<string> source = new List<string>(3) { "MainMenu", "InitScene", "SampleSceneRelay" };
			if (source.Any((string str) => str == ((Scene)(ref scene)).name))
			{
				Plugin.Mls.LogInfo((object)"Ignoring scene. Not reverting any modifications!");
				return;
			}
			UndoModifications();
			EventsHandler.Reset();
		}

		private void ApplyEnemyComponentRarity(SelectableLevel level, Dictionary<string, int> rarityPairs, Dictionary<string, int> rarityBackups, bool restore = false)
		{
			if (rarityPairs.Count <= 0)
			{
				return;
			}
			if (targetLevelEnemyRarityTotal == 0)
			{
				targetLevelEnemyRarityTotal = level.Enemies.Sum((SpawnableEnemyWithRarity enemy) => enemy.rarity);
			}
			foreach (KeyValuePair<string, int> rarityPair in rarityPairs)
			{
				using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = level.Enemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name == rarityPair.Key).GetEnumerator();
				if (enumerator2.MoveNext())
				{
					SpawnableEnemyWithRarity current = enumerator2.Current;
					if (restore)
					{
						current.rarity = rarityBackups[rarityPair.Key];
					}
					else
					{
						rarityBackups.TryAdd(rarityPair.Key, current.rarity);
						current.rarity = (int)Math.Floor((float)rarityPair.Value / 100f * (float)(targetLevelEnemyRarityTotal - current.rarity));
					}
					Plugin.Mls.LogInfo((object)$"Setting rarity of {((Object)current.enemyType.enemyPrefab).name} to {current.rarity}");
				}
			}
		}

		private void ApplyEnemyComponentMaxCount(SelectableLevel level, Dictionary<string, int> maxCountPairs, Dictionary<string, int> maxCountBackups, bool restore = false)
		{
			if (maxCountPairs.Count <= 0)
			{
				return;
			}
			foreach (KeyValuePair<string, int> maxCountPair in maxCountPairs)
			{
				using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = level.Enemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name == maxCountPair.Key).GetEnumerator();
				if (enumerator2.MoveNext())
				{
					SpawnableEnemyWithRarity current = enumerator2.Current;
					if (!restore)
					{
						maxCountBackups.TryAdd(maxCountPair.Key, current.enemyType.MaxCount);
					}
					current.enemyType.MaxCount = (restore ? maxCountBackups[maxCountPair.Key] : maxCountPair.Value);
					Plugin.Mls.LogInfo((object)$"Setting maxCount of {((Object)current.enemyType.enemyPrefab).name} to {current.enemyType.MaxCount}");
				}
			}
		}

		private void ApplyEnemyComponentPower(SelectableLevel level, Dictionary<string, int> powerPairs, Dictionary<string, int> powerBackups, bool restore = false)
		{
			if (powerPairs.Count <= 0)
			{
				return;
			}
			foreach (KeyValuePair<string, int> powerPair in powerPairs)
			{
				using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = level.Enemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name == powerPair.Key).GetEnumerator();
				if (enumerator2.MoveNext())
				{
					SpawnableEnemyWithRarity current = enumerator2.Current;
					if (!restore)
					{
						powerBackups.TryAdd(powerPair.Key, (int)Math.Round(current.enemyType.PowerLevel));
					}
					current.enemyType.PowerLevel = (restore ? powerBackups[powerPair.Key] : powerPair.Value);
					Plugin.Mls.LogInfo((object)$"Setting power of {((Object)current.enemyType.enemyPrefab).name} to {current.enemyType.PowerLevel}");
				}
			}
		}

		private void ApplyOutsideEnemyComponentRarity(SelectableLevel level, Dictionary<string, int> rarityPairs, Dictionary<string, int> rarityBackups, bool restore = false)
		{
			if (rarityPairs.Count <= 0)
			{
				return;
			}
			foreach (KeyValuePair<string, int> rarityPair in rarityPairs)
			{
				using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = level.OutsideEnemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name == rarityPair.Key).GetEnumerator();
				if (enumerator2.MoveNext())
				{
					SpawnableEnemyWithRarity current = enumerator2.Current;
					if (!restore)
					{
						rarityBackups.TryAdd(rarityPair.Key, current.rarity);
					}
					current.rarity = (restore ? rarityBackups[rarityPair.Key] : rarityPair.Value);
					Plugin.Mls.LogInfo((object)$"Setting rarity of {((Object)current.enemyType.enemyPrefab).name} to {current.rarity}");
				}
			}
		}

		private void ApplyDaytimeEnemyComponentRarity(SelectableLevel level, Dictionary<string, int> rarityPairs, Dictionary<string, int> rarityBackups, bool restore = false)
		{
			if (rarityPairs.Count <= 0)
			{
				return;
			}
			foreach (KeyValuePair<string, int> rarityPair in rarityPairs)
			{
				using IEnumerator<SpawnableEnemyWithRarity> enumerator2 = level.DaytimeEnemies.Where((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType.enemyPrefab).name == rarityPair.Key).GetEnumerator();
				if (enumerator2.MoveNext())
				{
					SpawnableEnemyWithRarity current = enumerator2.Current;
					if (!restore)
					{
						rarityBackups.TryAdd(rarityPair.Key, current.rarity);
					}
					current.rarity = (restore ? rarityBackups[rarityPair.Key] : rarityPair.Value);
					Plugin.Mls.LogInfo((object)$"Setting rarity of {((Object)current.enemyType.enemyPrefab).name} to {current.rarity}");
				}
			}
		}

		private void ApplyLootRarity(SelectableLevel level, Dictionary<string, int> rarityPairs, Dictionary<string, int> rarityBackups, bool restore = false)
		{
			if (rarityPairs.Count <= 0)
			{
				return;
			}
			if (targetLevelScrapRarityTotal == 0)
			{
				targetLevelScrapRarityTotal = level.spawnableScrap.Sum((SpawnableItemWithRarity scrap) => scrap.rarity);
			}
			foreach (KeyValuePair<string, int> rarityPair in rarityPairs)
			{
				using IEnumerator<SpawnableItemWithRarity> enumerator2 = level.spawnableScrap.Where((SpawnableItemWithRarity item) => item.spawnableItem.itemName == rarityPair.Key).GetEnumerator();
				if (enumerator2.MoveNext())
				{
					SpawnableItemWithRarity current = enumerator2.Current;
					if (restore)
					{
						current.rarity = rarityBackups[rarityPair.Key];
					}
					else
					{
						rarityBackups.TryAdd(rarityPair.Key, current.rarity);
						current.rarity = (int)Math.Floor((float)rarityPair.Value / 100f * (float)(targetLevelScrapRarityTotal - current.rarity));
					}
					Plugin.Mls.LogInfo((object)$"Setting rarity of {current.spawnableItem.itemName} to {current.rarity}");
				}
			}
		}

		private void ApplyMaxEnemyPower(SelectableLevel level, int power, bool restore = false)
		{
			if (power > 0)
			{
				if (!restore)
				{
					maxEnemyPower = level.maxEnemyPowerCount;
				}
				level.maxEnemyPowerCount = (restore ? power : (level.maxEnemyPowerCount + power));
				Plugin.Mls.LogInfo((object)$"Setting global max enemy power to {level.maxEnemyPowerCount}");
			}
		}

		private void ApplyMaxOutsideEnemyPower(SelectableLevel level, int power, bool restore = false)
		{
			if (power > 0)
			{
				if (!restore)
				{
					maxOutsideEnemyPower = level.maxOutsideEnemyPowerCount;
				}
				level.maxOutsideEnemyPowerCount = (restore ? power : (level.maxOutsideEnemyPowerCount + power));
				Plugin.Mls.LogInfo((object)$"Setting global max enemy power to {level.maxOutsideEnemyPowerCount}");
			}
		}

		private void ApplyMaxDaytimeEnemyPower(SelectableLevel level, int power, bool restore = false)
		{
			if (power > 0)
			{
				if (!restore)
				{
					maxDaytimeEnemyPower = level.maxDaytimeEnemyPowerCount;
				}
				level.maxDaytimeEnemyPowerCount = (restore ? power : (level.maxDaytimeEnemyPowerCount + power));
				Plugin.Mls.LogInfo((object)$"Setting global max enemy power to {level.maxDaytimeEnemyPowerCount}");
			}
		}

		private void ApplyEnemySpawnChanceThroughoutDay(SelectableLevel level, int value, bool revert = false)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0047: Expected O, but got Unknown
			if (value > 0)
			{
				if (!revert)
				{
					enemySpawnChanceThroghoutDayBackup = level.enemySpawnChanceThroughoutDay;
					level.enemySpawnChanceThroughoutDay = new AnimationCurve((Keyframe[])(object)new Keyframe[1]
					{
						new Keyframe(0f, (float)value)
					});
					Plugin.Mls.LogInfo((object)$"Setting global enemy spawn chance to {value}");
				}
				else
				{
					level.enemySpawnChanceThroughoutDay = enemySpawnChanceThroghoutDayBackup;
					Plugin.Mls.LogInfo((object)"Reverting global enemy spawn chance");
				}
			}
		}

		private void ApplyOutsideEnemySpawnChanceThroughoutDay(SelectableLevel level, int value, bool revert = false)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0047: Expected O, but got Unknown
			if (value > 0)
			{
				if (!revert)
				{
					outsideEnemySpawnChanceThroghoutDayBackup = level.outsideEnemySpawnChanceThroughDay;
					level.outsideEnemySpawnChanceThroughDay = new AnimationCurve((Keyframe[])(object)new Keyframe[1]
					{
						new Keyframe(0f, (float)value)
					});
					Plugin.Mls.LogInfo((object)$"Setting global outside enemy spawn chance to {value}");
				}
				else
				{
					level.outsideEnemySpawnChanceThroughDay = outsideEnemySpawnChanceThroghoutDayBackup;
					Plugin.Mls.LogInfo((object)"Reverting global outside enemy spawn chance");
				}
			}
		}

		private void ApplyDaytimeEnemySpawnChanceThroughoutDay(SelectableLevel level, int value, bool revert = false)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0047: Expected O, but got Unknown
			if (value > 0)
			{
				if (!revert)
				{
					daytimeEnemySpawnChanceThroghoutDayBackup = level.daytimeEnemySpawnChanceThroughDay;
					level.daytimeEnemySpawnChanceThroughDay = new AnimationCurve((Keyframe[])(object)new Keyframe[1]
					{
						new Keyframe(0f, (float)value)
					});
					Plugin.Mls.LogInfo((object)$"Setting global daytime enemy spawn chance to {value}");
				}
				else
				{
					level.daytimeEnemySpawnChanceThroughDay = daytimeEnemySpawnChanceThroghoutDayBackup;
					Plugin.Mls.LogInfo((object)"Reverting global daytime enemy spawn chance");
				}
			}
		}

		private void ApplyTimeScale(SelectableLevel level, float value, bool revert = false)
		{
			if (value != 0f)
			{
				if (!revert)
				{
					TimeOfDay instance = TimeOfDay.Instance;
					instance.globalTimeSpeedMultiplier *= value;
					Plugin.Mls.LogInfo((object)$"Increasing TimeSpeedMultiplier: Timescale {(int)Math.Round(value * 100f)}%");
				}
				else
				{
					TimeOfDay instance2 = TimeOfDay.Instance;
					instance2.globalTimeSpeedMultiplier /= value;
					Plugin.Mls.LogInfo((object)$"Decreasing TimeSpeedMultiplier: Timescale {(int)Math.Round(value * 100f)}%");
				}
			}
		}

		public void ApplyUnitModifications(SelectableLevel level, float landmineAmount, float turretAmount)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			if (landmineAmount > 0f)
			{
				Plugin.Mls.LogInfo((object)$"Adding Landmines: {landmineAmount}");
				SpawnableMapObject[] spawnableMapObjects = level.spawnableMapObjects;
				foreach (SpawnableMapObject val in spawnableMapObjects)
				{
					if ((Object)(object)val.prefabToSpawn.GetComponentInChildren<Landmine>() != (Object)null)
					{
						landminesBackup = val.numberToSpawn;
						val.numberToSpawn = new AnimationCurve((Keyframe[])(object)new Keyframe[1]
						{
							new Keyframe(0f, landmineAmount)
						});
					}
				}
			}
			if (!(turretAmount > 0f))
			{
				return;
			}
			Plugin.Mls.LogInfo((object)$"Adding Turrets: {turretAmount}");
			SpawnableMapObject[] spawnableMapObjects2 = level.spawnableMapObjects;
			foreach (SpawnableMapObject val2 in spawnableMapObjects2)
			{
				if ((Object)(object)val2.prefabToSpawn.GetComponentInChildren<Turret>() != (Object)null)
				{
					turretsBackup = val2.numberToSpawn;
					val2.numberToSpawn = new AnimationCurve((Keyframe[])(object)new Keyframe[1]
					{
						new Keyframe(0f, turretAmount)
					});
				}
			}
		}

		private void UndoUnitModifications(SelectableLevel level)
		{
			SpawnableMapObject[] spawnableMapObjects = level.spawnableMapObjects;
			foreach (SpawnableMapObject val in spawnableMapObjects)
			{
				if ((Object)(object)val.prefabToSpawn.GetComponentInChildren<Landmine>() != (Object)null && landminesBackup != null)
				{
					val.numberToSpawn = landminesBackup;
					Plugin.Mls.LogInfo((object)"Reverting added landmines");
				}
				if ((Object)(object)val.prefabToSpawn.GetComponentInChildren<Turret>() != (Object)null && turretsBackup != null)
				{
					val.numberToSpawn = turretsBackup;
					Plugin.Mls.LogInfo((object)"Reverting added turrets");
				}
			}
		}

		private bool IsTargetLevelSet()
		{
			if ((Object)(object)targetLevel == (Object)null)
			{
				Plugin.Mls.LogWarning((object)"Target level not set!");
				return false;
			}
			return true;
		}

		public void AddEnemyComponentRarity(string enemy, int percentOfTotalRarity)
		{
			enemyComponentRarityModifications.TryAdd(enemy, percentOfTotalRarity);
		}

		public void AddEnemyComponentMaxCount(string enemy, int maxCount)
		{
			enemyComponentMaxCountModifications.TryAdd(enemy, maxCount);
		}

		public void AddEnemyComponentPower(string enemy, int power)
		{
			enemyComponentPowerModifications.TryAdd(enemy, power);
		}

		public void AddDaytimeEnemyRarity(string enemy, int rarity)
		{
			daytimeEnemyComponentRarityModifications.TryAdd(enemy, rarity);
		}

		public void AddOutsideEnemyRarity(string enemy, int rarity)
		{
			outsideEnemyComponentRarityModifications.TryAdd(enemy, rarity);
		}

		public void AddSpawnableScrapRarity(string item, int percentOfTotalRarity)
		{
			spawnableScrapRarityModifications.TryAdd(item, percentOfTotalRarity);
		}

		public void AddSpawnableScrapRarityDict(Dictionary<string, int> scrapToSpawn)
		{
			foreach (KeyValuePair<string, int> item in scrapToSpawn)
			{
				AddSpawnableScrapRarity(item.Key, item.Value);
			}
		}

		public void AddMaxEnemyPower(int power)
		{
			maxEnemyPower = power;
		}

		public void AddMaxOutsideEnemyPower(int power)
		{
			maxOutsideEnemyPower = power;
		}

		public void AddMaxDaytimeEnemyPower(int power)
		{
			maxDaytimeEnemyPower = power;
		}

		public void AddEnemySpawnChanceThroughoutDay(int value)
		{
			enemySpawnChanceThroughoutDay += value;
		}

		public void AddOutsideEnemySpawnChanceThroughoutDay(int value)
		{
			outsideEnemySpawnChanceThroughoutDay += value;
		}

		public void AddDaytimeEnemySpawnChanceThroughoutDay(int value)
		{
			daytimeEnemySpawnChanceThroughoutDay += value;
		}

		public void AddLandmines(float amount)
		{
			landmines += amount;
		}

		public void AddTurrets(float amount)
		{
			turrets += amount;
		}

		public bool SetTimeScale(float value)
		{
			if (timeScale != 0f)
			{
				throw new Exception("Timescale already set!");
			}
			timeScale = value;
			return true;
		}

		public void ApplyModificationsToLevel()
		{
			if (IsTargetLevelSet())
			{
				HullManager.LogBox("APPLYING LEVEL MODIFICATIONS");
				ApplyEnemyComponentRarity(targetLevel, enemyComponentRarityModifications, enemyComponentRarityBackups);
				ApplyEnemyComponentMaxCount(targetLevel, enemyComponentMaxCountModifications, enemyComponentMaxCountBackups);
				ApplyEnemyComponentPower(targetLevel, enemyComponentPowerModifications, enemyComponentPowerBackups);
				ApplyEnemySpawnChanceThroughoutDay(targetLevel, enemySpawnChanceThroughoutDay);
				ApplyOutsideEnemyComponentRarity(targetLevel, outsideEnemyComponentRarityModifications, outsideEnemyComponentRarityBackups);
				ApplyOutsideEnemySpawnChanceThroughoutDay(targetLevel, outsideEnemySpawnChanceThroughoutDay);
				ApplyDaytimeEnemyComponentRarity(targetLevel, daytimeEnemyComponentRarityModifications, daytimeEnemyComponentRarityBackups);
				ApplyDaytimeEnemySpawnChanceThroughoutDay(targetLevel, daytimeEnemySpawnChanceThroughoutDay);
				ApplyLootRarity(targetLevel, spawnableScrapRarityModifications, spawnableScrapRarityBackups);
				ApplyMaxEnemyPower(targetLevel, maxEnemyPower);
				ApplyMaxOutsideEnemyPower(targetLevel, maxOutsideEnemyPower);
				ApplyMaxDaytimeEnemyPower(targetLevel, maxDaytimeEnemyPower);
				ApplyTimeScale(targetLevel, timeScale);
				ApplyUnitModifications(targetLevel, landmines, turrets);
				SceneManager.sceneUnloaded += OnSceneUnloaded;
			}
		}

		public void UndoModifications()
		{
			if (IsTargetLevelSet())
			{
				HullManager.LogBox("REVERTING LEVEL MODIFICATIONS");
				Plugin.Mls.LogInfo((object)("Reverting all modifications to " + targetLevel.PlanetName + "!"));
				ApplyEnemyComponentRarity(targetLevel, enemyComponentRarityModifications, enemyComponentRarityBackups, restore: true);
				ApplyEnemyComponentMaxCount(targetLevel, enemyComponentMaxCountModifications, enemyComponentMaxCountBackups, restore: true);
				ApplyEnemyComponentPower(targetLevel, enemyComponentPowerModifications, enemyComponentPowerBackups, restore: true);
				ApplyEnemySpawnChanceThroughoutDay(targetLevel, enemySpawnChanceThroughoutDay, revert: true);
				ApplyOutsideEnemyComponentRarity(targetLevel, outsideEnemyComponentRarityModifications, outsideEnemyComponentRarityBackups, restore: true);
				ApplyOutsideEnemySpawnChanceThroughoutDay(targetLevel, outsideEnemySpawnChanceThroughoutDay, revert: true);
				ApplyDaytimeEnemyComponentRarity(targetLevel, daytimeEnemyComponentRarityModifications, daytimeEnemyComponentRarityBackups, restore: true);
				ApplyDaytimeEnemySpawnChanceThroughoutDay(targetLevel, daytimeEnemySpawnChanceThroughoutDay, revert: true);
				ApplyLootRarity(targetLevel, spawnableScrapRarityModifications, spawnableScrapRarityBackups, restore: true);
				ApplyMaxEnemyPower(targetLevel, maxEnemyPower, restore: true);
				ApplyMaxOutsideEnemyPower(targetLevel, maxOutsideEnemyPower, restore: true);
				ApplyMaxDaytimeEnemyPower(targetLevel, maxDaytimeEnemyPower, restore: true);
				ApplyTimeScale(targetLevel, timeScale, revert: true);
				UndoUnitModifications(targetLevel);
				SceneManager.sceneUnloaded -= OnSceneUnloaded;
			}
		}

		public bool IsEnemySpawnable(string enemyName)
		{
			if (!IsTargetLevelSet())
			{
				return false;
			}
			if (targetLevel.Enemies.Any((SpawnableEnemyWithRarity unit) => ((Object)unit.enemyType.enemyPrefab).name.Equals(enemyName)))
			{
				return true;
			}
			Plugin.Mls.LogWarning((object)("Can't spawn enemy " + enemyName + " on this moon."));
			return false;
		}

		public bool IsOutsideEnemySpawnable(string enemyName)
		{
			if (!IsTargetLevelSet())
			{
				return false;
			}
			if (targetLevel.OutsideEnemies.Any((SpawnableEnemyWithRarity unit) => ((Object)unit.enemyType.enemyPrefab).name.Equals(enemyName)))
			{
				return true;
			}
			Plugin.Mls.LogWarning((object)("Can't spawn outside " + enemyName + " on this moon."));
			return false;
		}

		public bool IsDaytimeEnemySpawnable(string enemyName)
		{
			if (!IsTargetLevelSet())
			{
				return false;
			}
			if (targetLevel.DaytimeEnemies.Any((SpawnableEnemyWithRarity unit) => ((Object)unit.enemyType.enemyPrefab).name.Equals(enemyName)))
			{
				return true;
			}
			Plugin.Mls.LogWarning((object)("Can't spawn daytime enemy " + enemyName + " on this moon."));
			return false;
		}

		public bool IsScrapSpawnable(string itemName)
		{
			if (!IsTargetLevelSet())
			{
				return false;
			}
			if (targetLevel.spawnableScrap.Any((SpawnableItemWithRarity item) => item.spawnableItem.itemName.Equals(itemName)))
			{
				return true;
			}
			Plugin.Mls.LogWarning((object)("Can't spawn scrap " + itemName + " on this moon."));
			return false;
		}

		public void undoModificationsEarly()
		{
			SelectableLevel currentLevel = RoundManager.Instance.currentLevel;
			if ((Object)(object)currentLevel == (Object)null)
			{
				Plugin.Mls.LogInfo((object)"Scene does not contain a level!");
			}
			else if (currentLevel.levelID == 3)
			{
				Plugin.Mls.LogInfo((object)"Scene contains company building level!");
			}
			else if ((Object)(object)currentLevel != (Object)(object)targetLevel)
			{
				Plugin.Mls.LogWarning((object)("currentLevel (" + currentLevel.PlanetName + ") levelModifier (" + targetLevel.PlanetName + ") mismatch!"));
			}
			else
			{
				UndoModifications();
				EventsHandler.Reset();
			}
		}
	}
	[BepInPlugin("HullBreakerCompany", "HullBreakerCompany", "2.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		private static bool _loaded;

		public static ManualLogSource Mls;

		public static bool compatibilityLQ;

		public static float BunkerEnemyScale;

		public static float LandmineScale;

		public static float TurretScale;

		public static bool UseShortChatMessages;

		public static bool EnableEventMessages;

		public static bool UseHullBreakerLevelSettings;

		public static bool UseVanillaGameSettings;

		public static string LevelSettings;

		public static int MaxEnemyPowerCount;

		public static int MaxOutsideEnemyPowerCount;

		public static int MaxDaytimeEnemyPowerCount;

		public static bool IncreaseEventCountPerDay;

		public static int EventCount;

		public static int BountyRewardMin;

		public static int BountyRewardMax;

		public static int BountyRewardLimit;

		public static int HullBreakEventCreditsMin;

		public static int HullBreakEventCreditsMax;

		private readonly Harmony _harmony = new Harmony("HULLBREAKER");

		private void Awake()
		{
			Mls = Logger.CreateLogSource("HULLBREAKER 2.1.0");
			Mls.LogInfo((object)"Ready to break hull; HullBreakerCompany");
			_harmony.PatchAll(typeof(Plugin));
			_harmony.PatchAll(typeof(EventsHandler));
			if (!_loaded)
			{
				Initialize();
			}
		}

		public void Start()
		{
			if (!_loaded)
			{
				Initialize();
			}
		}

		public void OnDestroy()
		{
			if (!_loaded)
			{
				Initialize();
			}
		}

		public void Initialize()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			GameObject val = new GameObject("HullManager");
			Object.DontDestroyOnLoad((Object)(object)val);
			((Object)val).hideFlags = (HideFlags)61;
			val.AddComponent<HullManager>();
			SceneManager.sceneUnloaded += AfterGameInit;
			Mls.LogInfo((object)"HullManager created");
			_loaded = true;
		}

		private void AfterGameInit(Scene scene)
		{
			if (!(((Scene)(ref scene)).name != "InitScene"))
			{
				if (Chainloader.PluginInfos.ContainsKey("LethalQuantities"))
				{
					Mls.LogInfo((object)"Lethal Quantities found! Applying compatibility patch!");
					Harmony.CreateAndPatchAll(typeof(EventsManager), (string)null);
				}
				EventsManager.AddModEvents();
				EventsManager.AddCustomEvents();
				ConfigManager.RefreshConfig();
				ConfigManager.GetWeights();
				SceneManager.sceneUnloaded -= AfterGameInit;
			}
		}

		[HarmonyPatch(typeof(RoundManager), "LoadNewLevel")]
		[HarmonyPrefix]
		[HarmonyPriority(50)]
		private static bool ModifiedLoad(ref SelectableLevel newLevel)
		{
			Mls.LogInfo((object)("Client is host: " + ((NetworkBehaviour)RoundManager.Instance).IsHost));
			if (!((NetworkBehaviour)RoundManager.Instance).IsHost)
			{
				Mls.LogInfo((object)"LoadNewLevel called as client. Stopping..");
				return true;
			}
			HullManager.LogBox("MODIFIED LEVEL LOAD");
			Mls.LogInfo((object)$"Attempting to load and modify new level. ID: {newLevel.levelID}, Scene: {newLevel.sceneName}, Planet: {newLevel.PlanetName}");
			if (newLevel.levelID == 3)
			{
				Mls.LogInfo((object)"Level is company.");
				Mls.LogInfo((object)"Skipping modifications..");
				return true;
			}
			ConfigManager.RefreshConfig();
			EventsManager.ExecuteEvents(newLevel);
			return true;
		}

		private static void LQCompaitiblityPatch()
		{
			if (!compatibilityLQ && Chainloader.PluginInfos.ContainsKey("LethalQuantities"))
			{
				Mls.LogInfo((object)"Lethal Quantities found! Applying compatibility patch!");
				Harmony.CreateAndPatchAll(typeof(EventsManager), (string)null);
				compatibilityLQ = true;
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "HullBreakerCompany";

		public const string PLUGIN_NAME = "HullBreakerCompany";

		public const string PLUGIN_VERSION = "2.1.0";
	}
}
namespace HullBreakerCompany.Hull
{
	public class ConfigManager
	{
		private static string _configPath = Path.Combine(Paths.ConfigPath, "HullBreakerCompany.cfg");

		private static ConfigFile _configFile;

		private static T GetConfigValue<T>(string section, string key, T defaultValue, string description = null)
		{
			EnsureConfigExists();
			return _configFile.Bind<T>(section, key, defaultValue, description).Value;
		}

		private static void SetConfigValue()
		{
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Expected O, but got Unknown
			Plugin.EventCount = GetConfigValue("1 - Event Settings", "EventCount", 1, "Maximum number of active events. Less are possible depending on NothingEvent's weight.");
			Plugin.IncreaseEventCountPerDay = GetConfigValue("1 - Event Settings", "IncreaseEventCountPerDay", defaultValue: true, "Whether to increase EventCount by one for each day passed. Resets when a new quota begins.\nSetting this to \"true\" and EventCount to n will roll n events on the first day, n+1 on the second, ..");
			Plugin.EnableEventMessages = GetConfigValue("1.1 - Event Messages", "EnableEventMessages", defaultValue: true, "Enable chat event messages");
			Plugin.UseShortChatMessages = GetConfigValue("1.1 - Event Messages", "UseShortChatMessages", defaultValue: false, "Use short event message");
			Plugin.LandmineScale = GetConfigValue("1.2 - Event Configuration", "LandmineScale", 32, "The amount of additional landmines spawned by landmine event (there are more events that spawns mines and thus scale with the value set here)");
			Plugin.TurretScale = GetConfigValue("1.2 - Event Configuration", "TurretScale", 12, "The amount of additional turrets spawned by turret event");
			Plugin.BountyRewardMin = GetConfigValue("1.2 - Event Configuration", "BountyRewardMin", 20, "Minimum amount of credits rewarded for killing an enemy during EnemyBountyEvent");
			Plugin.BountyRewardMax = GetConfigValue("1.2 - Event Configuration", "BountyRewardMax", 70, "Maximum amount of credits rewarded for killing an enemy during EnemyBountyEvent");
			Plugin.BountyRewardLimit = GetConfigValue("1.2 - Event Configuration", "BountyRewardLimit", 10, "Limits the number of times you can get rewarded for kills during EnemyBountyEvent. Final reward will always pay `BountyRewardMax` * 1.5\nSet this to 0 for unlimited number of rewards.");
			Plugin.HullBreakEventCreditsMin = GetConfigValue("1.2 - Event Configuration", "HullBreakEventCreditsMin", 50, "Minimum amount of credits granted by HullBreakEvent");
			Plugin.HullBreakEventCreditsMax = GetConfigValue("1.2 - Event Configuration", "HullBreakEventCreditsMax", 200, "Maximum amount of credits granted by HullBreakEvent");
			Plugin.LevelSettings = _configFile.Bind<string>("2 - Level Settings", "LevelSettings", "vanilla", new ConfigDescription("Specifies the settings to apply to every level by default\nThese are baseline settings. Changes by events will always apply on top.\nSlimeEvent for example will increase a level's max power so it spawns *additional* slimes instead of just replacing enemies with slimes\n'vanilla': keep level settings as they are\n'hullbreaker': increases spawn rate inside and outside. Increases max power of inside and outside nemies by 16 and 20 respectively\n'custom': uses the values you specified below\n", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "vanilla", "hullbreaker", "custom" }), Array.Empty<object>())).Value;
			Plugin.MaxEnemyPowerCount = GetConfigValue("2.1 - Level Settings", "MaxEnemyPowerCount", 16, "Increase max enemy power count by this value");
			Plugin.MaxOutsideEnemyPowerCount = GetConfigValue("2.1 - Level Settings", "MaxOutsideEnemyPowerCount", 20, "Increase max outside enemy power count by this value (e.g. moutdog or forestgiant)");
			Plugin.MaxDaytimeEnemyPowerCount = GetConfigValue("2.1 - Level Settings", "MaxDaytimeEnemyPowerCount", 0, "Increase max daytime enemy power count by this value (e.g. bees)");
			Plugin.BunkerEnemyScale = GetConfigValue("2.1 - Level Settings", "BunkerEnemyScale", 256, "Change spawn rate for enemies inside. A value of '256' will instantly spawn enemies as you land (i.e. place or queue them in vents from which they will spawn after some time");
		}

		public static void RefreshConfig()
		{
			Plugin.Mls.LogInfo((object)"Refreshing config..");
			_configFile = null;
			SetConfigValue();
		}

		public static Dictionary<string, int> GetWeights()
		{
			Plugin.Mls.LogInfo((object)"Refreshing weights..");
			EnsureConfigExists();
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			foreach (HullEvent item in EventsManager.EventDictionary)
			{
				dictionary[item.ID()] = _configFile.Bind<int>("3 - Event Weights", item.ID(), item.GetWeight(), string.Format(item.ID() + " event: " + item.GetDescription())).Value;
			}
			return dictionary;
		}

		private static void EnsureConfigExists()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			if (_configFile == null)
			{
				if (!File.Exists(_configPath))
				{
					CreateDefaultConfigFile();
				}
				_configFile = new ConfigFile(_configPath, true);
			}
		}

		private static void CreateDefaultConfigFile()
		{
			using StreamWriter streamWriter = File.CreateText(_configPath);
			streamWriter.WriteLine("[Weights]");
			foreach (HullEvent item in EventsManager.EventDictionary)
			{
				streamWriter.WriteLine(item.ID() + "=" + item.GetWeight());
			}
		}
	}
	public class CustomEventLoader
	{
		public static void LoadCustomEvents()
		{
			List<Dictionary<string, string>> list = LoadEventDataFromCfgFiles();
			if (list.Count == 0)
			{
				return;
			}
			foreach (Dictionary<string, string> item in list)
			{
				CustomEvent customEvent = new CustomEvent();
				customEvent.SetID(item["EventID"]);
				customEvent.SetWeight(int.Parse(item["EventWeight"]));
				customEvent.Rarity = int.Parse(item["EnemyRarity"]);
				if (item.ContainsKey("SpawnableEnemies"))
				{
					customEvent.EnemySpawnList = new HashSet<string>(item["SpawnableEnemies"].Split(',')).ToList();
				}
				if (item.ContainsKey("SpawnableOutsideEnemies"))
				{
					customEvent.OutsideSpawnList = new HashSet<string>(item["SpawnableOutsideEnemies"].Split(',')).ToList();
				}
				customEvent.SetMessage(item["InGameMessage"]);
				customEvent.SetShortMessage(item["InGameShortMessage"]);
				EventsManager.EventDictionary.Add(customEvent);
			}
		}

		private static List<Dictionary<string, string>> LoadEventDataFromCfgFiles()
		{
			string text = Paths.BepInExRootPath + "\\HullEvents";
			if (!Directory.Exists(text))
			{
				Plugin.Mls.LogWarning((object)("Directory does not exist: " + text));
				Plugin.Mls.LogInfo((object)"Custom event folder 'HullEvents' not found. Skipping custom event loading.");
				return new List<Dictionary<string, string>>();
			}
			string[] files = Directory.GetFiles(text, "*.cfg");
			List<Dictionary<string, string>> list = new List<Dictionary<string, string>>();
			string[] array = files;
			foreach (string path in array)
			{
				string[] array2 = File.ReadAllLines(path);
				Dictionary<string, string> dictionary = new Dictionary<string, string>();
				string[] array3 = array2;
				foreach (string text2 in array3)
				{
					if (!text2.StartsWith("[") && !string.IsNullOrWhiteSpace(text2))
					{
						string[] array4 = text2.Split('=');
						if (array4.Length == 2)
						{
							string key = array4[0].Trim();
							string value = array4[1].Trim();
							dictionary[key] = value;
						}
					}
				}
				list.Add(dictionary);
				Plugin.Mls.LogInfo((object)("Loaded custom event: " + dictionary["EventID"]));
			}
			return list;
		}

		public static void AddEvent(HullEvent newEvent)
		{
			Plugin.Mls.LogInfo((object)("Adding new event" + newEvent.ID() + " to dictionary"));
			EventsManager.EventDictionary.Add(newEvent);
		}

		public static void DebugLoadCustomEvents()
		{
			foreach (HullEvent item in EventsManager.EventDictionary)
			{
				if (item is CustomEvent customEvent)
				{
					Plugin.Mls.LogInfo((object)("Event ID: " + customEvent.ID()));
					Plugin.Mls.LogInfo((object)("Spawnable Enemies: " + string.Join(", ", customEvent.EnemySpawnList)));
					Plugin.Mls.LogInfo((object)("Spawnable Outside Enemies: " + string.Join(", ", customEvent.OutsideSpawnList)));
					Plugin.Mls.LogInfo((object)("Message: " + customEvent.GetMessage()));
				}
			}
		}
	}
	internal class EnemyUtil
	{
		private static Dictionary<string, Type> EnemyBase = new Dictionary<string, Type>
		{
			{
				"flowerman",
				typeof(FlowermanAI)
			},
			{
				"hoarderbug",
				typeof(HoarderBugAI)
			},
			{
				"springman",
				typeof(SpringManAI)
			},
			{
				"crawler",
				typeof(CrawlerAI)
			},
			{
				"sandspider",
				typeof(SandSpiderAI)
			},
			{
				"jester",
				typeof(JesterAI)
			},
			{
				"centipede",
				typeof(CentipedeAI)
			},
			{
				"blobai",
				typeof(BlobAI)
			},
			{
				"dressgirl",
				typeof(DressGirlAI)
			},
			{
				"pufferenemy",
				typeof(PufferAI)
			},
			{
				"eyelessdogs",
				typeof(MouthDogAI)
			},
			{
				"forestgiant",
				typeof(ForestGiantAI)
			},
			{
				"sandworm",
				typeof(SandWormAI)
			},
			{
				"baboonbird",
				typeof(BaboonBirdAI)
			},
			{
				"nutcrackerenemy",
				typeof(NutcrackerEnemyAI)
			},
			{
				"maskedplayerenemy",
				typeof(MaskedPlayerEnemy)
			}
		};

		private static Dictionary<Type, string> EnemiesByType = new Dictionary<Type, string>
		{
			{
				typeof(FlowermanAI),
				"Flowerman"
			},
			{
				typeof(HoarderBugAI),
				"HoarderBug"
			},
			{
				typeof(SpringManAI),
				"SpringMan"
			},
			{
				typeof(CrawlerAI),
				"Crawler"
			},
			{
				typeof(SandSpiderAI),
				"SandSpider"
			},
			{
				typeof(JesterAI),
				"Jester"
			},
			{
				typeof(CentipedeAI),
				"Centipede"
			},
			{
				typeof(BlobAI),
				"Blob"
			},
			{
				typeof(DressGirlAI),
				"DressGirl"
			},
			{
				typeof(PufferAI),
				"PufferEnemy"
			},
			{
				typeof(MouthDogAI),
				"MouthDog"
			},
			{
				typeof(ForestGiantAI),
				"ForestGiant"
			},
			{
				typeof(SandWormAI),
				"SandWorm"
			},
			{
				typeof(BaboonBirdAI),
				"BaboonBird"
			},
			{
				typeof(NutcrackerEnemyAI),
				"NutcrackerEnemy"
			},
			{
				typeof(MaskedPlayerEnemy),
				"MaskedPlayerEnemy"
			},
			{
				typeof(ButlerEnemyAI),
				"ButlerEnemy"
			},
			{
				typeof(RedLocustBees),
				"RedLocustBees"
			}
		};

		public static string getEnemyByType(Type type)
		{
			try
			{
				EnemiesByType.TryGetValue(type, out var value);
				return value;
			}
			catch
			{
				return null;
			}
		}

		public static Type getEnemyByString(string str)
		{
			try
			{
				EnemyBase.TryGetValue(str, out var value);
				return value;
			}
			catch
			{
				return null;
			}
		}
	}
	public abstract class EventsHandler
	{
		public static bool BountyIsActive;

		public static int BountyRewards;

		public static bool OneForAllIsActive;

		public static bool BountyFirstKill;

		public static bool MeltdownActive;

		public static void Reset()
		{
			Plugin.Mls.LogInfo((object)"Resetting EventsHandler variables.");
			BountyIsActive = false;
			BountyRewards = 0;
			OneForAllIsActive = false;
			MeltdownActive = false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(EnemyAI), "KillEnemy")]
		private static void EnemyBounty(bool destroy)
		{
			Plugin.Mls.LogInfo((object)$"Enemy killed, instance isHost: {((NetworkBehaviour)RoundManager.Instance).IsHost}");
			if (!((NetworkBehaviour)RoundManager.Instance).IsHost)
			{
				return;
			}
			Plugin.Mls.LogInfo((object)$"Enemy killed, bounty is active: {BountyIsActive}; destroy is {destroy}");
			if (BountyIsActive && !destroy)
			{
				int num = Random.Range(Plugin.BountyRewardMin, Plugin.BountyRewardMax);
				BountyRewards++;
				if (BountyFirstKill)
				{
					List<string> list = new List<string> { "Threat neutralized! Keep up the good work. The company sends [AMOUNT] credits.", "Enemy killed! Your work keeps the company happy. You receive [AMOUNT] credits.", "Monster killed! The company values your commitment. [AMOUNT] credits received." };
					StringBuilder stringBuilder = new StringBuilder("<color=white>" + list[Random.Range(0, list.Count)] + "</color>");
					stringBuilder.Replace("[AMOUNT]", "</color><color=green>" + num + "</color><color=white>");
					HullManager.SendChatEventMessage(stringBuilder.ToString());
					BountyFirstKill = false;
				}
				else if (Plugin.BountyRewardLimit > 0 && BountyRewards >= Plugin.BountyRewardLimit)
				{
					BountyIsActive = false;
					num = (int)Math.Floor((float)Plugin.BountyRewardMax * 1.5f);
					Plugin.Mls.LogInfo((object)("<color=white>Bounty complete! You receive </color><color=green>" + num + "</color><color=white> credits. Your handwork is invaluable to the company."));
				}
				else
				{
					HullManager.SendChatEventMessage("<color=white>Bounty reward: </color><color=green>" + num + "</color><color=white> credits</color>");
				}
				HullManager.Instance.AddMoney(num);
				Plugin.Mls.LogInfo((object)$"Bounty credits rewarded: {num}");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "KillPlayerServerRpc")]
		private static void OneForAll()
		{
			if (((NetworkBehaviour)RoundManager.Instance).IsHost)
			{
				Plugin.Mls.LogInfo((object)$"Player killed, one for all is active: {OneForAllIsActive}");
				if (OneForAllIsActive)
				{
					OneForAllIsActive = false;
					HullManager.Instance.timeOfDay.votedShipToLeaveEarlyThisRound = true;
					HullManager.Instance.timeOfDay.SetShipLeaveEarlyServerRpc();
					HullManager.SendChatEventMessage("<color=red>Employee signal lost! Ship will leave in two hours!</color>");
				}
			}
		}
	}
	public abstract class EventsManager
	{
		public static int DaysPassed;

		public static bool modEventsLoaded = false;

		public static bool customEventsLoaded = false;

		private static LevelModifier levelModifier;

		public static List<HullEvent> EventDictionary = new List<HullEvent>
		{
			new ArachnophobiaEvent(),
			new BeeEvent(),
			new ButlerEvent(),
			new DevochkaPizdecEvent(),
			new FlowerManEvent(),
			new HellEvent(),
			new HoarderBugEvent(),
			new LizardsEvent(),
			new MaskedEvent(),
			new NutcrackerEvent(),
			new SlimeEvent(),
			new SpringManEvent(),
			new EnemyBountyEvent(),
			new HackedTurretsEvent(),
			new HordeModeEvent(),
			new HullBreakEvent(),
			new LandMineEvent(),
			new NothingEvent(),
			new OnAPowderKegEvent(),
			new OneForAllEvent(),
			new OpenTheNoorEvent(),
			new OutSideEnemyDayEvent(),
			new TimeAnomalyEvent(),
			new TimeDilationEvent(),
			new TurretEvent(),
			new ArmdayEvent(),
			new BabkinPogrebEvent(),
			new ChristmasEveEvent(),
			new ClownshowEvent(),
			new DayDrinkingEvent(),
			new LuckyDayEvent(),
			new SelfDefenseEvent()
		};

		public static void AddModEvents()
		{
			if (modEventsLoaded)
			{
				return;
			}
			Plugin.Mls.LogInfo((object)"Checking for compatible mods..");
			Dictionary<HullEvent, string> dictionary = new Dictionary<HullEvent, string>
			{
				{
					new BoombaEvent(),
					"evaisa.lethalthings"
				},
				{
					new HerobrineEvent(),
					"Kittenji.HerobrineMod"
				},
				{
					new MeltdownEvent(),
					"me.loaforc.facilitymeltdown"
				},
				{
					new ShyGuyEvent(),
					"DBJ.ShyGuyPatcherPatcher"
				}
			};
			foreach (KeyValuePair<HullEvent, string> item in dictionary)
			{
				if (Chainloader.PluginInfos.ContainsKey(item.Value))
				{
					Plugin.Mls.LogInfo((object)(Chainloader.PluginInfos[item.Value].Metadata.Name + " found! Enabling event: " + item.Key.ID()));
					EventDictionary.Add(item.Key);
				}
				else
				{
					Plugin.Mls.LogInfo((object)(item.Value + " not present! Disabling event: " + item.Key.ID()));
				}
			}
			modEventsLoaded = true;
		}

		public static void AddCustomEvents()
		{
			if (!customEventsLoaded)
			{
				Plugin.Mls.LogInfo((object)"Checking for custom events..");
				CustomEventLoader.LoadCustomEvents();
				CustomEventLoader.DebugLoadCustomEvents();
				customEventsLoaded = true;
			}
		}

		public static void ExecuteEvents(SelectableLevel newLevel)
		{
			HullManager.LogBox("EVENT EXECUTION");
			LevelModifier levelModifier = new LevelModifier(newLevel);
			EventsManager.levelModifier = levelModifier;
			UpdateLevelSettings();
			RefreshDaysPassed();
			List<HullEvent> list = new List<HullEvent>();
			int num = (Plugin.IncreaseEventCountPerDay ? (Plugin.EventCount + DaysPassed) : Plugin.EventCount);
			Plugin.Mls.LogInfo((object)$"Round events: {num}");
			Plugin.Mls.LogInfo((object)"Start event selection..");
			foreach (string gameEvent in RandomSelector.GetRandomGameEvents(num))
			{
				try
				{
					HullEvent hullEvent = EventDictionary.FirstOrDefault((HullEvent e) => e.ID() == gameEvent);
					if (hullEvent == null)
					{
						Plugin.Mls.LogWarning((object)("Couldn't find event " + gameEvent + " in event dictionary!"));
						continue;
					}
					Plugin.Mls.LogInfo((object)("Got event: " + hullEvent.ID()));
					if (hullEvent.Execute(newLevel, EventsManager.levelModifier))
					{
						list.Add(hullEvent);
					}
					else
					{
						Plugin.Mls.LogInfo((object)("Skipping event: " + hullEvent.ID()));
					}
				}
				catch (NullReferenceException ex)
				{
					Plugin.Mls.LogError((object)$"NullReferenceException caught while processing event: {gameEvent}. Exception message: {ex.Message}. Caused : {ex.InnerException}");
				}
			}
			while (list.Count() < num)
			{
				string newEvent = RandomSelector.GetAnotherRandomGameEvent();
				if (newEvent == null)
				{
					Plugin.Mls.LogInfo((object)"Event selection failed. No events left to execute..");
					break;
				}
				HullEvent hullEvent2 = EventDictionary.FirstOrDefault((HullEvent e) => e.ID() == newEvent);
				if (hullEvent2 == null)
				{
					Plugin.Mls.LogWarning((object)("Couldn't find event " + newEvent + " in event dictionary!"));
					continue;
				}
				Plugin.Mls.LogInfo((object)("Got event: " + hullEvent2.ID()));
				if (hullEvent2.Execute(newLevel, EventsManager.levelModifier))
				{
					list.Add(hullEvent2);
				}
				else
				{
					Plugin.Mls.LogInfo((object)("Skipping event: " + hullEvent2.ID()));
				}
			}
			Plugin.Mls.LogInfo((object)$"Selected events: {list.Count()}");
			Plugin.Mls.LogInfo((object)string.Format("Nothing events: {0}", list.Where((HullEvent e) => e.ID().Equals("Nothing")).Count()));
			list.RemoveAll((HullEvent e) => e.ID().Equals("Nothing"));
			Plugin.Mls.LogInfo((object)string.Format("Active events: {0} ({1})", list.Count(), string.Join(", ", list.Select((HullEvent e) => e.ID()))));
			EventsManager.levelModifier.ApplyModificationsToLevel();
			HullManager.SendChatEventMessages();
			PrintDebugLogs(newLevel);
		}

		private static int RefreshDaysPassed()
		{
			DaysPassed = HullManager.Instance.timeOfDay.quotaVariables.deadlineDaysAmount - HullManager.Instance.timeOfDay.daysUntilDeadline;
			Plugin.Mls.LogInfo((object)$"Days passed: {DaysPassed}");
			return DaysPassed;
		}

		private static void UpdateLevelSettings()
		{
			Plugin.Mls.LogInfo((object)("Level Settings config value: " + Plugin.LevelSettings));
			string levelSettings = Plugin.LevelSettings;
			string text = levelSettings;
			if (!(text == "hullbreaker"))
			{
				if (text == "custom")
				{
					Plugin.Mls.LogInfo((object)"Applying custom level settings from config");
					levelModifier.AddMaxEnemyPower(Plugin.MaxEnemyPowerCount);
					levelModifier.AddMaxOutsideEnemyPower(Plugin.MaxOutsideEnemyPowerCount);
					levelModifier.AddMaxDaytimeEnemyPower(Plugin.MaxDaytimeEnemyPowerCount);
					levelModifier.AddEnemySpawnChanceThroughoutDay((int)Plugin.BunkerEnemyScale);
				}
				else
				{
					Plugin.Mls.LogInfo((object)"Keeping Vanilla level settings");
				}
			}
			else
			{
				Plugin.Mls.LogInfo((object)"Applying Hullbreaker level settings");
				levelModifier.AddMaxEnemyPower(16);
				levelModifier.AddMaxOutsideEnemyPower(20);
				levelModifier.AddEnemySpawnChanceThroughoutDay(256);
				levelModifier.AddDaytimeEnemySpawnChanceThroughoutDay(5);
			}
		}

		private static void PrintDebugLogs(SelectableLevel level)
		{
			HullManager.LogEnemies(level.Enemies, "INSIDE ENEMIES");
			HullManager.LogEnemies(level.OutsideEnemies, "OUTSIDE ENEMIES");
			HullManager.LogEnemies(level.DaytimeEnemies, "DAYTIME ENEMIES");
			HullManager.LogScrapRarity(level.spawnableScrap, "LOOT TABLE");
		}

		[HarmonyPatch(typeof(RoundState), "OnDestroy")]
		[HarmonyPrefix]
		public static void RoundStateOnDestroyPrefix()
		{
			if (levelModifier == null)
			{
				Plugin.Mls.LogInfo((object)"No levelModifier found. No modifications to revert.");
			}
			else
			{
				levelModifier.undoModificationsEarly();
			}
		}
	}
	public abstract class HullEvent
	{
		public abstract string ID();

		public virtual int GetWeight()
		{
			return 1;
		}

		public virtual string GetDescription()
		{
			return "Default description";
		}

		public virtual string GetMessage()
		{
			return "Default message";
		}

		public virtual string GetShortMessage()
		{
			return "Short message";
		}

		public virtual bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			return true;
		}

		public virtual Dictionary<string, int> CalculateScrapRarities(Dictionary<string, int> inputScrap, LevelModifier levelModifier)
		{
			int num = 0;
			int num2 = 0;
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			foreach (KeyValuePair<string, int> item in inputScrap)
			{
				num += item.Value;
				Plugin.Mls.LogInfo((object)$"{ID()}: want to change rarity of {item.Key} to {item.Value}% of total scrap rarity");
				if (levelModifier.IsScrapSpawnable(item.Key))
				{
					num2 += item.Value;
					dictionary.TryAdd(item.Key, item.Value);
				}
			}
			Dictionary<string, int> dictionary2 = new Dictionary<string, int>(dictionary);
			foreach (KeyValuePair<string, int> item2 in inputScrap)
			{
				if (dictionary.ContainsKey(item2.Key))
				{
					dictionary[item2.Key] = (int)Math.Round((double)item2.Value / (double)num2 * (double)num);
					if (dictionary[item2.Key] != item2.Value)
					{
						Plugin.Mls.LogInfo((object)$"{ID()}: to compensate for unspawnable scrap, {item2.Key} will be added at {dictionary[item2.Key]}% of total scrap rarity ");
					}
				}
			}
			return dictionary;
		}
	}
	public class HullManager : MonoBehaviour
	{
		public TimeOfDay timeOfDay;

		public static List<string> chatMessages = new List<string>();

		public static HullManager Instance { get; private set; }

		public void Update()
		{
			if ((Object)(object)timeOfDay == (Object)null)
			{
				timeOfDay = Object.FindFirstObjectByType<TimeOfDay>();
			}
		}

		public void Start()
		{
			Plugin.Mls.LogDebug((object)"Start: HullManager");
		}

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			}
			else
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		public void AddMoney(int amount)
		{
			Terminal val = Object.FindObjectOfType<Terminal>();
			val.groupCredits += amount;
			val.SyncGroupCreditsServerRpc(val.groupCredits, val.numberOfItemsInDropship);
		}

		public void ExecuteAfterDelay(Action action, float delay)
		{
			((MonoBehaviour)this).StartCoroutine(DelayedExecution(action, delay));
		}

		private IEnumerator DelayedExecution(Action action, float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			action();
		}

		public static void AddChatEventMessage(HullEvent hullEvent)
		{
			if ((Object)(object)HUDManager.Instance != (Object)null && hullEvent != null && Plugin.EnableEventMessages)
			{
				chatMessages.Add(Plugin.UseShortChatMessages ? hullEvent.GetShortMessage() : hullEvent.GetMessage());
			}
		}

		public static void AddChatEventMessage(string message, bool addAsFirst = false)
		{
			if ((Object)(object)HUDManager.Instance != (Object)null && message != null && Plugin.EnableEventMessages)
			{
				if (!addAsFirst)
				{
					chatMessages.Add(message);
				}
				else
				{
					chatMessages.Insert(0, message);
				}
			}
		}

		public static void SendChatEventMessage(string message)
		{
			if ((Object)(object)HUDManager.Instance != (Object)null && message != null && Plugin.EnableEventMessages)
			{
				HUDManager.Instance.AddTextToChatOnServer(message, -1);
			}
		}

		public static void SendChatEventMessages()
		{
			if ((Object)(object)HUDManager.Instance != (Object)null && Plugin.EnableEventMessages && chatMessages.Count > 0)
			{
				AddChatEventMessage("<color=red>NOTES ABOUT MOON:</color>", addAsFirst: true);
				foreach (string chatMessage in chatMessages)
				{
					HUDManager.Instance.AddTextToChatOnServer(chatMessage, -1);
				}
			}
			chatMessages.Clear();
		}

		public static void LogEnemies(List<SpawnableEnemyWithRarity> enemies, string title)
		{
			LogBoxHeader(title);
			Plugin.Mls.LogInfo((object)string.Format("╠{0, -24}╦{1, 12}╤{2, 12}╤{3, 12}╗", new string('═', 23).Insert(title.Length + 2, "╩"), new string('═', 12), new string('═', 12), new string('═', 12)));
			Plugin.Mls.LogInfo((object)string.Format("║ {0, -22} ║ {1, 10} │ {2, 10} │ {3, 10} ║", "Enemy", "Rarity", "MaxCount", "Power"));
			Plugin.Mls.LogInfo((object)$"╠{new string('═', 24),-24}╬{new string('═', 12),12}╪{new string('═', 12),12}╪{new string('═', 12),12}╣");
			int num = 0;
			foreach (SpawnableEnemyWithRarity enemy in enemies)
			{
				try
				{
					Plugin.Mls.LogInfo((object)$"║ {((Object)enemy.enemyType.enemyPrefab).name,-22} ║ {enemy.rarity,10} │ {enemy.enemyType.MaxCount,10} │ {enemy.enemyType.PowerLevel,10} ║");
					num += enemy.rarity;
				}
				catch (Exception ex)
				{
					Plugin.Mls.LogError((object)ex.Message);
				}
			}
			Plugin.Mls.LogInfo((object)$"╠{new string('═', 24),-24}╬{new string('═', 12),12}╪{new string('═', 12),12}╪{new string('═', 12),12}╣");
			Plugin.Mls.LogInfo((object)string.Format("║ {0, -22} ║ {1, 10} │ {2, 10} │ {3, 10} ║", "Sum", num, "", ""));
			Plugin.Mls.LogInfo((object)$"╚{new string('═', 24),-24}╩{new string('═', 12),12}╧{new string('═', 12),12}╧{new string('═', 12),12}╝");
		}

		public static void LogScrapRarity(List<SpawnableItemWithRarity> loot, string title)
		{
			LogBoxHeader(title);
			Plugin.Mls.LogInfo((object)string.Format("╠{0, -30}╤{1, 12}╗", new string('═', 29).Insert(title.Length + 2, "╩"), new string('═', 12)));
			Plugin.Mls.LogInfo((object)string.Format("║ {0, -28} │ {1, 10} ║", "Scrap item", "Rarity"));
			Plugin.Mls.LogInfo((object)$"╠{new string('═', 30),-30}╪{new string('═', 12),12}╣");
			int num = 0;
			foreach (SpawnableItemWithRarity item in loot)
			{
				if (item != null)
				{
					Plugin.Mls.LogInfo((object)$"║ {item.spawnableItem.itemName,-28} │ {item.rarity,10} ║");
					num += item.rarity;
				}
			}
			Plugin.Mls.LogInfo((object)$"╠{new string('═', 30),-30}╪{new string('═', 12),12}╣");
			Plugin.Mls.LogInfo((object)string.Format("║ {0, -28} │ {1, 10} ║", "Sum", num));
			Plugin.Mls.LogInfo((object)$"╚{new string('═', 30),-30}╧{new string('═', 12),12}╝");
		}

		public static void LogBox(string title)
		{
			Plugin.Mls.LogInfo((object)("╔" + new string('═', title.Length + 2) + "╗"));
			Plugin.Mls.LogInfo((object)("║ " + title + " ║"));
			Plugin.Mls.LogInfo((object)("╚" + new string('═', title.Length + 2) + "╝"));
		}

		private static void LogBoxHeader(string title)
		{
			Plugin.Mls.LogInfo((object)("╔" + new string('═', title.Length + 2) + "╗"));
			Plugin.Mls.LogInfo((object)("║ " + title + " ║"));
		}
	}
	public abstract class RandomSelector
	{
		private static readonly Random _random = new Random();

		private static Dictionary<string, int> weights = new Dictionary<string, int>();

		public static List<string> GetRandomGameEvents(int count)
		{
			weights = ConfigManager.GetWeights();
			List<string> weightedRandomGameEvents = GetWeightedRandomGameEvents(weights, count);
			foreach (string item in weightedRandomGameEvents)
			{
				if (!(item == "NothingEvent"))
				{
					weights.Remove(item);
				}
			}
			return weightedRandomGameEvents;
		}

		public static string GetAnotherRandomGameEvent()
		{
			if (weights.Count == 0)
			{
				return null;
			}
			string text = GetWeightedRandomGameEvents(weights, 1)[0];
			if (text != "Nothing")
			{
				weights.Remove(text);
			}
			return text;
		}

		private static List<T> GetWeightedRandomGameEvents<T>(Dictionary<T, int> weights, int count)
		{
			int num = weights.Where((KeyValuePair<T, int> x) => x.Value > 0).Sum((KeyValuePair<T, int> x) => x.Value);
			HashSet<T> hashSet = new HashSet<T>();
			if (num < 1)
			{
				return hashSet.ToList();
			}
			while (hashSet.Count < count)
			{
				int num2 = _random.Next(num);
				foreach (KeyValuePair<T, int> weight in weights)
				{
					if (weight.Value != 0)
					{
						if (num2 < weight.Value)
						{
							hashSet.Add(weight.Key);
							break;
						}
						num2 -= weight.Value;
					}
				}
			}
			return hashSet.ToList();
		}

		private static void Shuffle<T>(IList<T> list)
		{
			int num = list.Count;
			while (num > 1)
			{
				num--;
				int num2 = _random.Next(num + 1);
				int index = num2;
				int index2 = num;
				T value = list[num];
				T value2 = list[num2];
				list[index] = value;
				list[index2] = value2;
			}
		}
	}
}
namespace HullBreakerCompany.Events
{
	public class CustomEvent : HullEvent
	{
		private string _id;

		private int _weight;

		private string _message;

		private string _shortMessage;

		public List<string> EnemySpawnList = new List<string>();

		public List<string> OutsideSpawnList = new List<string>();

		public int Rarity = 1;

		public override string ID()
		{
			return _id;
		}

		public void SetID(string value)
		{
			_id = value;
		}

		public void SetWeight(int value)
		{
			_weight = value;
		}

		public override int GetWeight()
		{
			return _weight;
		}

		public void SetMessage(string value)
		{
			_message = value;
		}

		public void SetShortMessage(string value)
		{
			_shortMessage = value;
		}

		public override string GetMessage()
		{
			return "<color=white>" + _message + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + _shortMessage + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			if (EnemySpawnList.Any((string enemy) => !levelModifier.IsEnemySpawnable(enemy)))
			{
				return false;
			}
			if (OutsideSpawnList.Any((string enemy) => !levelModifier.IsOutsideEnemySpawnable(enemy)))
			{
				return false;
			}
			foreach (string item in EnemySpawnList.TakeWhile((string enemy) => enemy != "off"))
			{
				levelModifier.AddEnemyComponentRarity(item, Rarity);
			}
			foreach (string item2 in OutsideSpawnList.TakeWhile((string enemy) => enemy != "off"))
			{
				levelModifier.AddOutsideEnemyRarity(item2, Rarity);
			}
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
}
namespace HullBreakerCompany.Events.Scrap
{
	public class ArmdayEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Expect to find some big heavy scrap", "Roll up your sleeves and collect the scrap!", "Slipped disks are not covered by company insurance!", "Lift heavy objects with a jerking twisting motion!", "Lower back pain" };

		public static List<string> shortMessagesList = new List<string> { "HEAVY" };

		public override string ID()
		{
			return "Armday";
		}

		public override int GetWeight()
		{
			return 20;
		}

		public override string GetDescription()
		{
			return "Spawns a lot of heavy loot.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			Dictionary<string, int> inputScrap = new Dictionary<string, int>
			{
				{ "Metal sheet", 20 },
				{ "Large axle", 10 },
				{ "V-type Engine", 10 },
				{ "Stop sign", 10 },
				{ "Yield sign", 10 },
				{ "Fire hydrant", 15 },
				{ "Broken engine", 10 },
				{ "Anvil", 5 }
			};
			inputScrap = CalculateScrapRarities(inputScrap, levelModifier);
			if (inputScrap.Count == 0)
			{
				return false;
			}
			levelModifier.AddSpawnableScrapRarityDict(inputScrap);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class BabkinPogrebEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Scans indicate all scrap is.. organic?", "There is something wrong with the scrap..", "We lost Rick. Find him!", "Quite a pickle indeed!" };

		public static List<string> shortMessagesList = new List<string> { "QUITE A PICKLE" };

		public static List<SpawnableItemWithRarity> scrapList = new List<SpawnableItemWithRarity>();

		public override string ID()
		{
			return "BabkinPogreb";
		}

		public override int GetWeight()
		{
			return 20;
		}

		public override string GetDescription()
		{
			return "Spawns a lot of pickle jars.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			string text = "Jar of pickles";
			if (levelModifier.IsScrapSpawnable(text))
			{
				levelModifier.AddSpawnableScrapRarity(text, 100);
				HullManager.AddChatEventMessage(this);
				return true;
			}
			return false;
		}
	}
	public class ChristmasEveEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Is it Christmas already?", "Help Santa collect the presents!", "The Company wishes a Merry Christmas!" };

		public static List<string> shortMessagesList = new List<string> { "XMAS" };

		public override string ID()
		{
			return "ChristmasEve";
		}

		public override int GetWeight()
		{
			return 20;
		}

		public override string GetDescription()
		{
			return "Spawns a lot of gifts.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			string text = "Gift";
			if (levelModifier.IsScrapSpawnable(text))
			{
				levelModifier.AddSpawnableScrapRarity(text, 300);
				HullManager.AddChatEventMessage(this);
				return true;
			}
			return false;
		}
	}
	public class ClownshowEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "This is a clown show!", "Your clown nose fell off.." };

		public static List<string> shortMessagesList = new List<string> { "CLOWN" };

		public override string ID()
		{
			return "Clownshow";
		}

		public override int GetWeight()
		{
			return 20;
		}

		public override string GetDescription()
		{
			return "Spawns a lot of noisy scrap.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			Dictionary<string, int> inputScrap = new Dictionary<string, int>
			{
				{ "Airhorn", 30 },
				{ "Clown horn", 30 },
				{ "Candy", 30 },
				{ "Whoopie cushion", 10 }
			};
			inputScrap = CalculateScrapRarities(inputScrap, levelModifier);
			if (inputScrap.Count == 0)
			{
				return false;
			}
			levelModifier.AddSpawnableScrapRarityDict(inputScrap);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class DayDrinkingEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Let's crack a beer or two!", "Alcohol use prohibited during work hours!", "There is something wrong with the scrap.." };

		public static List<string> shortMessagesList = new List<string> { "DAYDRINKING" };

		public override string ID()
		{
			return "DayDrinking";
		}

		public override int GetWeight()
		{
			return 20;
		}

		public override string GetDescription()
		{
			return "Spawns a lot of alcoholic beverages.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			Dictionary<string, int> inputScrap = new Dictionary<string, int>
			{
				{ "Bottles", 30 },
				{ "Alcohol Flask", 25 },
				{ "Wine bottle", 10 },
				{ "Canteen", 25 }
			};
			inputScrap = CalculateScrapRarities(inputScrap, levelModifier);
			if (inputScrap.Count == 0)
			{
				return false;
			}
			levelModifier.AddSpawnableScrapRarityDict(inputScrap);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class LuckyDayEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "High value scrap detected!", "Supposed to hold some very valuable scrap", "Today's your lucky day!" };

		public static List<string> shortMessagesList = new List<string> { "LUCKY" };

		public override string ID()
		{
			return "LuckyDay";
		}

		public override int GetWeight()
		{
			return 5;
		}

		public override string GetDescription()
		{
			return "Increases spawn chance of high value loot.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			Dictionary<string, int> inputScrap = new Dictionary<string, int>
			{
				{ "Cash register", 20 },
				{ "Gold bar", 20 }
			};
			inputScrap = CalculateScrapRarities(inputScrap, levelModifier);
			if (inputScrap.Count == 0)
			{
				return false;
			}
			levelModifier.AddSpawnableScrapRarityDict(inputScrap);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class SelfDefenseEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Weapons scattered all around!", "DIY self defense training today!" };

		public static List<string> shortMessagesList = new List<string> { "WEAPONS" };

		public override string ID()
		{
			return "SelfDefense";
		}

		public override int GetWeight()
		{
			return 20;
		}

		public override string GetDescription()
		{
			return "Spawns a lot of scrap that can be utilized as weapon.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			Dictionary<string, int> inputScrap = new Dictionary<string, int>
			{
				{ "Plunger", 20 },
				{ "Stop sign", 15 },
				{ "Yield sign", 15 },
				{ "Baseball bat", 15 },
				{ "Toy Hammer", 10 },
				{ "Fireaxe", 5 }
			};
			inputScrap = CalculateScrapRarities(inputScrap, levelModifier);
			if (inputScrap.Count == 0)
			{
				return false;
			}
			levelModifier.AddSpawnableScrapRarityDict(inputScrap);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
}
namespace HullBreakerCompany.Events.Misc
{
	public class EnemyBountyEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Company bounty: neutralize threats", "The company pays you for killing monsters", "Bounty assigned: kill enemies", "Company bounty: RIP AND TEAR" };

		public static List<string> shortMessagesList = new List<string> { "KILL BOUNTY", "COMPANY BOUNTY" };

		public override string ID()
		{
			return "EnemyBounty";
		}

		public override int GetWeight()
		{
			return 30;
		}

		public override string GetDescription()
		{
			return "Company rewards enemy kills with bonus credits.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			EventsHandler.BountyIsActive = true;
			EventsHandler.BountyFirstKill = true;
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class HackedTurretsEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Security systems offline", "Abandoned after their defense sytems were hacked", "The company disabled all turrets on this moon" };

		public static List<string> shortMessagesList = new List<string> { "SECURITY OFFLINE", "TURRETS HACKED " };

		public override string ID()
		{
			return "HackedTurrets";
		}

		public override int GetWeight()
		{
			return 20;
		}

		public override string GetDescription()
		{
			return "All turrets are permanently disabled.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			if ((Object)(object)HullManager.Instance == (Object)null)
			{
				Plugin.Mls.LogError((object)"HullManager.Instance is null");
				return false;
			}
			if ((Object)(object)level == (Object)null)
			{
				Plugin.Mls.LogError((object)"level is null");
				return false;
			}
			HullManager.Instance.ExecuteAfterDelay(delegate
			{
				HackTurrets();
			}, 16f);
			HullManager.AddChatEventMessage(this);
			return true;
		}

		private void HackTurrets()
		{
			Turret[] array = Object.FindObjectsOfType<Turret>();
			Turret[] array2 = array;
			foreach (Turret val in array2)
			{
				val.ToggleTurretServerRpc(false);
			}
		}
	}
	public class HordeModeEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Extreme activity levels!", "No one has ever returned from here..", "Caution! Activity level 9 9 9 9 9 9 9 9 9 9 9 9", "The company wishes the best of luck!" };

		public static List<string> shortMessagesList = new List<string> { "HORDEMODE" };

		public override string ID()
		{
			return "HordeMode";
		}

		public override int GetWeight()
		{
			return 5;
		}

		public override string GetDescription()
		{
			return "Increases inside enemy spawn rate. Spawns enemies earlier and more frequently.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			if (Plugin.UseHullBreakerLevelSettings)
			{
				Plugin.Mls.LogInfo((object)"Spawn chance already increased by HullBreaker level settings");
				return false;
			}
			levelModifier.AddEnemySpawnChanceThroughoutDay(512);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class HullBreakEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "KPI report: underperforming\nUse </color><color=green>[AMOUNT]</color><color=white> credits to prove your worth to the company!", "The company appreciates your loyalty. You receive </color><color=green>[AMOUNT]</color><color=white> credits", "Bonus payment received: </color><color=green>[AMOUNT]</color><color=white> credits. Keep up the good work!" };

		public static List<string> shortMessagesList = new List<string> { "BONUS CREDITS: </color><color=green>[AMOUNT]", "BONUS PAYMENT: </color><color=green>[AMOUNT]" };

		private static int bonus_credits;

		public override string ID()
		{
			return "HullBreak";
		}

		public override int GetWeight()
		{
			return 10;
		}

		public override string GetDescription()
		{
			return "The company sends a bonus payment. Take a break from stressfull events.";
		}

		public override string GetMessage()
		{
			string text = "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
			return text.Replace("[AMOUNT]", bonus_credits.ToString());
		}

		public override string GetShortMessage()
		{
			string text = "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
			return text.Replace("[AMOUNT]", bonus_credits.ToString());
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			bonus_credits = Random.Range(Plugin.HullBreakEventCreditsMin, Plugin.HullBreakEventCreditsMax);
			HullManager.Instance.AddMoney(bonus_credits);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class LandMineEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "High security compound", "They rigged this place up", "Watch your step!", "Expect mines", "Lots of mines might block your path" };

		public static List<string> shortMessagesList = new List<string> { "LANDMINES" };

		public override string ID()
		{
			return "LandMine";
		}

		public override int GetWeight()
		{
			return 30;
		}

		public override string GetDescription()
		{
			return "Spawns additional landmines inside.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			levelModifier.AddLandmines(Plugin.LandmineScale);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class MeltdownEvent : HullEvent
	{
		public int dayInSeconds;

		public int currentDaysLeft;

		public static List<string> MessagesList = new List<string> { "Unstable reactor core. Extract and leave immediately!", "Elevated radiation levels. Reactor meltdown imminent!", "Prevent a nuclear disaster by gracefully removing the apparatus core", "Increased radiation levels. Don't wander too far off the ship." };

		public static List<string> shortMessagesList = new List<string> { "SURPRISE", "MELTDOWN" };

		public override string ID()
		{
			return "Meltdown";
		}

		public override int GetWeight()
		{
			return 10;
		}

		public override string GetDescription()
		{
			return "Starts reactor meltdown sequence sometime during the day.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			currentDaysLeft = TimeOfDay.Instance.daysUntilDeadline;
			dayInSeconds = (int)HullManager.Instance.timeOfDay.lengthOfHours * HullManager.Instance.timeOfDay.numberOfHours;
			HullManager.AddChatEventMessage(this);
			HullManager.Instance.ExecuteAfterDelay(delegate
			{
				StartMeltdown();
			}, Random.Range((float)dayInSeconds * 0.3f, (float)dayInSeconds * 0.8f));
			EventsHandler.MeltdownActive = true;
			return true;
		}

		private void StartMeltdown()
		{
			if (!EventsHandler.MeltdownActive || TimeOfDay.Instance.playersManager.inShipPhase || RoundManager.Instance.currentLevel.levelID == 3)
			{
				Plugin.Mls.LogInfo((object)($"Meltdown Event abort. Reason: MeltdownActive: {EventsHandler.MeltdownActive}; " + $"inShipPhase: {TimeOfDay.Instance.playersManager.inShipPhase}; " + $"currentLevel: {RoundManager.Instance.currentLevel.PlanetName} (ID {RoundManager.Instance.currentLevel.levelID}"));
				return;
			}
			Plugin.Mls.LogInfo((object)(ID() + " Event: Meltdown initiated"));
			MeltdownAPI.StartMeltdown("HullBreakerCompany");
			HullManager.SendChatEventMessage("<color=red>NUCLEAR MELTDOWN IMMINENT! ABANDON MISSION!</color>");
		}
	}
	public class NothingEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "<color=white>...</color>", "<color=white>---</color>", "<color=white>   </color>" };

		public override string ID()
		{
			return "Nothing";
		}

		public override int GetWeight()
		{
			return 100;
		}

		public override string GetDescription()
		{
			return "Nothing happens - This event means there is no event.\nAdjust weight to set overall chance of getting an event vs. not getting an event for each time an event is randomly selected.";
		}

		public override string GetMessage()
		{
			return MessagesList[Random.Range(0, MessagesList.Count)];
		}

		public override string GetShortMessage()
		{
			return MessagesList[Random.Range(0, MessagesList.Count)];
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			return true;
		}
	}
	public class OnAPowderKegEvent : HullEvent
	{
		public int dayInSeconds;

		public static List<string> MessagesList = new List<string> { "Reccuring explosions", "Explosions detected", "They installed faulty mines", "Mines explode at the slightest vibration", "Tick, tick.. BOOM!" };

		public static List<string> shortMessagesList = new List<string> { "SURPRISE", "EXPLOSIONS" };

		public override string ID()
		{
			return "OnAPowderKeg";
		}

		public override int GetWeight()
		{
			return 10;
		}

		public override string GetDescription()
		{
			return "Landmines will detonate randomly. Spawns additional landmines.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			dayInSeconds = (int)HullManager.Instance.timeOfDay.lengthOfHours * HullManager.Instance.timeOfDay.numberOfHours;
			HullManager.AddChatEventMessage(this);
			levelModifier.AddLandmines(Plugin.LandmineScale * 2f / 3f);
			HullManager.Instance.ExecuteAfterDelay(delegate
			{
				DetonateLandMine(level);
			}, Random.Range(dayInSeconds / 6, dayInSeconds / 2));
			return true;
		}

		private async void DetonateLandMine(SelectableLevel level)
		{
			if ((Object)(object)level == (Object)null)
			{
				Plugin.Mls.LogError((object)"level is null");
				return;
			}
			Landmine[] landmines = Object.FindObjectsOfType<Landmine>();
			if (landmines.Count() == 0)
			{
				return;
			}
			Plugin.Mls.LogInfo((object)(ID() + $" Event: PowderKeg has been ignited. Will explode a landmine every {dayInSeconds / landmines.Count() / 30}-{dayInSeconds / landmines.Count() / 4} seconds."));
			foreach (var (landmine2, j) in landmines.Select((Landmine landmine, int i) => (landmine, i)))
			{
				Plugin.Mls.LogMessage((object)(ID() + $" Event: Random landmine explosion #{j + 1}"));
				landmine2.ExplodeMineServerRpc();
				await Task.Delay(TimeSpan.FromSeconds(Random.Range(dayInSeconds / landmines.Count() / 30, dayInSeconds / landmines.Count() / 4)));
			}
		}
	}
	public class OneForAllEvent : HullEvent
	{
		public override string ID()
		{
			return "OneForAll";
		}

		public override int GetWeight()
		{
			return 10;
		}

		public override string GetDescription()
		{
			return "The ship will leave within two hours after one of the workers has died.";
		}

		public override string GetMessage()
		{
			return "<color=white>You have been selected for team building measures!</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=red>ONE FOR ALL</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			EventsHandler.OneForAllIsActive = true;
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class OpenTheNoorEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "High security compound", "You shall not pass!", "Hodor - Hold the door!", "They locked this place down", "Abandoned on lockdown. All security doors are closed." };

		public static List<string> shortMessagesList = new List<string> { "HODOR", "OPEN THE NOOR" };

		public override string ID()
		{
			return "OpenTheNoor";
		}

		public override int GetWeight()
		{
			return 15;
		}

		public override string GetDescription()
		{
			return "All security doors spawn in closed state.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			if ((Object)(object)HullManager.Instance == (Object)null)
			{
				Plugin.Mls.LogError((object)"HullManager.Instance is null");
				return false;
			}
			if ((Object)(object)level == (Object)null)
			{
				Plugin.Mls.LogError((object)"level is null");
				return false;
			}
			HullManager.Instance.ExecuteAfterDelay(delegate
			{
				CloseBigDoors();
			}, 16f);
			HullManager.AddChatEventMessage(this);
			return true;
		}

		private void CloseBigDoors()
		{
			TerminalAccessibleObject[] array = Object.FindObjectsOfType<TerminalAccessibleObject>();
			TerminalAccessibleObject[] array2 = array;
			foreach (TerminalAccessibleObject val in array2)
			{
				val.SetDoorOpenServerRpc(false);
			}
		}
	}
	public class OutSideEnemyDayEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "This place was shrouded in darkness for weeks", "A prolonged eclipse has disrupted wild life's circadian rhythm", "Highly populated surface area", "Due to frequent weather events wildlife roams the surface during daytime" };

		public static List<string> shortMessagesList = new List<string> { "SILENCE SEASON", "OUTSIDE PARTY", "ECLIPSED?" };

		public override string ID()
		{
			return "OutSideEnemyDay";
		}

		public override int GetWeight()
		{
			return 10;
		}

		public override string GetDescription()
		{
			return "Increased amount of outside enemies during daytime. Eclipsed without eclipse.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			levelModifier.AddOutsideEnemySpawnChanceThroughoutDay(512);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class TimeAnomalyEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Gravity distorts space time. You better hurry!", "Let's go! In and out. Twenty minute adventure.", "Gravitional anomaly nearby! Time passes at a faster rate." };

		public static List<string> shortMessagesList = new List<string> { "TIME-" };

		public override string ID()
		{
			return "TimeAnomaly";
		}

		public override int GetWeight()
		{
			return 10;
		}

		public override string GetDescription()
		{
			return "Makes day shorter i.e. time passes faster";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			try
			{
				Random random = new Random();
				levelModifier.SetTimeScale((float)Math.Round(Random.Range(1.5f, 2f), 2));
			}
			catch (Exception ex)
			{
				Plugin.Mls.LogWarning((object)ex.Message);
				return false;
			}
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class TimeDilationEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Gravity distorts space time. Take your time!", "You have all the time you need.", "Gravitional anomaly distorts spacetime! Time passes at a slower rate." };

		public static List<string> shortMessagesList = new List<string> { "TIME+" };

		public override string ID()
		{
			return "TimeDilation";
		}

		public override int GetWeight()
		{
			return 5;
		}

		public override string GetDescription()
		{
			return "Makes day longer i.e. time passes slower";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			try
			{
				Random random = new Random();
				levelModifier.SetTimeScale((float)Math.Round(Random.Range(0.5f, 0.75f), 2));
			}
			catch (Exception ex)
			{
				Plugin.Mls.LogWarning((object)ex.Message);
				return false;
			}
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class TurretEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "High security compound", "It's right around the corner!", "Keep moving and don't get stuck!", "The company recommends bringing a bulletproof vest" };

		public static List<string> shortMessagesList = new List<string> { "TURRETS", "BULLET HELL" };

		public override string ID()
		{
			return "Turret";
		}

		public override int GetWeight()
		{
			return 20;
		}

		public override string GetDescription()
		{
			return "Spawns additional turrets inside.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			levelModifier.AddTurrets(Plugin.TurretScale);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
}
namespace HullBreakerCompany.Events.Enemy
{
	public class ArachnophobiaEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Dominated by hostile life form", "Dominant species detected", "This place is crawling..", "They have 8 eyes..", "Natural spider habitat" };

		public static List<string> shortMessagesList = new List<string> { "EIGHT EYES", "EIGHT LEGS" };

		public override string ID()
		{
			return "Arachnophobia";
		}

		public override int GetWeight()
		{
			return 10;
		}

		public override string GetDescription()
		{
			return "Increases bunker spider (SandSpider) spawn chance. Allows more than one to spawn.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			if (!levelModifier.IsEnemySpawnable(EnemyUtil.getEnemyByType(typeof(SandSpiderAI))))
			{
				return false;
			}
			levelModifier.AddEnemyComponentRarity(EnemyUtil.getEnemyByType(typeof(SandSpiderAI)), 100);
			levelModifier.AddEnemyComponentMaxCount(EnemyUtil.getEnemyByType(typeof(SandSpiderAI)), 5);
			levelModifier.AddEnemyComponentPower(EnemyUtil.getEnemyByType(typeof(SandSpiderAI)), 1);
			levelModifier.AddMaxEnemyPower(4);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class BeeEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Dominated by hostile life form", "Dominant species detected", "Sticky golden goodness", "Extract the bee hives!", "Don't get stung by bees!" };

		public static List<string> shortMessagesList = new List<string> { "BZZZZZ", "STICKY GOLD" };

		public override string ID()
		{
			return "Bee";
		}

		public override int GetWeight()
		{
			return 20;
		}

		public override string GetDescription()
		{
			return "Increases bee hive spawns outside";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			if (!levelModifier.IsDaytimeEnemySpawnable(EnemyUtil.getEnemyByType(typeof(RedLocustBees))))
			{
				return false;
			}
			levelModifier.AddDaytimeEnemyRarity(EnemyUtil.getEnemyByType(typeof(RedLocustBees)), 1000);
			levelModifier.AddDaytimeEnemySpawnChanceThroughoutDay(64);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class BoombaEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Cleaning crew's still around", "Mines left right and center", "Lots of mines and some.. are moving?" };

		public static List<string> shortMessagesList = new List<string> { "BOOM-BA" };

		public override string ID()
		{
			return "Boomba";
		}

		public override int GetWeight()
		{
			return 10;
		}

		public override string GetDescription()
		{
			return "Increases spawn chance of Boomba and there's more of them. Also spawns more landmines.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			if (!levelModifier.IsEnemySpawnable("Boomba"))
			{
				return false;
			}
			levelModifier.AddEnemyComponentRarity("Boomba", 100);
			levelModifier.AddEnemyComponentMaxCount("Boomba", 10);
			levelModifier.AddMaxEnemyPower(10);
			levelModifier.AddLandmines(Plugin.LandmineScale * 2f / 3f);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class ButlerEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Reports of paranormal activity", "Paranormal signature detected", "Someone is taking care of this place" };

		public static List<string> shortMessagesList = new List<string> { "BUTLER", "JANITOR" };

		public override string ID()
		{
			return "Butler";
		}

		public override int GetWeight()
		{
			return 5;
		}

		public override string GetDescription()
		{
			return "Increases spawn chance of butler and there's more of them";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			if (!levelModifier.IsEnemySpawnable(EnemyUtil.getEnemyByType(typeof(ButlerEnemyAI))))
			{
				return false;
			}
			levelModifier.AddEnemyComponentRarity(EnemyUtil.getEnemyByType(typeof(ButlerEnemyAI)), 100);
			levelModifier.AddEnemyComponentMaxCount(EnemyUtil.getEnemyByType(typeof(ButlerEnemyAI)), 4);
			levelModifier.AddEnemyComponentPower(EnemyUtil.getEnemyByType(typeof(ButlerEnemyAI)), 0);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class DevochkaPizdecEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Reports of paranormal activity", "Paranormal signature detected", "Workers were loosing their mind before they shut this place down. Extract what was left behind.", "Don't loose your head now!" };

		public static List<string> shortMessagesList = new List<string> { "PARANOID", "PLAYTIME " };

		public override string ID()
		{
			return "DevochkaPizdec";
		}

		public override int GetWeight()
		{
			return 5;
		}

		public override string GetDescription()
		{
			return "Increases Ghostgirl (Dressgirl) spawn chance. Allows more than one to spawn.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			if (!levelModifier.IsEnemySpawnable(EnemyUtil.getEnemyByType(typeof(DressGirlAI))))
			{
				return false;
			}
			levelModifier.AddEnemyComponentRarity(EnemyUtil.getEnemyByType(typeof(DressGirlAI)), 100);
			levelModifier.AddEnemyComponentMaxCount(EnemyUtil.getEnemyByType(typeof(DressGirlAI)), 4);
			levelModifier.AddEnemyComponentPower(EnemyUtil.getEnemyByType(typeof(DressGirlAI)), 1);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class FlowerManEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Reports of paranormal activity", "Paranormal signature detected", "Something is lurking in the shadows", "Are you afraid of the dark?", "Always behind you..", "White eyes watching you..", "Sometimes you don't want to win a staring contest!" };

		public static List<string> shortMessagesList = new List<string> { "STALKER", "FEAR OF THE DARK" };

		public override string ID()
		{
			return "FlowerMan";
		}

		public override int GetWeight()
		{
			return 10;
		}

		public override string GetDescription()
		{
			return "Increases Bracken (Flowerman) spawn chance. Allows more than one to spawn.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			if (!levelModifier.IsEnemySpawnable(EnemyUtil.getEnemyByType(typeof(FlowermanAI))))
			{
				return false;
			}
			levelModifier.AddEnemyComponentRarity(EnemyUtil.getEnemyByType(typeof(FlowermanAI)), 100);
			levelModifier.AddEnemyComponentMaxCount(EnemyUtil.getEnemyByType(typeof(FlowermanAI)), 4);
			levelModifier.AddEnemyComponentPower(EnemyUtil.getEnemyByType(typeof(FlowermanAI)), 1);
			HullManager.AddChatEventMessage(this);
			return true;
		}
	}
	public class HellEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "What's in the box?!", "Upon encounter evacuate immediately!", "Sir, I'm going to have to ask you to leave.", "The company wishes the best of luck!" };

		public static List<string> shortMessagesList = new List<string> { "HELL", "LEAVE" };

		public override string ID()
		{
			return "Hell";
		}

		public override int GetWeight()
		{
			return 1;
		}

		public override string GetDescription()
		{
			return "Increases Jester spawn chance. Allows more than one to spawn.";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			if (!levelModifier.IsEnemySpawnable(EnemyUtil.getEnemyByType(typeof(JesterAI))))
			{
				return false;
			}
			levelModifier.AddEnemyComponentRarity(EnemyUtil.getEnemyByType(typeof(JesterAI)), 100);
			levelModifier.AddEnemyComponentMaxCount(EnemyUtil.getEnemyByType(typeof(JesterAI)), 4);
			levelModifier.AddEnemyComponentPower(EnemyUtil.getEnemyByType(typeof(JesterAI)), 1);
			HullManager.AddChatEventMessage(this);
			return true;
		}

		private void Hell()
		{
			EnemyVent[] array = Object.FindObjectsOfType<EnemyVent>();
			for (int i = 0; i < 8; i++)
			{
				if (array.Length != 0)
				{
					EnemyVent val = array[Random.Range(0, array.Length)];
					RoundManager.Instance.SpawnEnemyFromVent(val);
				}
			}
		}
	}
	public class HerobrineEvent : HullEvent
	{
		public static List<string> MessagesList = new List<string> { "Removed.", "Don't turn around.." };

		public static List<string> shortMessagesList = new List<string> { "HAUNTED", "REMOVED" };

		public override string ID()
		{
			return "Herobrine";
		}

		public override int GetWeight()
		{
			return 5;
		}

		public override string GetDescription()
		{
			return "Guarantees Herobrine spawn. Herobrine doesn't reduce the amount of other enemies (doesn't add to global power)";
		}

		public override string GetMessage()
		{
			return "<color=white>" + MessagesList[Random.Range(0, MessagesList.Count)] + "</color>";
		}

		public override string GetShortMessage()
		{
			return "<color=white>" + shortMessagesList[Random.Range(0, shortMessagesList.Count)] + "</color>";
		}

		public override bool Execute(SelectableLevel level, LevelModifier levelModifier)
		{
			if (!levelModifier.IsEnemySpawnable("Herobrine"))
			{
				return false;
			}
			levelModifier.AddEnemyComponentRarity("Herobrine", 1000);
			levelModifier.AddEnemyComponentPower("Herobrine", 1);
			levelModifier.AddMaxEnemyPower(1);
			HullManager.AddCha