Decompiled source of ChaosCompany v1.2.5

ChaosCompany.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using ChaosCompany.Scripts.Abstracts;
using ChaosCompany.Scripts.Components;
using ChaosCompany.Scripts.DataStructures;
using ChaosCompany.Scripts.Entities;
using ChaosCompany.Scripts.Items;
using ChaosCompany.Scripts.Managers;
using ChaosCompany.Scripts.Patches;
using Dissonance.Integrations.Unity_NFGO;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ChaosCompany")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("It's unpredictable chaos can you survive?")]
[assembly: AssemblyFileVersion("1.2.5.0")]
[assembly: AssemblyInformationalVersion("1.2.5+6f6be5ce8483c7c7e8198489f2f482d770ad0542")]
[assembly: AssemblyProduct("ChaosCompany")]
[assembly: AssemblyTitle("ChaosCompany")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.5.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ChaosCompany
{
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ChaosCompany";

		public const string PLUGIN_NAME = "ChaosCompany";

		public const string PLUGIN_VERSION = "1.2.5";
	}
}
namespace ChaosCompany.Scripts
{
	[BepInPlugin("ChaosCompany", "ChaosCompany", "1.2.5")]
	public class Plugin : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("ChaosCompany");

		public static ManualLogSource Logger { get; private set; } = Logger.CreateLogSource("ChaosCompany");


		private void Awake()
		{
			Logger.LogInfo((object)"Plugin ChaosCompany is loaded! yeah baby!!!");
			harmony.PatchAll(Assembly.GetExecutingAssembly());
		}
	}
}
namespace ChaosCompany.Scripts.Patches
{
	[HarmonyPatch(typeof(DepositItemsDesk))]
	internal static class DepositItemsDeskPatch
	{
		public static HashSet<float> soundVolumes = new HashSet<float>();

		private static int timesHearingNoise = 0;

		public static Timer consecutiveNoiseDelay = new Timer(3f, oneshot: false);

		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void StartPostfix(DepositItemsDesk __instance)
		{
			if (NetworkManager.Singleton.IsServer)
			{
				GameManager.Timers.Add(consecutiveNoiseDelay);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("SetTimesHeardNoiseServerRpc")]
		private static void SetTimesHeardNoiseServerRpcPostfix(DepositItemsDesk __instance, ref float valueChange)
		{
			if (!NetworkManager.Singleton.IsServer)
			{
				return;
			}
			int num = 0;
			bool flag = false;
			foreach (float soundVolume in soundVolumes)
			{
				if (soundVolume < valueChange)
				{
					num++;
				}
				if (MathF.Abs(soundVolume - valueChange) <= 0.1f)
				{
					flag = true;
				}
			}
			if (flag && num < 1)
			{
				return;
			}
			if (num < 1 || soundVolumes.Count == 0)
			{
				soundVolumes.Add(valueChange);
				return;
			}
			soundVolumes.Add(valueChange);
			consecutiveNoiseDelay.Restart();
			consecutiveNoiseDelay.OnTimeout += delegate
			{
				timesHearingNoise = 0;
				consecutiveNoiseDelay.Stop();
			};
			if (timesHearingNoise > 2 && timesHearingNoise < 8)
			{
				__instance.MakeWarningNoiseClientRpc();
			}
			else if (timesHearingNoise >= 8)
			{
				__instance.AttackPlayersServerRpc();
				timesHearingNoise = 0;
				return;
			}
			timesHearingNoise++;
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager))]
	public class GameNetworkManagerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("DisconnectProcess")]
		private static void DisconnectProcessPostfix()
		{
			if (NetworkManager.Singleton.IsServer)
			{
				if (TimeOfDayPatch.Instance != null)
				{
					TimeOfDayPatch.Instance.quotaVariables.deadlineDaysAmount = Random.Range(4, 7);
				}
				GameManager.gameOver = true;
				Plugin.Logger.LogError((object)"Game Ended");
				GameManager.Reset();
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal static class PlayerControllerBPatch
	{
		public static bool isEnemyAlreadySpawnedOnItemPosition;

		[HarmonyPrefix]
		[HarmonyPatch("StartSinkingServerRpc")]
		private static void StartSinkingServerRpcPrefix(ref float sinkingSpeed, ref int audioClipIndex)
		{
			if (NetworkManager.Singleton.IsServer)
			{
				sinkingSpeed *= Random.Range(0.25f, 2f);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("DamagePlayerServerRpc")]
		private static void DamagePlayerServerRpcPrefix(ref int damageNumber, ref int newHealthAmount)
		{
			if (NetworkManager.Singleton.IsServer)
			{
				damageNumber = (int)((float)damageNumber * Random.Range(0.25f, 1f));
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("GrabObjectServerRpc")]
		private static void GrabObjectServerRpcPostfix(PlayerControllerB __instance, ref NetworkObjectReference grabbedObject)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			NetworkObject val = default(NetworkObject);
			if (!NetworkManager.Singleton.IsServer || (Object)(object)__instance == (Object)null || (Object)(object)NetworkManager.Singleton == (Object)null || (Object)(object)RoundManagerPatch.Instance == (Object)null || !((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, NetworkManager.Singleton))
			{
				return;
			}
			ChaoticItemAdditionalData component = ((Component)val).GetComponent<ChaoticItemAdditionalData>();
			if (component != null)
			{
				component.pickedUp = true;
			}
			if (RoundManagerPatch.Instance.currentLevel.Enemies.Count == 0 || isEnemyAlreadySpawnedOnItemPosition || __instance.isInElevator || Random.Range(0, 100) != 0)
			{
				return;
			}
			if (__instance.isInsideFactory)
			{
				var (val2, val3) = GameManager.SpawnRandomEnemy(RoundManagerPatch.Instance, inside: true, ((Component)val).transform.position, 0f, new List<string>(2) { "dressedgirl", "nutcracker" });
				if ((Object)(object)val2 == (Object)null)
				{
					return;
				}
			}
			else if (!__instance.isInsideFactory && !__instance.isInHangarShipRoom)
			{
				var (val4, val5) = GameManager.SpawnRandomEnemy(RoundManagerPatch.Instance, inside: false, ((Component)val).transform.position, 0f, new List<string>(4) { "mech", "worm", "dog", "double" });
				if ((Object)(object)val4 == (Object)null)
				{
					return;
				}
			}
			isEnemyAlreadySpawnedOnItemPosition = true;
			Timer timer = new Timer(1f, oneshot: true);
			timer.OnTimeout += delegate
			{
				isEnemyAlreadySpawnedOnItemPosition = false;
			};
			timer.Start();
			GameManager.Timers.Add(timer);
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	internal static class RoundManagerPatch
	{
		public static RoundManager? Instance { get; private set; }

		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void StartPostfix(RoundManager __instance)
		{
			if (NetworkManager.Singleton.IsServer)
			{
				Plugin.Logger.LogError((object)"Round Manager start method get called");
				GameManager.Reset();
				Instance = __instance;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		private static void UpdatePrefix()
		{
			if (!NetworkManager.Singleton.IsServer)
			{
				return;
			}
			for (int num = GameManager.Timers.Count - 1; num >= 0; num--)
			{
				GameManager.Timers[num].Update();
				if (GameManager.Timers[num].Finished)
				{
					GameManager.Timers.RemoveAt(num);
				}
			}
			if (Instance == null || GameManager.gameOver || !Instance.dungeonFinishedGeneratingForAllPlayers || Instance.allEnemyVents.Length == 0)
			{
				return;
			}
			for (int num2 = GameManager.chaoticEntities.Count - 1; num2 >= 0; num2--)
			{
				GameManager.chaoticEntities[num2].Update();
				if (GameManager.chaoticEntities[num2].ItsJoever)
				{
					if (GameManager.chaoticEntities[num2] is ChaoticEnemy)
					{
						Timer timer = new Timer(Random.Range(120, 150), oneshot: true);
						timer.OnTimeout += delegate
						{
							GameManager.SpawnChaoticEnemy(Instance);
						};
						timer.Start();
						GameManager.Timers.Add(timer);
					}
					GameManager.chaoticEntities.RemoveAt(num2);
				}
			}
			if (GameManager.beginChaos)
			{
				return;
			}
			GameManager.StartSpawning(Instance);
			Plugin.Logger.LogError((object)"Chaos is starting");
			Timer timer2 = new Timer(5f, oneshot: true);
			timer2.OnTimeout += delegate
			{
				for (int i = 0; i < GameManager.maxChaoticItemSpawn; i++)
				{
					GameManager.SpawnChaoticItem(Instance);
				}
			};
			timer2.Start();
			GameManager.Timers.Add(timer2);
			GameManager.spawnEnemyTimer.Start();
			GameManager.beginChaos = true;
		}

		[HarmonyPrefix]
		[HarmonyPatch("DetectElevatorIsRunning")]
		private static void DetectElevatorIsRunningPrefix()
		{
			if (NetworkManager.Singleton.IsServer)
			{
				if (TimeOfDayPatch.Instance != null)
				{
					TimeOfDayPatch.Instance.quotaVariables.deadlineDaysAmount = Random.Range(4, 7);
				}
				GameManager.gameOver = true;
				GameManager.Reset();
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	public class StartOfRoundPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("SceneManager_OnLoad")]
		private static void SceneManager_OnLoadPatch(StartOfRound __instance, ulong clientId, ref string sceneName, ref LoadSceneMode loadSceneMode, ref AsyncOperation asyncOperation)
		{
			if (NetworkManager.Singleton.IsServer)
			{
				Random.InitState(__instance.randomMapSeed);
				Plugin.Logger.LogError((object)("Game Starting with level " + sceneName));
				if (sceneName != "CompanyBuilding")
				{
					GameManager.gameOver = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(TimeOfDay))]
	internal static class TimeOfDayPatch
	{
		public static TimeOfDay? Instance { get; set; }

		[HarmonyPrefix]
		[HarmonyPatch("Awake")]
		private static void AwakePrefix(TimeOfDay __instance)
		{
			if (NetworkManager.Singleton.IsServer)
			{
				if ((Object)(object)Instance == (Object)null)
				{
					__instance.quotaVariables.deadlineDaysAmount = Random.Range(4, 7);
					__instance.SyncTimeClientRpc(__instance.globalTime, (int)__instance.timeUntilDeadline);
				}
				Instance = __instance;
				GameManager.timeMultiplier = Random.Range(0.25f, 1.75f);
				GameManager.spawnEnemyTimer = new Timer(180f * (1f / GameManager.timeMultiplier), oneshot: false);
				__instance.globalTimeSpeedMultiplier = GameManager.timeMultiplier;
			}
		}
	}
}
namespace ChaosCompany.Scripts.Managers
{
	public enum EnemySpawnType
	{
		Inside,
		Outside
	}
	public static class GameManager
	{
		public static bool gameOver;

		public static Timer spawnEnemyTimer = new Timer(Random.Range(180, 240), oneshot: false);

		public static EnemySpawnType[] spawnTypes = new EnemySpawnType[2]
		{
			EnemySpawnType.Inside,
			EnemySpawnType.Outside
		};

		public static List<Chaotic> chaoticEntities = new List<Chaotic>();

		public static int numberOfTriesOfSpawningRandomEnemyNearPlayer = 6;

		public static int modMaxEnemyNumber = Random.Range(2, 4);

		public static int modEnemyNumber = 0;

		public static int maxChaoticEnemySpawn = 2;

		public static int maxMoveEnemySpawn = 2;

		public static int maxChaoticItemSpawn = Random.Range(2, 5);

		public static bool beginChaos;

		public static float timeMultiplier;

		public static List<Timer> Timers { get; private set; } = new List<Timer>();


		public static void Reset()
		{
			Plugin.Logger.LogError((object)"Game Reset");
			Timers.Clear();
			foreach (Chaotic chaoticEntity in chaoticEntities)
			{
				if ((Object)(object)chaoticEntity.NetworkObject == (Object)null)
				{
					Plugin.Logger.LogError((object)"Despawning chaotic entities failed because network object == null");
					continue;
				}
				if (!chaoticEntity.NetworkObject.IsSpawned)
				{
					Plugin.Logger.LogError((object)"chaoticEntity is not spawned on the network");
					continue;
				}
				if (chaoticEntity is ChaoticEnemy chaoticEnemy)
				{
					if ((Object)(object)chaoticEnemy.EnemyAI == (Object)null)
					{
						Plugin.Logger.LogError((object)"chaoticEnemy.EnemyAI == null while trying to print the enemy");
						chaoticEntity.NetworkObject.Despawn(true);
						continue;
					}
					Plugin.Logger.LogError((object)("Despawning chaotic enemy " + chaoticEnemy.EnemyAI.enemyType.enemyName));
				}
				else if (chaoticEntity is MoveEnemy moveEnemy)
				{
					if ((Object)(object)moveEnemy.EnemyAI == (Object)null)
					{
						Plugin.Logger.LogError((object)"moveEnemy.EnemyAI == null while trying to print the enemy");
						chaoticEntity.NetworkObject.Despawn(true);
						continue;
					}
					Plugin.Logger.LogError((object)("Despawning move enemy " + moveEnemy.EnemyAI.enemyType.enemyName));
				}
				else if (chaoticEntity is ChaoticItem)
				{
					Plugin.Logger.LogError((object)"Despawning chaotic item");
				}
				chaoticEntity.NetworkObject.Despawn(true);
			}
			PlayerControllerBPatch.isEnemyAlreadySpawnedOnItemPosition = false;
			chaoticEntities.Clear();
			modEnemyNumber = 0;
			maxChaoticItemSpawn = Random.Range(2, 5);
			modMaxEnemyNumber = Random.Range(2, 4);
			maxChaoticEnemySpawn = 2;
			maxMoveEnemySpawn = 2;
			beginChaos = false;
			numberOfTriesOfSpawningRandomEnemyNearPlayer = 6;
		}

		public static (EnemyType?, NetworkObjectReference?) SpawnRandomEnemy(RoundManager roundManager, bool inside, Vector3 position, float yRotation = 0f, List<string>? exclusion = null)
		{
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Logger.LogError((object)"Trying to spawn random enemy");
			List<SpawnableEnemyWithRarity> list;
			if (inside)
			{
				list = roundManager.currentLevel.Enemies;
			}
			else
			{
				List<SpawnableEnemyWithRarity> outsideEnemies = roundManager.currentLevel.OutsideEnemies;
				outsideEnemies.AddRange(roundManager.currentLevel.DaytimeEnemies);
				list = outsideEnemies;
			}
			int count = list.Count;
			if (count == 0)
			{
				Plugin.Logger.LogError((object)"Cannot spawn enemy, enemiesTypes list is empty");
				return (null, null);
			}
			SpawnableEnemyWithRarity val = list[Random.Range(0, count)];
			bool flag = false;
			if (exclusion != null)
			{
				foreach (string item in exclusion)
				{
					string text = ((object)val.enemyType).ToString().ToLower().Trim();
					string text2 = item.ToLower().Trim();
					if (text.Contains(text2) || text == text2)
					{
						flag = true;
						break;
					}
				}
				int num = 20;
				while (flag && num != 0)
				{
					val = list[Random.Range(0, count)];
					flag = false;
					foreach (string item2 in exclusion)
					{
						string text3 = ((object)val.enemyType).ToString().ToLower().Trim();
						if (text3.Contains(item2.ToLower().Trim()))
						{
							flag = true;
							break;
						}
					}
					num--;
				}
			}
			if (flag)
			{
				Plugin.Logger.LogError((object)"Cannot spawn enemy all of the enemies level in the map is in the exclusion list");
				return (null, null);
			}
			NetworkObjectReference value = roundManager.SpawnEnemyGameObject(position, yRotation, -1, val.enemyType);
			NetworkObject val2 = default(NetworkObject);
			((NetworkObjectReference)(ref value)).TryGet(ref val2, (NetworkManager)null);
			return (val.enemyType, value);
		}

		public static PlayerControllerB? GetClosestPlayerWithLineOfSight(RoundManager roundManager, EnemyAI enemyAI)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			List<PlayerControllerB> list = roundManager.playersManager.allPlayerScripts.ToList();
			for (int num = list.Count - 1; num >= 0; num--)
			{
				if (list[num].isPlayerDead)
				{
					list.RemoveAt(num);
				}
			}
			if (list.Count == 0)
			{
				return null;
			}
			PlayerControllerB val = list[0];
			for (int i = 0; i < list.Count; i++)
			{
				if (enemyAI.CheckLineOfSightForPosition(((Component)((NetworkBehaviour)list[i]).NetworkObject).transform.position, 360f, 100000, -1f, (Transform)null) && !list[i].isPlayerDead && Vector3.Distance(((Component)((NetworkBehaviour)list[i]).NetworkObject).transform.position, ((Component)((NetworkBehaviour)enemyAI).NetworkObject).transform.position) < Vector3.Distance(((Component)((NetworkBehaviour)val).NetworkObject).transform.position, ((Component)((NetworkBehaviour)enemyAI).NetworkObject).transform.position))
				{
					val = list[i];
				}
			}
			return val;
		}

		public static PlayerControllerB? GetRandomAlivePlayer(RoundManager roundManager, bool inside)
		{
			Plugin.Logger.LogError((object)"Trying to get random alive player");
			List<PlayerControllerB> list = roundManager.playersManager.allPlayerScripts.ToList();
			int count = list.Count;
			if (count == 0)
			{
				Plugin.Logger.LogError((object)"No player is online lmao");
				return null;
			}
			PlayerControllerB val = list[Random.Range(0, count)];
			int num = list.Count;
			int num2 = 20;
			while ((val.isInsideFactory != inside || (Object)(object)val.deadBody != (Object)null) && num2 != 0)
			{
				list.Remove(val);
				if (list.Count == 0)
				{
					return null;
				}
				val = list[Random.Range(0, list.Count)];
				num--;
				if (num <= 0)
				{
					return null;
				}
				num2--;
			}
			if (val.isInsideFactory != inside && (Object)(object)val.deadBody != (Object)null)
			{
				return null;
			}
			return val;
		}

		public static void SpawnRandomEnemyNearRandomPlayer(RoundManager roundManager, bool inside)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			RoundManager roundManager2 = roundManager;
			if (roundManager2.playersManager.allPlayerScripts.Length == 0)
			{
				Plugin.Logger.LogError((object)"Cannot spawn enemy there is no player");
				return;
			}
			PlayerControllerB randomAlivePlayer = GetRandomAlivePlayer(roundManager2, inside);
			if ((Object)(object)randomAlivePlayer == (Object)null)
			{
				return;
			}
			Vector3 targetPositionPrevious = ((Component)randomAlivePlayer).gameObject.GetComponent<NfgoPlayer>().Position;
			Timer timer = new Timer(10f, oneshot: true);
			timer.OnTimeout += delegate
			{
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00be: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_015d: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)randomAlivePlayer.deadBody != (Object)null || randomAlivePlayer.isInsideFactory != inside)
				{
					if (numberOfTriesOfSpawningRandomEnemyNearPlayer != 0)
					{
						SpawnRandomEnemyNearRandomPlayer(roundManager2, inside);
						numberOfTriesOfSpawningRandomEnemyNearPlayer--;
					}
				}
				else
				{
					Vector3 position = ((Component)randomAlivePlayer).gameObject.GetComponent<NfgoPlayer>().Position;
					int num = 20;
					if (Vector3.Distance(targetPositionPrevious, position) <= (float)num)
					{
						if (numberOfTriesOfSpawningRandomEnemyNearPlayer != 0)
						{
							SpawnRandomEnemyNearRandomPlayer(roundManager2, inside);
							numberOfTriesOfSpawningRandomEnemyNearPlayer--;
						}
					}
					else
					{
						bool flag = false;
						PlayerControllerB[] allPlayerScripts = roundManager2.playersManager.allPlayerScripts;
						foreach (PlayerControllerB val in allPlayerScripts)
						{
							if (Vector3.Distance(((Component)val).transform.position, targetPositionPrevious) <= (float)num)
							{
								flag = true;
								break;
							}
						}
						if (flag)
						{
							if (numberOfTriesOfSpawningRandomEnemyNearPlayer != 0)
							{
								SpawnRandomEnemyNearRandomPlayer(roundManager2, inside);
								numberOfTriesOfSpawningRandomEnemyNearPlayer--;
							}
						}
						else
						{
							if (inside)
							{
								var (val2, val3) = SpawnRandomEnemy(roundManager2, inside: true, targetPositionPrevious, 0f, new List<string>(1) { "DressGirl" });
								if ((Object)(object)val2 == (Object)null)
								{
									return;
								}
							}
							else
							{
								var (val4, val5) = SpawnRandomEnemy(roundManager2, inside: false, targetPositionPrevious, 0f, new List<string>(3) { "mech", "worm", "double" });
								if ((Object)(object)val4 == (Object)null)
								{
									return;
								}
							}
							numberOfTriesOfSpawningRandomEnemyNearPlayer = 6;
						}
					}
				}
			};
			Timers.Add(timer);
			timer.Start();
		}

		public static void SpawnChaoticItem(RoundManager roundManager)
		{
			if ((Object)(object)roundManager == (Object)null)
			{
				Plugin.Logger.LogError((object)"roundManager == null");
				return;
			}
			ChaoticItem chaoticItem = new ChaoticItem(roundManager);
			if (chaoticItem.Spawn() == null)
			{
				Plugin.Logger.LogError((object)"Cannot spawn chaotic item");
			}
			else
			{
				chaoticEntities.Add(chaoticItem);
			}
		}

		public static NetworkObjectReference? SwitchToRandomEnemyType(RoundManager roundManager, EnemyAI? enemyTarget, bool inside, NetworkObject networkObject)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Logger.LogError((object)"Trying to switch an enemy type to random enemy");
			if ((Object)(object)enemyTarget == (Object)null)
			{
				Plugin.Logger.LogError((object)"enemyTarget target == null");
				return null;
			}
			if ((Object)(object)enemyTarget.thisNetworkObject == (Object)null)
			{
				Plugin.Logger.LogError((object)"enemyTarget.thisNetworkObject == null");
				return null;
			}
			if (roundManager?.currentLevel.Enemies == null)
			{
				Plugin.Logger.LogError((object)"roundManager?.currentLevel.Enemies == null");
				return null;
			}
			if (!((NetworkBehaviour)enemyTarget).IsSpawned)
			{
				Plugin.Logger.LogError((object)"!enemyTarget.IsSpawned");
				return null;
			}
			var (val, result) = SpawnRandomEnemy(roundManager, inside, ((Component)enemyTarget.thisNetworkObject).transform.position, 0f, new List<string>(6) { "cave", "double", "redlocust", "DressGirl", "Nutcracker", "Spider" });
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Logger.LogError((object)"enemySpawnedType == null");
				return null;
			}
			if (!result.HasValue)
			{
				Plugin.Logger.LogError((object)"networkObjectReference == null");
				return null;
			}
			enemyTarget.KillEnemyOnOwnerClient(true);
			if (((NetworkBehaviour)enemyTarget).IsSpawned)
			{
				networkObject.Despawn(true);
			}
			return result;
		}

		public static void SpawnChaoticEnemy(RoundManager roundManager)
		{
			ChaoticEnemy chaoticEnemy = new ChaoticEnemy(roundManager, Random.Range(0f, 1f) > 0.2f);
			if (chaoticEnemy.Spawn() == null)
			{
				Plugin.Logger.LogError((object)"Cannot spawn chaotic enemy");
			}
			else
			{
				chaoticEntities.Add(chaoticEnemy);
			}
		}

		public static void SpawnMoveEnemy(RoundManager roundManager)
		{
			MoveEnemy moveEnemy = new MoveEnemy(roundManager, Random.Range(0f, 1f) > 0.5f);
			if (moveEnemy.Spawn() == null)
			{
				Plugin.Logger.LogError((object)"Cannot spawn move enemy");
			}
			else
			{
				chaoticEntities.Add(moveEnemy);
			}
		}

		public static void StartSpawning(RoundManager roundManager)
		{
			RoundManager roundManager2 = roundManager;
			Plugin.Logger.LogError((object)"Start spawning enemies");
			if ((Object)(object)roundManager2 == (Object)null)
			{
				Plugin.Logger.LogError((object)"Cannot spawn monster roundManager == null");
				return;
			}
			spawnEnemyTimer.OnTimeout += delegate
			{
				//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0218: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0341: Unknown result type (might be due to invalid IL or missing references)
				//IL_0346: Unknown result type (might be due to invalid IL or missing references)
				//IL_034e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0357: Unknown result type (might be due to invalid IL or missing references)
				//IL_035d: Unknown result type (might be due to invalid IL or missing references)
				//IL_037c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0381: Unknown result type (might be due to invalid IL or missing references)
				//IL_0389: Unknown result type (might be due to invalid IL or missing references)
				//IL_0394: Unknown result type (might be due to invalid IL or missing references)
				//IL_0399: Unknown result type (might be due to invalid IL or missing references)
				//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
				if (modEnemyNumber >= modMaxEnemyNumber)
				{
					spawnEnemyTimer.Stop();
					return;
				}
				if (Random.Range(0f, 1f) > 0.5f)
				{
					if (Random.Range(0f, 1f) > 0.5f)
					{
						if (maxChaoticEnemySpawn != 0)
						{
							SpawnChaoticEnemy(roundManager2);
							maxChaoticEnemySpawn--;
							return;
						}
					}
					else if (maxMoveEnemySpawn != 0)
					{
						SpawnMoveEnemy(roundManager2);
						maxMoveEnemySpawn--;
						return;
					}
				}
				float num = Random.Range(0, 100);
				EnemySpawnType enemySpawnType = ((num <= 30f) ? EnemySpawnType.Outside : EnemySpawnType.Inside);
				if (Random.Range(0, 100) < 10)
				{
					roundManager2.SwitchPower(false);
					int num2 = Random.Range(30, 180);
					HUDManager.Instance.AddTextToChatOnServer("Warning: There is a power outage for " + TimeSpan.FromSeconds(num2).ToString("mm\\:ss"), -1);
					Timer timer = new Timer(num2, oneshot: true);
					timer.OnTimeout += delegate
					{
						roundManager2.SwitchPower(true);
					};
					timer.Start();
					Timers.Add(timer);
				}
				try
				{
					switch (enemySpawnType)
					{
					case EnemySpawnType.Inside:
						if (Random.Range(0, 100) <= 20)
						{
							SpawnRandomEnemyNearRandomPlayer(roundManager2, inside: true);
							modEnemyNumber++;
						}
						else
						{
							int num4 = roundManager2.allEnemyVents.Length;
							if (num4 == 0)
							{
								Plugin.Logger.LogError((object)"Cannot spawn enemy on the vent because there is no vent available");
							}
							else
							{
								EnemyVent val2 = roundManager2.allEnemyVents[Random.Range(0, num4)];
								Vector3 randomNavMeshPositionInBoxPredictable = val2.floorNode.position;
								float y = val2.floorNode.eulerAngles.y;
								if (Random.Range(0f, 1f) <= 0.5f)
								{
									var (val3, val4) = SpawnRandomEnemy(roundManager2, inside: true, randomNavMeshPositionInBoxPredictable, y);
									if ((Object)(object)val3 == (Object)null)
									{
										break;
									}
									val2.OpenVentClientRpc();
								}
								else
								{
									var (val5, val6) = SpawnRandomEnemy(roundManager2, inside: false, randomNavMeshPositionInBoxPredictable, 0f, new List<string>(3) { "giant", "worm", "double" });
									if ((Object)(object)val5 == (Object)null)
									{
										Plugin.Logger.LogError((object)"Cannot spawn enemy inside");
										break;
									}
									val2.OpenVentClientRpc();
								}
								modEnemyNumber++;
							}
						}
						break;
					case EnemySpawnType.Outside:
						if (Random.Range(0, 100) <= 20)
						{
							SpawnRandomEnemyNearRandomPlayer(roundManager2, inside: false);
							modEnemyNumber++;
						}
						else
						{
							int count = roundManager2.currentLevel.OutsideEnemies.Count;
							if (count == 0)
							{
								Plugin.Logger.LogError((object)"Cannot spawn enemy outside, no enemy list available");
							}
							else
							{
								SpawnableEnemyWithRarity val = roundManager2.currentLevel.OutsideEnemies[Random.Range(0, count)];
								GameObject[] array = GameObject.FindGameObjectsWithTag("OutsideAINode");
								int num3 = array.Length;
								if (num3 == 0)
								{
									Plugin.Logger.LogError((object)"Cannot spawn enemy outside, no spawn point available");
								}
								else
								{
									Vector3 position = array[Random.Range(0, num3)].transform.position;
									Vector3 randomNavMeshPositionInBoxPredictable = roundManager2.GetRandomNavMeshPositionInBoxPredictable(position, 10f, default(NavMeshHit), roundManager2.AnomalyRandom, roundManager2.GetLayermaskForEnemySizeLimit(val.enemyType));
									randomNavMeshPositionInBoxPredictable = roundManager2.PositionWithDenialPointsChecked(randomNavMeshPositionInBoxPredictable, array, val.enemyType);
									roundManager2.SpawnEnemyGameObject(randomNavMeshPositionInBoxPredictable, 0f, -1, val.enemyType);
									modEnemyNumber++;
								}
							}
						}
						break;
					}
				}
				catch (Exception ex)
				{
					Plugin.Logger.LogError((object)ex);
				}
			};
			Timers.Add(spawnEnemyTimer);
		}
	}
}
namespace ChaosCompany.Scripts.Items
{
	public class ChaoticItem : Chaotic
	{
		private Timer changeType;

		public ChaoticItem(RoundManager roundManager)
			: base(roundManager)
		{
			changeType = new Timer(1f, oneshot: false);
			changeType.OnTimeout += delegate
			{
				if (!((Object)(object)base.NetworkObject == (Object)null))
				{
					GrabbableObject component = ((Component)base.NetworkObject).gameObject.GetComponent<GrabbableObject>();
					if (component != null)
					{
						ChaoticItemAdditionalData component2 = ((Component)base.NetworkObject).gameObject.GetComponent<ChaoticItemAdditionalData>();
						if (component2 != null && component2.pickedUp)
						{
							changeType.Stop();
							changeType.Finished = true;
							base.ItsJoever = true;
						}
						component.scrapValue = Random.Range(10, 150);
					}
				}
			};
			GameManager.Timers.Add(changeType);
		}

		public override void Update()
		{
			if (!((Object)(object)base.NetworkObject == (Object)null) && ((Component)base.NetworkObject).gameObject.GetComponent<GrabbableObject>().isHeld)
			{
				changeType.Stop();
				changeType.Finished = true;
				base.ItsJoever = true;
			}
		}

		public override Chaotic? Spawn()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			if (base.RoundManager.currentLevel.spawnableScrap.Count == 0)
			{
				Plugin.Logger.LogError((object)"No spawnable scrap in the level");
				return null;
			}
			SpawnableItemWithRarity val = base.RoundManager.currentLevel.spawnableScrap[Random.Range(0, base.RoundManager.currentLevel.spawnableScrap.Count)];
			RandomScrapSpawn[] array = Object.FindObjectsOfType<RandomScrapSpawn>();
			if (array.Length == 0)
			{
				Plugin.Logger.LogError((object)"randomScrapSpawnArray is empty");
				return null;
			}
			RandomScrapSpawn val2 = array[Random.Range(0, array.Length)];
			Vector3 val3 = base.RoundManager.GetRandomNavMeshPositionInBoxPredictable(((Component)val2).transform.position, val2.itemSpawnRange, base.RoundManager.navHit, base.RoundManager.AnomalyRandom, -1) + Vector3.up * val.spawnableItem.verticalOffset;
			GameObject val4 = Object.Instantiate<GameObject>(val.spawnableItem.spawnPrefab, val3 + new Vector3(0f, 0.5f, 0f), Quaternion.identity);
			GrabbableObject component = val4.GetComponent<GrabbableObject>();
			((Component)component).transform.rotation = Quaternion.Euler(component.itemProperties.restingRotation);
			component.fallTime = 0f;
			component.scrapValue = Random.Range(5, 150);
			((NetworkBehaviour)component).NetworkObject.Spawn(false);
			base.NetworkObject = ((NetworkBehaviour)component).NetworkObject;
			((Component)base.NetworkObject).gameObject.AddComponent<ChaoticItemAdditionalData>();
			changeType.Start();
			return this;
		}
	}
}
namespace ChaosCompany.Scripts.Extensions
{
	public static class Vector2Extension
	{
		public static Vector2 RotateDegrees(this Vector2 value, float degrees)
		{
			float x = MathF.PI / 180f * degrees;
			float num = MathF.Cos(x);
			float num2 = MathF.Sin(x);
			return new Vector2(num * value.X - num2 * value.Y, num2 * value.X + num * value.Y);
		}
	}
}
namespace ChaosCompany.Scripts.Entities
{
	public class ChaoticEnemy : ChaoticEntities
	{
		private Timer changeType;

		private bool isChaoticEnemyAlreadyTryingToChange;

		public ChaoticEnemy(RoundManager roundManager, bool inside)
		{
			RoundManager roundManager2 = roundManager;
			base..ctor(roundManager2, inside, new List<string>(7) { "DocileLocust", "cave", "DressGirl", "Nutcracker", "Spider", "double", "Red" });
			ChaoticEnemy chaoticEnemy = this;
			changeType = new Timer(10f, oneshot: false);
			changeType.OnTimeout += delegate
			{
				//IL_015d: Unknown result type (might be due to invalid IL or missing references)
				if (!GameManager.gameOver)
				{
					if (chaoticEnemy.isChaoticEnemyAlreadyTryingToChange)
					{
						chaoticEnemy.isChaoticEnemyAlreadyTryingToChange = !chaoticEnemy.isChaoticEnemyAlreadyTryingToChange;
					}
					else if ((Object)(object)chaoticEnemy.NetworkObject == (Object)null)
					{
						Plugin.Logger.LogError((object)"NetworkObject == null");
					}
					else if ((Object)(object)chaoticEnemy.EnemyAI == (Object)null)
					{
						Plugin.Logger.LogError((object)"enemyAI == null");
					}
					else
					{
						NetworkObject? networkObject = chaoticEnemy.NetworkObject;
						if ((Object)(object)((networkObject != null) ? ((Component)networkObject).gameObject : null) == (Object)null)
						{
							Plugin.Logger.LogError((object)"NetworkObject.gameObject == null");
						}
						else if ((Object)(object)((Component)chaoticEnemy.NetworkObject).gameObject == (Object)null)
						{
							Plugin.Logger.LogError((object)"A chaotic enemy gameObject == null");
						}
						else
						{
							Plugin.Logger.LogError((object)("An " + chaoticEnemy.kindString + " " + chaoticEnemy.EnemyAI.enemyType.enemyName + " chaotic enemy is changing"));
							NetworkObjectReference? val = GameManager.SwitchToRandomEnemyType(roundManager2, chaoticEnemy.EnemyAI, chaoticEnemy.Inside, chaoticEnemy.NetworkObject);
							if (val.HasValue)
							{
								chaoticEnemy.NetworkObject = NetworkObjectReference.op_Implicit(val.GetValueOrDefault());
								chaoticEnemy.EnemyAI = ((Component)chaoticEnemy.NetworkObject).gameObject.GetComponent<EnemyAI>();
							}
							else
							{
								Plugin.Logger.LogError((object)"networkObjectReference == null after switching enemy type");
							}
							chaoticEnemy.isChaoticEnemyAlreadyTryingToChange = !chaoticEnemy.isChaoticEnemyAlreadyTryingToChange;
						}
					}
				}
			};
			GameManager.Timers.Add(changeType);
		}

		public override void Update()
		{
			if (!((Object)(object)base.EnemyAI == (Object)null))
			{
				if (base.EnemyAI.isEnemyDead)
				{
					Plugin.Logger.LogError((object)("An " + kindString + " chaotic enemy died as " + base.EnemyAI.enemyType.enemyName));
					changeType.Stop();
					changeType.Finished = true;
					base.ItsJoever = true;
				}
				else
				{
					base.Inside = !base.EnemyAI.isOutside;
				}
			}
		}

		public override Chaotic? Spawn()
		{
			ChaoticEnemy chaoticEnemy = (ChaoticEnemy)base.Spawn();
			if (chaoticEnemy == null)
			{
				return null;
			}
			if ((Object)(object)base.EnemyAI == (Object)null)
			{
				Plugin.Logger.LogError((object)"EnemyAI shouldn't be null here");
				return null;
			}
			changeType.Start();
			return chaoticEnemy;
		}
	}
	public class ChaoticEntities : Chaotic
	{
		protected string kindString;

		private List<string>? exclusion;

		public EnemyAI? EnemyAI { get; protected set; }

		public bool Inside { get; protected set; }

		public ChaoticEntities(RoundManager roundManager, bool inside, List<string>? exclusion)
			: base(roundManager)
		{
			this.exclusion = exclusion;
			Inside = inside;
			kindString = (Inside ? "inside" : "outside");
		}

		public override Chaotic? Spawn()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			float yRotation;
			Vector3 position;
			if (Inside)
			{
				int num = base.RoundManager.allEnemyVents.Length;
				if (num == 0)
				{
					return null;
				}
				EnemyVent val = base.RoundManager.allEnemyVents[Random.Range(0, num)];
				position = val.floorNode.position;
				yRotation = val.floorNode.eulerAngles.y;
				val.OpenVentClientRpc();
			}
			else
			{
				int count = base.RoundManager.currentLevel.OutsideEnemies.Count;
				if (count == 0)
				{
					Plugin.Logger.LogError((object)"Cannot spawn enemy outside, no enemy list available");
					return null;
				}
				SpawnableEnemyWithRarity val2 = base.RoundManager.currentLevel.OutsideEnemies[Random.Range(0, count)];
				GameObject[] array = GameObject.FindGameObjectsWithTag("OutsideAINode");
				int num2 = array.Length;
				if (num2 == 0)
				{
					Plugin.Logger.LogError((object)"Cannot chaotic outside, no spawn point available");
					return null;
				}
				Vector3 position2 = array[Random.Range(0, num2)].transform.position;
				yRotation = 0f;
				position = base.RoundManager.GetRandomNavMeshPositionInBoxPredictable(position2, 10f, default(NavMeshHit), base.RoundManager.AnomalyRandom, base.RoundManager.GetLayermaskForEnemySizeLimit(val2.enemyType));
				position = base.RoundManager.PositionWithDenialPointsChecked(position, array, val2.enemyType);
			}
			var (val3, val4) = GameManager.SpawnRandomEnemy(base.RoundManager, Inside, position, yRotation, exclusion);
			if ((Object)(object)val3 == (Object)null || !val4.HasValue)
			{
				return null;
			}
			if (!val4.HasValue)
			{
				Plugin.Logger.LogError((object)"Error networkObjectReference == null when trying to spawn chaotic entity");
				return null;
			}
			NetworkObjectReference? val5 = val4;
			base.NetworkObject = (val5.HasValue ? NetworkObjectReference.op_Implicit(val5.GetValueOrDefault()) : null);
			EnemyAI = ((Component)base.NetworkObject).gameObject.GetComponent<EnemyAI>();
			return this;
		}
	}
	public class MoveEnemy : ChaoticEntities
	{
		private PlayerControllerB? closestPlayer;

		private Vector3 lastClosestPlayerPosition;

		private NavMeshAgent? navMeshAgent;

		private Timer findClosestPlayerDelay;

		private Vector3? freezePosition;

		private string playerUsername = "";

		private string previousPlayerUsername = "";

		public MoveEnemy(RoundManager roundManager, bool inside)
			: base(roundManager, inside, new List<string>(8) { "forest", "RedLocust", "Doublewing", "FlowerSnake", "DocileLocust", "double", "Centipede", "puffer" })
		{
			findClosestPlayerDelay = new Timer(1f, oneshot: false);
			findClosestPlayerDelay.OnTimeout += delegate
			{
				if (!((Object)(object)base.NetworkObject == (Object)null) && !((Object)(object)base.EnemyAI == (Object)null))
				{
					closestPlayer = GameManager.GetClosestPlayerWithLineOfSight(base.RoundManager, base.EnemyAI);
					if (!((Object)(object)closestPlayer == (Object)null))
					{
						previousPlayerUsername = playerUsername;
						playerUsername = closestPlayer.playerUsername;
						if (playerUsername != previousPlayerUsername)
						{
							Plugin.Logger.LogError((object)("Changing target to " + closestPlayer.playerUsername));
						}
					}
				}
			};
			findClosestPlayerDelay.Start();
			GameManager.Timers.Add(findClosestPlayerDelay);
		}

		public override void Update()
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if (GameManager.gameOver || (Object)(object)base.EnemyAI == (Object)null || (Object)(object)base.NetworkObject == (Object)null)
			{
				return;
			}
			if (base.EnemyAI.isEnemyDead)
			{
				Plugin.Logger.LogError((object)("A " + kindString + " move enemy died as " + base.EnemyAI.enemyType.enemyName));
				base.ItsJoever = true;
				return;
			}
			EnemyAIAdditionalData component = ((Component)base.NetworkObject).gameObject.GetComponent<EnemyAIAdditionalData>();
			if ((Object)(object)closestPlayer == (Object)null)
			{
				component.paused = false;
				return;
			}
			component.paused = closestPlayer.timeSincePlayerMoving > 0.05f;
			if (component.paused)
			{
				Vector3? val = freezePosition;
				if (val.HasValue)
				{
					Vector3 valueOrDefault = val.GetValueOrDefault();
					((Component)base.NetworkObject).transform.position = valueOrDefault;
					base.EnemyAI.SyncPositionToClients();
				}
			}
			else
			{
				freezePosition = ((Component)base.NetworkObject).transform.position;
			}
		}

		public override Chaotic? Spawn()
		{
			MoveEnemy moveEnemy = (MoveEnemy)base.Spawn();
			if ((Object)(object)base.EnemyAI == (Object)null)
			{
				Plugin.Logger.LogError((object)"EnemyAI shouldn't be null here");
				return null;
			}
			if (moveEnemy == null)
			{
				Plugin.Logger.LogError((object)"Move enemy == null");
				return null;
			}
			if ((Object)(object)moveEnemy.NetworkObject == (Object)null)
			{
				Plugin.Logger.LogError((object)"Move enemy NetworkObject == null");
				return null;
			}
			((Component)moveEnemy.NetworkObject).gameObject.AddComponent<EnemyAIAdditionalData>();
			navMeshAgent = ((Component)base.EnemyAI).GetComponent<NavMeshAgent>();
			return moveEnemy;
		}
	}
}
namespace ChaosCompany.Scripts.DataStructures
{
	public class ChaoticItemAdditionalData : MonoBehaviour
	{
		public bool pickedUp;
	}
	public class EnemyAIAdditionalData : MonoBehaviour
	{
		public bool paused;
	}
}
namespace ChaosCompany.Scripts.Components
{
	public sealed class Timer
	{
		public bool Finished { get; set; }

		public float WaitTime { get; set; }

		public bool Oneshot { get; set; }

		public float TimeLeft { get; private set; }

		public bool Paused { get; private set; } = true;


		public event Action? OnTimeout;

		public Timer(float waitTime, bool oneshot)
		{
			WaitTime = waitTime;
			Oneshot = oneshot;
		}

		public void Start()
		{
			Paused = false;
		}

		public void Restart()
		{
			TimeLeft = 0f;
			Start();
		}

		public void Stop()
		{
			Paused = true;
		}

		public void Update()
		{
			if (Paused)
			{
				return;
			}
			TimeLeft += Time.deltaTime;
			if (!(TimeLeft >= WaitTime))
			{
				return;
			}
			TimeLeft = 0f;
			if (this.OnTimeout != null)
			{
				this.OnTimeout();
				if (Oneshot)
				{
					Finished = true;
				}
			}
			if (Oneshot)
			{
				Paused = true;
			}
		}
	}
}
namespace ChaosCompany.Scripts.Abstracts
{
	public abstract class Chaotic
	{
		public RoundManager RoundManager { get; private set; }

		public NetworkObject? NetworkObject { get; protected set; }

		public bool ItsJoever { get; protected set; }

		public Chaotic(RoundManager roundManager)
		{
			RoundManager = roundManager;
		}

		public virtual void Update()
		{
		}

		public virtual Chaotic? Spawn()
		{
			return null;
		}
	}
}