Decompiled source of EEC H v1.8.4

ExtraEnemyCustomization.dll

Decompiled 2 months ago
#define DEBUG
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AIGraph;
using AK;
using Agents;
using AssetShards;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using CellMenu;
using CullingSystem;
using EEC;
using EEC.API;
using EEC.Configs;
using EEC.Configs.Customizations;
using EEC.CustomAbilities.Bleed;
using EEC.CustomAbilities.Bleed.Handlers;
using EEC.CustomAbilities.Bleed.Inject;
using EEC.CustomAbilities.DrainStamina;
using EEC.CustomAbilities.EMP;
using EEC.CustomAbilities.EMP.Handlers;
using EEC.CustomAbilities.EMP.Inject;
using EEC.CustomAbilities.Explosion;
using EEC.CustomAbilities.Explosion.Handlers;
using EEC.CustomSettings.CustomProjectiles;
using EEC.CustomSettings.CustomScoutWaves;
using EEC.CustomSettings.CustomTentacles;
using EEC.EnemyCustomizations;
using EEC.EnemyCustomizations.Abilities;
using EEC.EnemyCustomizations.Abilities.Handlers;
using EEC.EnemyCustomizations.Abilities.Inject;
using EEC.EnemyCustomizations.Detections;
using EEC.EnemyCustomizations.EnemyAbilities;
using EEC.EnemyCustomizations.EnemyAbilities.Abilities;
using EEC.EnemyCustomizations.EnemyAbilities.Events;
using EEC.EnemyCustomizations.EnemyAbilities.Handlers;
using EEC.EnemyCustomizations.Models;
using EEC.EnemyCustomizations.Models.Handlers;
using EEC.EnemyCustomizations.Properties;
using EEC.EnemyCustomizations.Shared;
using EEC.EnemyCustomizations.Shared.Handlers;
using EEC.EnemyCustomizations.Shooters;
using EEC.EnemyCustomizations.Shooters.Handlers;
using EEC.EnemyCustomizations.Strikers;
using EEC.Events;
using EEC.Managers;
using EEC.Managers.Assets;
using EEC.Managers.Properties;
using EEC.Networking;
using EEC.Networking.Events;
using EEC.Networking.Replicators;
using EEC.Patches.Handlers;
using EEC.Utils;
using EEC.Utils.Integrations;
using EEC.Utils.Json;
using EEC.Utils.Json.Converters;
using EEC.Utils.Json.Elements;
using EEC.Utils.Unity;
using Enemies;
using ExtraEnemyCustomization.EnemyCustomizations.Properties.Inject;
using ExtraEnemyCustomization.Utils.Integrations;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using Gear;
using HarmonyLib;
using IRF;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.InteropTypes.Fields;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using InjectLib.JsonNETInjection.Supports;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using SemanticVersioning;
using StateMachines;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ExtraEnemyCustomization")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+gite3cf4af-dirty-master.e3cf4af2ae7be1c49b17fc3a74b48d1151e9a9b5")]
[assembly: AssemblyProduct("ExtraEnemyCustomization")]
[assembly: AssemblyTitle("ExtraEnemyCustomization")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
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;
		}
	}
}
namespace ExtraEnemyCustomization
{
	[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
	[CompilerGenerated]
	internal static class VersionInfo
	{
		public const string RootNamespace = "ExtraEnemyCustomization";

		public const string Version = "1.0.0";

		public const string VersionPrerelease = null;

		public const string VersionMetadata = "gite3cf4af-dirty-master";

		public const string SemVer = "1.0.0+gite3cf4af-dirty-master";

		public const string GitRevShort = "e3cf4af-dirty";

		public const string GitRevLong = "e3cf4af2ae7be1c49b17fc3a74b48d1151e9a9b5-dirty";

		public const string GitBranch = "master";

		public const string GitTag = "0.8.1";

		public const bool GitIsDirty = true;
	}
}
namespace ExtraEnemyCustomization.Utils.Integrations
{
	public static class InjectLibUtil
	{
		public const string PLUGIN_GUID = "GTFO.InjectLib";

		public static JsonConverter InjectLibConnector { get; private set; }

		public static bool IsLoaded { get; private set; }

		static InjectLibUtil()
		{
			InjectLibConnector = null;
			IsLoaded = false;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("GTFO.InjectLib", out var value))
			{
				return;
			}
			try
			{
				Assembly assembly = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
				if ((object)assembly == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type[] types = assembly.GetTypes();
				Type type = types.First((Type t) => t.Name == "InjectLibConnector");
				if ((object)type == null)
				{
					throw new Exception("Unable to Find InjectLibConnector Class");
				}
				InjectLibConnector = (JsonConverter)Activator.CreateInstance(type);
				IsLoaded = true;
			}
			catch (Exception value2)
			{
				Logger.Error($"Exception thrown while reading data from GTFO.AWO: {value2}");
			}
		}
	}
}
namespace ExtraEnemyCustomization.EnemyCustomizations._EnemyEvents
{
	internal interface IEnemySpawn
	{
	}
}
namespace ExtraEnemyCustomization.EnemyCustomizations.Properties.Inject
{
	[HarmonyPatch(typeof(LG_LevelInteractionManager), "DoSetWaveRoarSoundInformation")]
	internal static class Inject_DoSetWaveRoar
	{
		[HarmonyWrapSafe]
		public static bool Prefix(pWaveRoarSettings settings)
		{
			//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)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			DistantRoarCustom distantRoarCustom = SharedRoarData.Condense(SharedRoarData.Dict.Where<KeyValuePair<uint, SharedRoarData.RoarData>>((KeyValuePair<uint, SharedRoarData.RoarData> entry) => entry.Value.EnemyType == settings.enemyType && entry.Value.IsInWave).ToList());
			if (distantRoarCustom == null)
			{
				return true;
			}
			CellSoundPlayer val = new CellSoundPlayer(Vector3.zero);
			val.UpdatePosition(settings.position);
			bool flag = false;
			CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Cleanup(val)), (Action)null);
			switch (settings.enemyType)
			{
			case 0:
				val.SetSwitch(ENEMY_TYPE.GROUP, SWITCH.STRIKER);
				break;
			case 1:
				val.SetSwitch(ENEMY_TYPE.GROUP, SWITCH.SHOOTER);
				break;
			case 2:
				val.SetSwitch(ENEMY_TYPE.GROUP, SWITCH.BIRTHER);
				break;
			case 3:
				val.SetSwitch(ENEMY_TYPE.GROUP, SWITCH.SHADOW);
				break;
			case 4:
				val.SetSwitch(ENEMY_TYPE.GROUP, SWITCH.TANK);
				break;
			case 5:
				val.SetSwitch(ENEMY_TYPE.GROUP, SWITCH.FLYER);
				break;
			case 6:
				val.SetSwitch(ENEMY_TYPE.GROUP, SWITCH.IMMORTAL);
				break;
			case 7:
				val.SetSwitch(ENEMY_TYPE.GROUP, SWITCH.BULLRUSHER);
				break;
			case 8:
				val.SetSwitch(ENEMY_TYPE.GROUP, SWITCH.POUNCER);
				break;
			case 9:
				val.SetSwitch(ENEMY_TYPE.GROUP, SWITCH.STRIKER_BERSERK);
				break;
			case 10:
				val.SetSwitch(ENEMY_TYPE.GROUP, SWITCH.SHOOTER_SPREAD);
				break;
			case 11:
				return false;
			case 12:
				flag = true;
				break;
			case 13:
				val.Post(distantRoarCustom.SoundID, distantRoarCustom.IsGlobal);
				return false;
			default:
				return true;
			}
			int num = ((distantRoarCustom.RoarSize == RoarSizeOverride.Unchanged) ? ((int)settings.roarSize) : ((int)distantRoarCustom.RoarSize));
			if (flag)
			{
				val.Post((num < 3) ? EVENTS.DISTANT_ROAR_MEDIUM : EVENTS.DISTANT_ROAR_LARGE, distantRoarCustom.IsGlobal);
				return false;
			}
			switch (num)
			{
			case 1:
				val.SetSwitch(ROAR_SIZE.GROUP, SWITCH.SMALL);
				break;
			case 2:
				val.SetSwitch(ROAR_SIZE.GROUP, SWITCH.MEDIUM);
				break;
			case 3:
				val.SetSwitch(ROAR_SIZE.GROUP, SWITCH.BIG);
				break;
			default:
				return true;
			}
			val.SetSwitch(ENVIROMENT.GROUP, distantRoarCustom.IsOutside.GetValue(settings.isOutside) ? SWITCH.DESERT : SWITCH.COMPLEX);
			val.Post(EVENTS.PLAY_WAVE_DISTANT_ROAR, true);
			return false;
		}

		private static IEnumerator Cleanup(CellSoundPlayer csPlayer)
		{
			yield return (object)new WaitForSeconds(10f);
			csPlayer.Recycle();
		}
	}
	[HarmonyPatch]
	internal static class Inject_EnemyGroup
	{
		[HarmonyPatch(typeof(EnemyGroup), "TryGetAKSwitchIDFromEnemyType")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static bool OverrideSwitchID(ref bool __result, EnemyAgent agent, out uint switchID)
		{
			switchID = 0u;
			if (SharedRoarData.Dict.TryGetValue(((GameDataBlockBase<EnemyDataBlock>)(object)agent.EnemyData).persistentID, out SharedRoarData.RoarData value))
			{
				switchID = value.SwitchID;
				SharedRoarData.Dict[((GameDataBlockBase<EnemyDataBlock>)(object)agent.EnemyData).persistentID].IsInWave = true;
				__result = true;
			}
			return switchID == 0;
		}

		[HarmonyPatch(typeof(EnemyGroup), "GetByteFromEnemyType")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static bool AppendAKEnemyTypes(ref byte __result, uint enemyType)
		{
			if (enemyType == SWITCH.POUNCER)
			{
				__result = 8;
				return false;
			}
			if (enemyType == SWITCH.STRIKER_BERSERK)
			{
				__result = 9;
				return false;
			}
			if (enemyType == SWITCH.SHOOTER_SPREAD)
			{
				__result = 10;
				return false;
			}
			switch (enemyType)
			{
			case 99900u:
				__result = 11;
				return false;
			case 99901u:
				__result = 12;
				return false;
			case 99902u:
				__result = 13;
				return false;
			default:
				return true;
			}
		}
	}
	internal static class SharedRoarData
	{
		internal class RoarData
		{
			public DistantRoarCustom RoarSettings { get; set; } = new DistantRoarCustom();


			public uint SwitchID { get; set; }

			public byte EnemyType { get; set; }

			public bool IsInWave { get; set; } = false;

		}

		public static Dictionary<uint, RoarData> Dict = new Dictionary<uint, RoarData>();

		public static DistantRoarCustom? Condense(List<KeyValuePair<uint, RoarData>>? filter)
		{
			if (filter == null || !filter.Any())
			{
				return null;
			}
			foreach (KeyValuePair<uint, RoarData> item in filter)
			{
				if (Dict.TryGetValue(item.Key, out RoarData value))
				{
					value.IsInWave = false;
				}
			}
			return filter.OrderByDescending<KeyValuePair<uint, RoarData>, RoarSizeOverride>((KeyValuePair<uint, RoarData> entry) => entry.Value.RoarSettings.RoarSize).FirstOrDefault().Value.RoarSettings;
		}
	}
}
namespace EEC
{
	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
	internal sealed class CallConstructorOnLoadAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
	internal sealed class InjectToIl2CppAttribute : Attribute
	{
	}
	public static class Configuration
	{
		public const string SECTION_USER = "1. User-End";

		public const string SECTION_RUNDEVS = "2. Rundown Developer";

		public const string SECTION_LOGGING = "3. Logging";

		public const string SECTION_DEV = "4. DEBUG";

		public const int CONFIG_VERSION = 1;

		private static ConfigEntry<bool> _showMarkerText;

		private static ConfigEntry<bool> _showMarkerDistance;

		private static ConfigEntry<bool> _showExplosionEffect;

		private static ConfigEntry<ShitpostType> _shitpostType;

		private static ConfigEntry<bool> _useLiveEdit;

		private static ConfigEntry<bool> _linkMTFOHotReload;

		private static ConfigEntry<bool> _useDebugLog;

		private static ConfigEntry<bool> _useVerboseLog;

		private static ConfigEntry<AssetCacheManager.OutputType> _assetCacheBehaviour;

		private static ConfigEntry<bool> _dumpConfig;

		private static ConfigEntry<bool> _profiler;

		private static ConfigFile _currentContext;

		public static bool ShowMarkerText { get; private set; }

		public static bool ShowMarkerDistance { get; private set; }

		public static bool ShowExplosionEffect { get; private set; }

		public static ShitpostType ShitpostType { get; private set; }

		public static bool UseLiveEdit { get; private set; }

		public static bool LinkMTFOHotReload { get; private set; }

		public static bool UseDebugLog { get; private set; }

		public static bool UseVerboseLog { get; private set; }

		public static AssetCacheManager.OutputType AssetCacheBehaviour { get; private set; }

		public static bool DumpConfig { get; private set; }

		public static bool Profiler { get; private set; }

		public static bool CanShitpostOf(ShitpostType type)
		{
			switch (ShitpostType)
			{
			case ShitpostType.ForceOff:
				return false;
			case ShitpostType.Enable:
			{
				DateTime now = DateTime.Now;
				return now.Month == 4 && now.Day == 1;
			}
			default:
				return ShitpostType.HasFlag(type);
			}
		}

		public static void CreateAndBindAll()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			string text = Path.Combine(Paths.ConfigPath, "EEC.cfg");
			ConfigFile context = new ConfigFile(text, true);
			ConfigEntry<int> val = BindConfigVersion(context);
			if (val.Value < 1)
			{
				File.Delete(text);
				context = new ConfigFile(text, true);
				BindConfigVersion(context);
			}
			BindAll(context);
		}

		public static void BindAll(ConfigFile context)
		{
			_currentContext = context;
			_showMarkerText = BindUserConfig("Marker Text", "Display Enemy Marker Texts? (if set by rundown devs)", defaultValue: true);
			_showMarkerDistance = BindUserConfig("Marker Distance", "Display Enemy Marker Distance? (if set by rundown devs)", defaultValue: true);
			_showExplosionEffect = BindUserConfig("Explosion Flash", "(Accessibility) Display Light flash effect for explosion abilities?", defaultValue: true);
			_shitpostType = BindUserConfig("Shitposting", "Shitpost mode use comma to enable multiple stuffs", ShitpostType.ForceOff);
			ShowMarkerText = _showMarkerText.Value;
			ShowMarkerDistance = _showMarkerDistance.Value;
			ShowExplosionEffect = _showExplosionEffect.Value;
			ShitpostType = _shitpostType.Value;
			_useLiveEdit = BindRdwDevConfig("Live Edit", "Reload Config when they are edited while in-game", defaultValue: false);
			_linkMTFOHotReload = BindRdwDevConfig("Reload on MTFO HotReload", "Reload Configs when MTFO's HotReload button has pressed?", defaultValue: true);
			UseLiveEdit = _useLiveEdit.Value;
			LinkMTFOHotReload = _linkMTFOHotReload.Value;
			_useDebugLog = BindLoggingConfig("UseDevMessage", "Using Dev Message for Debugging your config?", defaultValue: false);
			_useVerboseLog = BindLoggingConfig("Verbose", "Using Much more detailed Message for Debugging?", defaultValue: false);
			_assetCacheBehaviour = BindLoggingConfig("Cached Asset Result Output", "How does your cached material/texture result be returned?", AssetCacheManager.OutputType.None);
			UseDebugLog = _useDebugLog.Value;
			UseVerboseLog = _useVerboseLog.Value;
			AssetCacheBehaviour = _assetCacheBehaviour.Value;
			_dumpConfig = BindDevConfig("DumpConfig", "Dump Empty Config file?", defaultValue: false);
			_profiler = BindDevConfig("Profiler", "Show Profiler Info for Spawned Event", defaultValue: false);
			DumpConfig = _dumpConfig.Value;
			Profiler = _profiler.Value;
		}

		private static ConfigEntry<int> BindConfigVersion(ConfigFile context)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return context.Bind<int>(new ConfigDefinition("Version", "Config Version"), 1, (ConfigDescription)null);
		}

		private static ConfigEntry<T> BindUserConfig<T>(string name, string description, T defaultValue)
		{
			return BindItem(_currentContext, "1. User-End", name, description, defaultValue);
		}

		private static ConfigEntry<T> BindRdwDevConfig<T>(string name, string description, T defaultValue)
		{
			return BindItem(_currentContext, "2. Rundown Developer", name, description, defaultValue);
		}

		private static ConfigEntry<T> BindLoggingConfig<T>(string name, string description, T defaultValue)
		{
			return BindItem(_currentContext, "3. Logging", name, description, defaultValue);
		}

		private static ConfigEntry<T> BindDevConfig<T>(string name, string description, T defaultValue)
		{
			return BindItem(_currentContext, "4. DEBUG", name, description, defaultValue);
		}

		private static ConfigEntry<T> BindItem<T>(ConfigFile context, string section, string name, string description, T defaultValue)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_001c: Expected O, but got Unknown
			return context.Bind<T>(new ConfigDefinition(section, name), defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	[BepInPlugin("GTFO.EECustomization", "EECustom", "1.8.4")]
	[BepInProcess("GTFO.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class EntryPoint : BasePlugin
	{
		public static Harmony HarmonyInstance { get; private set; }

		public static string BasePath { get; private set; }

		public override void Load()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			Configuration.CreateAndBindAll();
			Logger.Initialize();
			ClassInjector.RegisterTypeInIl2Cpp<ShadowCustom.FixEnemySER>();
			ClassInjector.RegisterTypeInIl2Cpp<ShadowCustom.FixShadows>();
			InjectAllIl2CppType();
			CallAllAutoConstructor();
			BasePath = Path.Combine(MTFOUtil.CustomPath, "ExtraEnemyCustomization");
			HarmonyInstance = new Harmony("EEC.Harmony");
			HarmonyInstance.PatchAll();
			NetworkManager.Initialize();
			ConfigManager.Initialize();
			if (Configuration.DumpConfig)
			{
				ConfigManager.DumpDefault();
			}
			AssetEvents.AllAssetLoaded += AllAssetLoaded;
			AssetCacheManager.OutputMethod = Configuration.AssetCacheBehaviour;
		}

		private void AllAssetLoaded()
		{
			SpriteManager.Initialize();
			AssetCacheManager.AssetLoaded();
			ConfigManager.FireAssetLoaded();
			ConfigManager.FirePrefabBuildEventAll(rebuildPrefabs: false);
		}

		public override bool Unload()
		{
			UninjectAllIl2CppType();
			HarmonyInstance.UnpatchSelf();
			ConfigManager.UnloadAllConfig(doClear: true);
			return ((BasePlugin)this).Unload();
		}

		private void InjectAllIl2CppType()
		{
			Logger.Debug("Injecting IL2CPP Types");
			IEnumerable<Type> allHandlers = GetAllHandlers();
			Logger.Debug($" - Count: {allHandlers.Count()}");
			foreach (Type item in allHandlers)
			{
				if (!ClassInjector.IsTypeRegisteredInIl2Cpp(item))
				{
					ClassInjector.RegisterTypeInIl2Cpp(item);
				}
			}
		}

		private void CallAllAutoConstructor()
		{
			Logger.Debug("Calling Necessary Static .ctors");
			IEnumerable<Type> allAutoConstructor = GetAllAutoConstructor();
			Logger.Debug($" - Count: {allAutoConstructor.Count()}");
			foreach (Type item in allAutoConstructor)
			{
				Logger.Debug("calling ctor of: " + item.Name);
				RuntimeHelpers.RunClassConstructor(item.TypeHandle);
			}
		}

		private void UninjectAllIl2CppType()
		{
			Logger.Debug("Uninjecting IL2CPP Types");
			IEnumerable<Type> allHandlers = GetAllHandlers();
			Logger.Debug($" - Count: {allHandlers.Count()}");
			foreach (Type item in allHandlers)
			{
				if (ClassInjector.IsTypeRegisteredInIl2Cpp(item))
				{
				}
			}
		}

		private IEnumerable<Type> GetAllAutoConstructor()
		{
			return from type in ((object)this).GetType().Assembly.GetTypes()
				where type != null && Attribute.IsDefined(type, typeof(CallConstructorOnLoadAttribute))
				select type;
		}

		private IEnumerable<Type> GetAllHandlers()
		{
			return from type in ((object)this).GetType().Assembly.GetTypes()
				where type != null && Attribute.IsDefined(type, typeof(InjectToIl2CppAttribute))
				select type;
		}
	}
	public static class AgentExtension
	{
		public static bool TryCastToEnemyAgent(this Agent agent, out EnemyAgent enemyAgent)
		{
			return TryCast<EnemyAgent>(agent, (AgentType)1, out enemyAgent);
		}

		public static bool TryCastToPlayerAgent(this Agent agent, out PlayerAgent playerAgent)
		{
			return TryCast<PlayerAgent>(agent, (AgentType)0, out playerAgent);
		}

		private static bool TryCast<T>(Agent agent, AgentType type, out T result) where T : Agent
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)agent == (Object)null) && !((Il2CppObjectBase)agent).WasCollected && agent.Type == type)
			{
				T val = ((Il2CppObjectBase)agent).TryCast<T>();
				if (!((Object)(object)val == (Object)null))
				{
					result = val;
					return true;
				}
			}
			result = default(T);
			return false;
		}
	}
	public static class EasingExtension
	{
		public static float Evaluate(this eEasingType easeType, float progress, bool backward = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Easing.GetEasingValue(easeType, progress, backward);
		}

		public static Func<float, float, float, float, float> GetEaseFunction(this eEasingType easeType)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected I4, but got Unknown
			return (easeType - 1) switch
			{
				0 => Easing.EaseInQuad, 
				1 => Easing.EaseOutQuad, 
				2 => Easing.EaseInOutQuad, 
				3 => Easing.EaseInCubic, 
				4 => Easing.EaseOutCubic, 
				5 => Easing.EaseInOutCubic, 
				6 => Easing.EaseInQuart, 
				7 => Easing.EaseOutQuart, 
				8 => Easing.EaseInOutQuart, 
				9 => Easing.EaseInQuint, 
				10 => Easing.EaseOutQuint, 
				11 => Easing.EaseInOutQuint, 
				12 => Easing.EaseInSine, 
				13 => Easing.EaseOutSine, 
				14 => Easing.EaseInOutSine, 
				15 => Easing.EaseInExpo, 
				16 => Easing.EaseOutExpo, 
				17 => Easing.EaseInOutExpo, 
				18 => Easing.EaseInCirc, 
				19 => Easing.EaseOutCirc, 
				20 => Easing.EaseInOutCirc, 
				_ => Easing.LinearTween, 
			};
		}
	}
	public static class EnemyAgentExtension
	{
		public static void AddOnDeadOnce(this EnemyAgent agent, Action onDead)
		{
			Action onDead2 = onDead;
			bool called = false;
			agent.OnDeadCallback += Action.op_Implicit((Action)delegate
			{
				if (!called)
				{
					onDead2?.Invoke();
					called = true;
				}
			});
		}

		public static T RegisterOrGetProperty<T>(this EnemyAgent agent) where T : class, new()
		{
			return EnemyProperty<T>.RegisterOrGet(agent);
		}

		public static bool TryGetProperty<T>(this EnemyAgent agent, out T property) where T : class, new()
		{
			return EnemyProperty<T>.TryGet(agent, out property);
		}

		public static bool TryGetSpawnData(this EnemyAgent agent, out pEnemySpawnData spawnData)
		{
			return EnemySpawnDataManager.TryGet(((Agent)agent).GlobalID, out spawnData);
		}

		public static bool TryGetEnemyGroup(this EnemyAgent agent, out EnemyGroup group)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!agent.TryGetSpawnData(out var spawnData))
			{
				group = null;
				return false;
			}
			if (spawnData.groupReplicatorKey == 0)
			{
				group = null;
				return false;
			}
			IReplicator val = default(IReplicator);
			if (!SNet_Replication.TryGetReplicator(spawnData.groupReplicatorKey, ref val))
			{
				group = null;
				return false;
			}
			if (val.ReplicatorSupplier == null)
			{
				group = null;
				return false;
			}
			group = ((Il2CppObjectBase)val.ReplicatorSupplier).TryCast<EnemyGroup>();
			return (Object)(object)group != (Object)null;
		}

		public static AIG_CourseNode GetSpawnedNode(this EnemyAgent agent)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			pEnemySpawnData spawnData = ((SNet_DynamicReplicator<pEnemySpawnData>)(object)((Il2CppObjectBase)agent.Sync.Replicator).Cast<EnemyReplicator>()).GetSpawnData();
			AIG_CourseNode result = default(AIG_CourseNode);
			if (!((pCourseNode)(ref spawnData.courseNode)).TryGet(ref result))
			{
				return null;
			}
			return result;
		}
	}
	public static class EnemyDataBlockExtension
	{
		public static bool TryGetBehaviourBlock(this EnemyDataBlock data, out EnemyBehaviorDataBlock behaviour)
		{
			if (data == null)
			{
				behaviour = null;
				return false;
			}
			behaviour = GameDataBlockBase<EnemyBehaviorDataBlock>.GetBlock(data.BehaviorDataId);
			return behaviour != null;
		}

		public static bool TryGetBalancingBlock(this EnemyDataBlock data, out EnemyBalancingDataBlock balancing)
		{
			if (data == null)
			{
				balancing = null;
				return false;
			}
			balancing = GameDataBlockBase<EnemyBalancingDataBlock>.GetBlock(data.BalancingDataId);
			return balancing != null;
		}
	}
	public static class GameObjectExtension
	{
		public static bool TryGetComp<T>(this GameObject obj, out T component)
		{
			component = obj.GetComponent<T>();
			return component != null;
		}

		public static T AddOrGetComponent<T>(this GameObject obj) where T : Component
		{
			if (!obj.TryGetComp<T>(out var component))
			{
				return obj.AddComponent<T>();
			}
			return component;
		}

		public static GameObject FindChild(this GameObject obj, string name, bool includeInactive = false)
		{
			Il2CppArrayBase<Transform> componentsInChildren = obj.GetComponentsInChildren<Transform>(includeInactive);
			foreach (Transform item in componentsInChildren)
			{
				if (((Object)((Component)item).gameObject).name != name)
				{
					continue;
				}
				return ((Component)item).gameObject;
			}
			return null;
		}

		public static GameObject RegexFindChild(this GameObject obj, Regex rx, bool includeInactive = false)
		{
			Il2CppArrayBase<Transform> componentsInChildren = obj.GetComponentsInChildren<Transform>(includeInactive);
			foreach (Transform item in componentsInChildren)
			{
				if (!rx.IsMatch(((Object)item).name))
				{
					continue;
				}
				return ((Component)item).gameObject;
			}
			return null;
		}

		public static GameObject Instantiate(this GameObject obj, Transform toParent, string name)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(obj);
			val.transform.parent = toParent;
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.Euler(Vector3.zero);
			((Object)val).name = name;
			return val;
		}
	}
	public static class MonoBehaviourExtension
	{
		public static Coroutine StartCoroutine(this MonoBehaviour self, IEnumerator routine)
		{
			return self.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(routine));
		}
	}
	public static class ProjectileTargetingExtension
	{
		public static bool TryGetOwnerEnemyDataID(this ProjectileBase projectile, out uint id)
		{
			if ((Object)(object)projectile == (Object)null)
			{
				id = 0u;
				return false;
			}
			return ProjectileOwnerManager.TryGetDataID(((Object)((Component)projectile).gameObject).GetInstanceID(), out id);
		}

		public static bool TryGetOwnerEnemyDataID(this ProjectileTargeting projectile, out uint id)
		{
			if ((Object)(object)projectile == (Object)null)
			{
				id = 0u;
				return false;
			}
			return ProjectileOwnerManager.TryGetDataID(((Object)((Component)projectile).gameObject).GetInstanceID(), out id);
		}

		public static bool TryGetOwner(this ProjectileBase projectile, out EnemyAgent agent)
		{
			if ((Object)(object)projectile == (Object)null)
			{
				agent = null;
				return false;
			}
			return ProjectileOwnerManager.TryGet(((Object)((Component)projectile).gameObject).GetInstanceID(), out agent);
		}

		public static bool TryGetOwner(this ProjectileTargeting projectile, out EnemyAgent agent)
		{
			if ((Object)(object)projectile == (Object)null)
			{
				agent = null;
				return false;
			}
			return ProjectileOwnerManager.TryGet(((Object)((Component)projectile).gameObject).GetInstanceID(), out agent);
		}
	}
	public static class StringExtension
	{
		public static bool InvariantEquals(this string str, string strToCompare, bool ignoreCase = false)
		{
			return str.Equals(strToCompare, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture);
		}

		public static bool InvariantContains(this string str, string strToCompare, bool ignoreCase = false)
		{
			return str.Contains(strToCompare, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture);
		}

		public static bool InvariantStartsWith(this string str, string strToCompare, bool ignoreCase = false)
		{
			return str.StartsWith(strToCompare, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture);
		}

		public static bool InvariantEndsWith(this string str, string strToCompare, bool ignoreCase = false)
		{
			return str.EndsWith(strToCompare, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture);
		}

		public static bool EqualsAnyIgnoreCase(this string input, params string[] args)
		{
			return input.EqualsAny(ignoreCase: true, args);
		}

		public static bool EqualsAny(this string input, bool ignoreCase, params string[] args)
		{
			StringComparison comparisonType = (ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
			foreach (string value in args)
			{
				if (input.Equals(value, comparisonType))
				{
					return true;
				}
			}
			return false;
		}

		public static bool ContainsAnyIgnoreCase(this string input, params string[] args)
		{
			return input.ContainsAny(ignoreCase: true, args);
		}

		public static bool ContainsAny(this string input, bool ignoreCase, params string[] args)
		{
			StringComparison comparisonType = (ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
			foreach (string value in args)
			{
				if (input.Contains(value, comparisonType))
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class Logger
	{
		public static ManualLogSource LogInstance { get; private set; }

		public static bool UsingDevMessage { get; private set; }

		public static bool UsingVerbose { get; private set; }

		public static bool DevLogAllowed => UsingDevMessage;

		public static bool VerboseLogAllowed => UsingDevMessage && UsingVerbose;

		internal static void Initialize()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			LogInstance = new ManualLogSource("EEC");
			Logger.Sources.Add((ILogSource)(object)LogInstance);
			UsingDevMessage = Configuration.UseDebugLog;
			UsingVerbose = Configuration.UseVerboseLog;
		}

		public static void Log(string format, params object[] args)
		{
			Log(string.Format(format, args));
		}

		public static void Log(string str)
		{
			ManualLogSource logInstance = LogInstance;
			if (logInstance != null)
			{
				logInstance.Log((LogLevel)8, (object)str);
			}
		}

		public static void Warning(string format, params object[] args)
		{
			Warning(string.Format(format, args));
		}

		public static void Warning(string str)
		{
			ManualLogSource logInstance = LogInstance;
			if (logInstance != null)
			{
				logInstance.Log((LogLevel)4, (object)str);
			}
		}

		public static void Error(string format, params object[] args)
		{
			Error(string.Format(format, args));
		}

		public static void Error(string str)
		{
			ManualLogSource logInstance = LogInstance;
			if (logInstance != null)
			{
				logInstance.Log((LogLevel)2, (object)str);
			}
		}

		public static void Debug(string format, params object[] args)
		{
			Debug(string.Format(format, args));
		}

		public static void Debug(string str)
		{
			if (UsingDevMessage)
			{
				ManualLogSource logInstance = LogInstance;
				if (logInstance != null)
				{
					logInstance.LogDebug((object)str);
				}
			}
		}

		public static void Verbose(string format, params object[] args)
		{
			Verbose(string.Format(format, args));
		}

		public static void Verbose(string str)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if (!UsingDevMessage || !UsingVerbose)
			{
				return;
			}
			ManualLogSource logInstance = LogInstance;
			if (logInstance != null)
			{
				bool flag = default(bool);
				BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(10, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(str);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (Verbose)");
				}
				logInstance.LogDebug(val);
			}
		}

		[Conditional("DEBUG")]
		public static void Dev(string format, params object[] args)
		{
			Dev(string.Format(format, args));
		}

		[Conditional("DEBUG")]
		public static void Dev(string str)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource logInstance = LogInstance;
			if (logInstance != null)
			{
				LogLevel val = (LogLevel)8;
				LogLevel val2 = val;
				bool flag = default(bool);
				BepInExLogInterpolatedStringHandler val3 = new BepInExLogInterpolatedStringHandler(6, 1, val, ref flag);
				if (flag)
				{
					val3.AppendLiteral("[DEV] ");
					val3.AppendFormatted<string>(str);
				}
				logInstance.Log(val2, val3);
			}
		}
	}
}
namespace EEC.Utils
{
	public static class EnemyAnimUtil
	{
		private static readonly Dictionary<EnemyAnimType, int[]> _animHashsLookup;

		private static bool _initialized;

		static EnemyAnimUtil()
		{
			_initialized = false;
			_animHashsLookup = new Dictionary<EnemyAnimType, int[]>(Enum.GetValues(typeof(EnemyAnimType)).Length);
		}

		internal static void Initialize()
		{
			if (!_initialized)
			{
				CacheLookup();
				_initialized = true;
			}
		}

		private static void CacheLookup()
		{
			Type typeFromHandle = typeof(EnemyLocomotion);
			foreach (EnemyAnimType value in Enum.GetValues(typeof(EnemyAnimType)))
			{
				switch (value)
				{
				case EnemyAnimType.Heartbeats:
					_animHashsLookup.Add(value, Il2CppArrayBase<int>.op_Implicit((Il2CppArrayBase<int>)(object)EnemyLocomotion.s_hashHearbeats));
					Logger.Verbose($"{value},  {string.Join(" / ", (IEnumerable<int>)EnemyLocomotion.s_hashHearbeats)}");
					continue;
				case EnemyAnimType.None:
					continue;
				}
				string text = "s_hash" + Enum.GetName(typeof(EnemyAnimType), value);
				PropertyInfo property = typeFromHandle.GetProperty(text, BindingFlags.Static | BindingFlags.Public);
				if (property == null)
				{
					Logger.Warning(text + " does not exist!");
				}
				else if (property.PropertyType == typeof(int))
				{
					_animHashsLookup.Add(value, new int[1] { (int)property.GetValue(null) });
					Logger.Verbose($"{value},  {property.GetValue(null)}");
				}
				else if (property.PropertyType == typeof(Il2CppStructArray<int>))
				{
					int[] array = Il2CppArrayBase<int>.op_Implicit((Il2CppArrayBase<int>)(object)(Il2CppStructArray<int>)property.GetValue(null));
					_animHashsLookup.Add(value, array);
					Logger.Verbose($"{value},  {string.Join(" / ", array)}");
				}
				else
				{
					Logger.Error($"{value} is not a valid hash property!");
				}
			}
		}

		public static void DoAnimationLocal(EnemyAgent agent, EnemyAnimType type, float crossfadeTime, bool pauseAI)
		{
			if (!_initialized)
			{
				Logger.Error("EnemyAnimUtil.DoAnimation was called too fast before it got cached!");
			}
			else
			{
				if (type == EnemyAnimType.None)
				{
					return;
				}
				if (!_animHashsLookup.TryGetValue(type, out int[] value))
				{
					Logger.Error($"Cannot find AnimationHash with: {type}");
					return;
				}
				int num = ((value.Length > 1) ? Rand.IndexOf(value) : 0);
				agent.Locomotion.m_animator.applyRootMotion = true;
				agent.Locomotion.m_animator.CrossFadeInFixedTime(value[num], crossfadeTime);
				if (pauseAI && ((AgentAI)agent.AI).m_navMeshAgent.isOnNavMesh)
				{
					((AgentAI)agent.AI).m_navMeshAgent.isStopped = true;
				}
			}
		}

		public static void DoAnimation(EnemyAgent agent, EnemyAnimType type, float crossfadeTime, bool pauseAI)
		{
			if (!_initialized)
			{
				Logger.Error("EnemyAnimUtil.DoAnimation was called too fast before it got cached!");
			}
			else if (type != 0)
			{
				if (!_animHashsLookup.TryGetValue(type, out int[] value))
				{
					Logger.Error($"Cannot find AnimationHash with: {type}");
					return;
				}
				int num = ((value.Length > 1) ? Rand.IndexOf(value) : 0);
				NetworkManager.EnemyAnim.Send(new EnemyAnimEvent.Packet
				{
					enemyID = ((Agent)agent).GlobalID,
					crossfadeTime = crossfadeTime,
					pauseAI = pauseAI,
					animHash = value[num]
				});
			}
		}
	}
	public enum EnemyAnimType : byte
	{
		None,
		MoveOnGround,
		Forward,
		Right,
		ClimbLadder,
		GiveBirth,
		HitLights_Fwd,
		HitLights_Bwd,
		HitLights_Rt,
		HitLights_Lt,
		HitHeavys_Fwd,
		HitHeavys_Bwd,
		HitHeavys_Rt,
		HitHeavys_Lt,
		Screams,
		ScreamTurns,
		HibernationIn,
		Heartbeats,
		HibernationWakeups,
		HibernationWakeupTurns,
		AbilityFires,
		AbilityUse,
		AbilityUseOut,
		MeleeWalkSequences,
		MeleeSequences,
		Melee180Sequences,
		JumpStart,
		JumpLand
	}
	public static class EnemyProperty<T> where T : class, new()
	{
		private static readonly Dictionary<ushort, T> _properties;

		public static IEnumerable<T> Properties => _properties.Values;

		static EnemyProperty()
		{
			_properties = new Dictionary<ushort, T>();
			EnemyEvents.Despawn += EnemyDespawn;
			LevelEvents.LevelCleanup += OnLevelCleanup;
		}

		private static void EnemyDespawn(EnemyAgent agent)
		{
			_properties.Remove(((Agent)agent).GlobalID);
		}

		private static void OnLevelCleanup()
		{
			_properties.Clear();
		}

		public static T RegisterOrGet(EnemyAgent agent)
		{
			T val = RegisterEnemy(agent);
			if (val != null)
			{
				return val;
			}
			return Get(agent);
		}

		public static T RegisterEnemy(EnemyAgent agent)
		{
			ushort globalID = ((Agent)agent).GlobalID;
			if (_properties.ContainsKey(globalID))
			{
				return null;
			}
			T val = new T();
			_properties.Add(globalID, val);
			return val;
		}

		public static T Get(EnemyAgent agent)
		{
			return Get(((Agent)agent).GlobalID);
		}

		public static T Get(ushort id)
		{
			if (_properties.ContainsKey(id))
			{
				return _properties[id];
			}
			return null;
		}

		public static bool TryGet(EnemyAgent agent, out T property)
		{
			return TryGet(((Agent)agent).GlobalID, out property);
		}

		public static bool TryGet(ushort id, out T property)
		{
			return _properties.TryGetValue(id, out property);
		}
	}
	[Obsolete("Will be moved to ExplosionManager")]
	public static class ExplosionUtil
	{
		public static void MakeExplosion(Vector3 position, float damage, float enemyMulti, float minRange, float maxRange)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			ExplosionData data = default(ExplosionData);
			data.position = position;
			data.damage = damage;
			data.enemyMulti = enemyMulti;
			data.minRange = minRange;
			data.maxRange = maxRange;
			data.lightColor = ExplosionManager.FlashColor;
			ExplosionManager.DoExplosion(data);
		}
	}
	public static class PlayerData
	{
		public static float MaxHealth { get; internal set; } = 25f;


		public static float MaxInfection { get; internal set; } = 1f;

	}
	public static class Rand
	{
		public const int InclusiveDoublePrecision = 10000;

		public const double InclusiveDoubleConversion = 0.0001;

		private static readonly Random _rand = new Random();

		public static Random CreateInstance()
		{
			return new Random(_rand.Next());
		}

		public static T ItemOf<T>(T[] array)
		{
			return array[IndexOf(array)];
		}

		public static int IndexOf(Array array)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (array.Length == 0)
			{
				throw new ArgumentException("Array Length was zero!", "array");
			}
			return _rand.Next(0, array.Length);
		}

		public static int Index(int length)
		{
			return _rand.Next(0, length);
		}

		public static int Range(int min, int max)
		{
			return _rand.Next(min, max);
		}

		public static float Range(float min, float max)
		{
			return NextFloat() * (max - min) + min;
		}

		public static int RangeInclusive(int min, int max)
		{
			return _rand.Next(min, max + 1);
		}

		public static float RangeInclusive(float min, float max)
		{
			return NextFloatInclusive() * (max - min) + min;
		}

		public static float NextFloatInclusive()
		{
			return Math.Clamp((float)NextDoubleInclusive(), 0f, 1f);
		}

		public static double NextDoubleInclusive()
		{
			int num = _rand.Next(0, 10001);
			return Math.Clamp((double)num * 0.0001, 0.0, 1.0);
		}

		public static float NextFloat()
		{
			return (float)_rand.NextDouble();
		}

		public static bool CanDoBy(float chance01)
		{
			return NextFloat() <= chance01;
		}

		public static int NextInt()
		{
			return _rand.Next();
		}
	}
	public static class RegexUtil
	{
		private static readonly Regex _vectorRegex = new Regex("-?[0-9.]+");

		public static bool TryParseVectorString(string input, out float[] vectorArray)
		{
			try
			{
				MatchCollection matchCollection = _vectorRegex.Matches(input);
				int count = matchCollection.Count;
				if (count < 1)
				{
					throw new Exception();
				}
				vectorArray = new float[count];
				for (int i = 0; i < count; i++)
				{
					Match match = matchCollection[i];
					vectorArray[i] = float.Parse(match.Value, CultureInfo.InvariantCulture);
				}
				return true;
			}
			catch
			{
				vectorArray = null;
				return false;
			}
		}
	}
}
namespace EEC.Utils.Unity
{
	[CallConstructorOnLoad]
	public static class InLevelCoroutine
	{
		[InjectToIl2Cpp]
		private sealed class InLevelCoroutineHandler : MonoBehaviour
		{
		}

		private static InLevelCoroutineHandler _handler;

		static InLevelCoroutine()
		{
			AssetEvents.AllAssetLoaded += AssetEvents_AllAssetLoaded;
			LevelEvents.LevelCleanup += LevelEvents_LevelCleanup;
			SNetEvents.PrepareRecall += SNetEvents_PrepareRecall;
		}

		private static void AssetEvents_AllAssetLoaded()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			if ((Object)(object)_handler == (Object)null)
			{
				GameObject val = new GameObject();
				Object.DontDestroyOnLoad((Object)(object)val);
				_handler = val.AddComponent<InLevelCoroutineHandler>();
			}
		}

		private static void SNetEvents_PrepareRecall(eBufferType _)
		{
			StopAll();
		}

		private static void LevelEvents_LevelCleanup()
		{
			StopAll();
		}

		public static Coroutine Start(IEnumerator coroutine)
		{
			if ((Object)(object)_handler != (Object)null && GameStateManager.IsInExpedition)
			{
				return ((MonoBehaviour)_handler).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(coroutine));
			}
			return null;
		}

		public static void Stop(Coroutine coroutine)
		{
			if ((Object)(object)_handler != (Object)null && GameStateManager.IsInExpedition)
			{
				((MonoBehaviour)_handler).StopCoroutine(coroutine);
			}
		}

		public static void StopAll()
		{
			if ((Object)(object)_handler != (Object)null)
			{
				((MonoBehaviour)_handler).StopAllCoroutines();
			}
		}
	}
	public struct LazyTimer
	{
		private float _lastTickTime;

		private float _durationInv;

		public float PassedTime { get; private set; }

		public float Duration { get; private set; }

		public bool Done => Progress >= 1f;

		public float Progress => Mathf.Clamp01(ProgressUnclamped);

		public float ProgressUnclamped
		{
			get
			{
				if (Duration != 0f)
				{
					return PassedTime * _durationInv;
				}
				return 1f;
			}
		}

		public LazyTimer(float duration)
		{
			PassedTime = 0f;
			Duration = duration;
			_durationInv = 1f / duration;
			_lastTickTime = GetTime();
		}

		public void Reset(float newDuration = -1f)
		{
			PassedTime = 0f;
			if (newDuration >= 0f)
			{
				Duration = newDuration;
				_durationInv = 1f / newDuration;
			}
			_lastTickTime = GetTime();
		}

		public void Tick()
		{
			float time = GetTime();
			float num = time - _lastTickTime;
			_lastTickTime = time;
			PassedTime += num;
		}

		public bool TickAndCheckDone()
		{
			Tick();
			return Done;
		}

		private static float GetTime()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			eGameStateName currentStateName = GameStateManager.CurrentStateName;
			if ((int)currentStateName == 10)
			{
				return Clock.ExpeditionProgressionTime;
			}
			return Clock.Time;
		}
	}
	public struct Timer
	{
		private float _durationInv;

		public float PassedTime { get; private set; }

		public float Duration { get; private set; }

		public bool Done => Progress >= 1f;

		public float Progress => Mathf.Clamp01(ProgressUnclamped);

		public float ProgressUnclamped
		{
			get
			{
				if (Duration != 0f)
				{
					return PassedTime * _durationInv;
				}
				return 1f;
			}
		}

		public Timer(float duration)
		{
			PassedTime = 0f;
			Duration = duration;
			_durationInv = 1f / duration;
		}

		public void Reset(float newDuration = -1f)
		{
			PassedTime = 0f;
			if (newDuration >= 0f)
			{
				Duration = newDuration;
				_durationInv = 1f / newDuration;
			}
		}

		public void Tick()
		{
			PassedTime += Time.deltaTime;
		}

		public void Tick(float deltaTime)
		{
			PassedTime += deltaTime;
		}

		public bool TickAndCheckDone()
		{
			Tick();
			return Done;
		}

		public bool TickAndCheckDone(float deltaTime)
		{
			Tick(deltaTime);
			return Done;
		}
	}
	public struct DoubleTimer
	{
		private double _durationInv;

		public double PassedTime { get; private set; }

		public double Duration { get; private set; }

		public bool Done => Progress >= 1.0;

		public double Progress => Math.Clamp(0.0, 1.0, ProgressUnclamped);

		public double ProgressUnclamped
		{
			get
			{
				if (Duration != 0.0)
				{
					return PassedTime * _durationInv;
				}
				return 1.0;
			}
		}

		public DoubleTimer(double duration)
		{
			PassedTime = 0.0;
			Duration = duration;
			_durationInv = 1.0 / duration;
		}

		public void Reset(double newDuration = -1.0)
		{
			PassedTime = 0.0;
			if (newDuration >= 0.0)
			{
				Duration = newDuration;
				_durationInv = 1.0 / newDuration;
			}
		}

		public void Tick()
		{
			PassedTime += Time.deltaTime;
		}

		public bool TickAndCheckDone()
		{
			Tick();
			return Done;
		}
	}
	public static class WaitFor
	{
		public static readonly WaitForEndOfFrame EndOfFrame = new WaitForEndOfFrame();

		public static readonly WaitForFixedUpdate FixedUpdate = new WaitForFixedUpdate();

		public static readonly WaitForSecondsCollection Seconds = new WaitForSecondsCollection();

		public static readonly WaitForSecondsRealtimeCollection SecondsRealtime = new WaitForSecondsRealtimeCollection();
	}
	public sealed class WaitForSecondsCollection : WaitForCollection<WaitForSeconds>
	{
		protected override WaitForSeconds CreateInstance(float time)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			return new WaitForSeconds(time);
		}
	}
	public sealed class WaitForSecondsRealtimeCollection : WaitForCollection<WaitForSecondsRealtime>
	{
		protected override WaitForSecondsRealtime CreateInstance(float time)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			return new WaitForSecondsRealtime(time);
		}
	}
	public abstract class WaitForCollection<T>
	{
		private readonly Dictionary<int, T> _lookup = new Dictionary<int, T>(100);

		private T _temp;

		public T this[float time]
		{
			get
			{
				int key = ((!(time <= 0f)) ? Mathf.RoundToInt(time * 1000f) : 0);
				if (_lookup.TryGetValue(key, out _temp))
				{
					return _temp;
				}
				_temp = CreateInstance(time);
				_lookup[key] = _temp;
				return _temp;
			}
		}

		protected abstract T CreateInstance(float time);
	}
}
namespace EEC.Utils.Json
{
	public static class JSON
	{
		private static readonly JsonSerializerOptions _setting;

		static JSON()
		{
			_setting = new JsonSerializerOptions
			{
				ReadCommentHandling = JsonCommentHandling.Skip,
				IncludeFields = false,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true,
				IgnoreReadOnlyProperties = true
			};
			_setting.Converters.Add(new ColorConverter());
			_setting.Converters.Add(new LocalizedTextConverter());
			_setting.Converters.Add(new JsonStringEnumConverter());
			_setting.Converters.Add(new Vector2Converter());
			_setting.Converters.Add(new Vector3Converter());
			if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized)
			{
				_setting.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter);
				Logger.Log("PartialData Support Found!");
			}
			if (InjectLibUtil.IsLoaded)
			{
				_setting.Converters.Add(InjectLibUtil.InjectLibConnector);
				Logger.Log("InjectLib found!");
			}
		}

		public static T Deserialize<T>(string json)
		{
			return JsonSerializer.Deserialize<T>(json, _setting);
		}

		public static object Deserialize(Type type, string json)
		{
			return JsonSerializer.Deserialize(json, type, _setting);
		}

		public static string Serialize(object value, Type type)
		{
			return JsonSerializer.Serialize(value, type, _setting);
		}
	}
}
namespace EEC.Utils.Json.Elements
{
	[JsonConverter(typeof(AgentModeTargetConverter))]
	public struct AgentModeTarget
	{
		public static readonly AgentModeTarget All = new AgentModeTarget(AgentModeType.Off | AgentModeType.Hibernate | AgentModeType.Agressive | AgentModeType.Scout | AgentModeType.Patrolling);

		public static readonly AgentModeTarget Scout = new AgentModeTarget(AgentModeType.Scout);

		public static readonly AgentModeTarget Hibernate = new AgentModeTarget(AgentModeType.Hibernate);

		public static readonly AgentModeTarget Agressive = new AgentModeTarget(AgentModeType.Agressive);

		public static readonly AgentModeTarget None = new AgentModeTarget(AgentModeType.None);

		public AgentModeType Mode;

		public AgentModeTarget(AgentModeType modes)
		{
			Mode = modes;
		}

		public bool IsMatch(EnemyAgent agent)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected I4, but got Unknown
			if ((Object)(object)agent == (Object)null)
			{
				return false;
			}
			AgentMode mode = ((AgentAI)agent.AI).Mode;
			return (int)mode switch
			{
				0 => Mode.HasFlag(AgentModeType.Off), 
				4 => Mode.HasFlag(AgentModeType.Hibernate), 
				1 => Mode.HasFlag(AgentModeType.Agressive), 
				3 => Mode.HasFlag(AgentModeType.Scout), 
				2 => Mode.HasFlag(AgentModeType.Patrolling), 
				_ => false, 
			};
		}
	}
	[Flags]
	public enum AgentModeType
	{
		None = 0,
		Off = 1,
		Hibernate = 2,
		Agressive = 4,
		Scout = 8,
		Patrolling = 0x10
	}
	public sealed class AgentModeTargetConverter : JsonConverter<AgentModeTarget>
	{
		private static readonly char[] _separators = new char[2] { ',', '|' };

		public override AgentModeTarget Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			switch (reader.TokenType)
			{
			case JsonTokenType.String:
			{
				string @string = reader.GetString();
				string[] array = @string.Split(_separators, StringSplitOptions.RemoveEmptyEntries);
				if (array.Length == 0)
				{
					throw new JsonException("There are no entries in " + @string + "! Are you sure it's in right format?");
				}
				AgentModeType agentModeType = AgentModeType.None;
				string[] array2 = array;
				foreach (string text in array2)
				{
					switch (text.ToLowerInvariant().Trim())
					{
					case "off":
					case "dead":
						agentModeType |= AgentModeType.Off;
						break;
					case "agressive":
					case "combat":
						agentModeType |= AgentModeType.Agressive;
						break;
					case "hibernate":
					case "hibernation":
					case "hibernating":
					case "sleeping":
						agentModeType |= AgentModeType.Hibernate;
						break;
					case "scout":
					case "scoutpatrolling":
						agentModeType |= AgentModeType.Scout;
						break;
					case "patrolling":
						agentModeType |= AgentModeType.Patrolling;
						break;
					}
				}
				return new AgentModeTarget(agentModeType);
			}
			case JsonTokenType.Number:
				Logger.Warning("Found flag number value in AgentModeTarget! : consider changing it to string.");
				return new AgentModeTarget((AgentModeType)reader.GetInt32());
			default:
				throw new JsonException($"Token type: {reader.TokenType} in AgentModeTarget is not supported!");
			}
		}

		public override void Write(Utf8JsonWriter writer, AgentModeTarget value, JsonSerializerOptions options)
		{
			writer.WriteNumberValue((int)value.Mode);
		}
	}
	[JsonConverter(typeof(BoolBaseConverter))]
	public struct BoolBase
	{
		public static readonly BoolBase False = new BoolBase(BoolMode.False);

		public static readonly BoolBase True = new BoolBase(BoolMode.True);

		public static readonly BoolBase Unchanged = new BoolBase(BoolMode.Unchanged);

		public BoolMode Mode;

		public BoolBase(bool mode)
		{
			Mode = (mode ? BoolMode.True : BoolMode.False);
		}

		public BoolBase(BoolMode mode)
		{
			Mode = mode;
		}

		public bool GetValue(bool originalValue)
		{
			switch (Mode)
			{
			case BoolMode.Unchanged:
				return originalValue;
			case BoolMode.True:
				return true;
			case BoolMode.False:
				return false;
			default:
				Logger.Error($"BoolBase.GetValue; Got Unknown Mode: {Mode}!\n{Environment.StackTrace}");
				return originalValue;
			}
		}
	}
	public enum BoolMode
	{
		False,
		True,
		Unchanged
	}
	public sealed class BoolBaseConverter : JsonConverter<BoolBase>
	{
		public override bool HandleNull => false;

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(BoolBase);
		}

		public override BoolBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			switch (reader.TokenType)
			{
			case JsonTokenType.String:
			{
				string text = reader.GetString().Trim();
				if (text.EqualsAnyIgnoreCase("Unchanged", "Ignore", "Keep", "Original", "KeepOriginal"))
				{
					return BoolBase.Unchanged;
				}
				if (bool.TryParse(text, out var result))
				{
					return new BoolBase(result);
				}
				throw new JsonException("Cannot parse BoolBase string: " + text + "! Are you sure it's in right format?");
			}
			case JsonTokenType.True:
				return BoolBase.True;
			case JsonTokenType.False:
				return BoolBase.False;
			default:
				throw new JsonException($"BoolBaseJson type: {reader.TokenType} is not implemented!");
			}
		}

		public override void Write(Utf8JsonWriter writer, BoolBase value, JsonSerializerOptions options)
		{
			switch (value.Mode)
			{
			case BoolMode.True:
				writer.WriteBooleanValue(value: true);
				break;
			case BoolMode.False:
				writer.WriteBooleanValue(value: false);
				break;
			case BoolMode.Unchanged:
				writer.WriteStringValue("Unchanged");
				break;
			}
			writer.WriteCommentValue("BoolBase");
		}
	}
	public sealed class CurveWrapper : Collection<CurveKeyFrame>
	{
		public const int KEYFRAME_FRAMECOUNT = 20;

		public const float KEYFRAME_PROGRESS_INV = 0.05f;

		public static readonly CurveWrapper Empty = new CurveWrapper();

		private static readonly List<Keyframe> _keys = new List<Keyframe>();

		public bool HasSetting => base.Count >= 2;

		public bool TryBuildCurve(out AnimationCurve curve)
		{
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			if (base.Count < 2)
			{
				curve = null;
				return false;
			}
			CurveKeyFrame[] array = this.OrderBy((CurveKeyFrame x) => x.Time).ToArray();
			_keys.Clear();
			for (int i = 0; i < base.Count - 1; i++)
			{
				CurveKeyFrame curveKeyFrame = array[i];
				CurveKeyFrame curveKeyFrame2 = array[i + 1];
				if (curveKeyFrame.Time > 1f || curveKeyFrame.Time < 0f)
				{
					Logger.Error($"CurveWrapper Time '{curveKeyFrame.Time}' was invalid!, must be range of 0.0 ~ 1.0");
					curve = null;
					return false;
				}
				float num = curveKeyFrame2.Time - curveKeyFrame.Time;
				float num2 = curveKeyFrame2.Value - curveKeyFrame.Value;
				float num3 = num2 / num;
				for (int j = 0; j < 20; j++)
				{
					float num4 = 0.05f * (float)j;
					float time = curveKeyFrame.Time + num * num4;
					float value = curveKeyFrame.Value + num2 * curveKeyFrame.OutEaseType.Evaluate(num4);
					List<Keyframe> keys = _keys;
					Keyframe item = default(Keyframe);
					((Keyframe)(ref item)).time = time;
					((Keyframe)(ref item)).value = value;
					((Keyframe)(ref item)).inTangent = num3;
					((Keyframe)(ref item)).outTangent = num3;
					keys.Add(item);
				}
			}
			curve = new AnimationCurve(_keys.ToArray());
			return true;
		}
	}
	public struct CurveKeyFrame
	{
		public float Time { get; set; }

		public float Value { get; set; }

		public eEasingType OutEaseType { get; set; }
	}
	[JsonConverter(typeof(EventWrapperConverter))]
	public sealed class EventWrapper : IDisposable
	{
		private string _json;

		private WardenObjectiveEventData _cached = null;

		public EventWrapper(string json)
		{
			_json = json;
		}

		public void Cache()
		{
			_cached = InjectLibJSON.Deserialize<WardenObjectiveEventData>(_json, Array.Empty<JsonConverter>());
			_json = string.Empty;
		}

		public WardenObjectiveEventData ToEvent()
		{
			if (_cached == null)
			{
				Cache();
			}
			return _cached;
		}

		public void Dispose()
		{
			_json = null;
			_cached = null;
		}
	}
	internal sealed class EventWrapperConverter : JsonConverter<EventWrapper>
	{
		public override bool HandleNull => false;

		public override EventWrapper Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			if (reader.TokenType == JsonTokenType.StartObject)
			{
				using (JsonDocument jsonDocument = JsonDocument.ParseValue(ref reader))
				{
					return new EventWrapper(jsonDocument.RootElement.ToString());
				}
			}
			throw new JsonException($"{reader.TokenType} is not supported for EventWrapperValue!");
		}

		public override void Write(Utf8JsonWriter writer, EventWrapper value, JsonSerializerOptions options)
		{
		}
	}
	[JsonConverter(typeof(ValueBaseConverter))]
	public struct ValueBase
	{
		public static readonly ValueBase Unchanged = new ValueBase(1f, ValueMode.Rel, fromDefault: true);

		public static readonly ValueBase Zero = new ValueBase(0f, ValueMode.Abs, fromDefault: false);

		public float Value;

		public ValueMode Mode;

		public bool FromDefault;

		public ValueBase(float value = 1f, ValueMode mode = ValueMode.Rel, bool fromDefault = true)
		{
			Value = value;
			Mode = mode;
			FromDefault = fromDefault;
		}

		public float GetAbsValue(float maxValue, float currentValue)
		{
			if (Mode == ValueMode.Rel)
			{
				if (FromDefault)
				{
					return currentValue * Value;
				}
				return maxValue * Value;
			}
			return Value;
		}

		public float GetAbsValue(float baseValue)
		{
			if (Mode == ValueMode.Rel)
			{
				return baseValue * Value;
			}
			return Value;
		}

		public int GetAbsValue(int maxValue, int currentValue)
		{
			return (int)Math.Round(GetAbsValue((float)maxValue, (float)currentValue));
		}

		public int GetAbsValue(int baseValue)
		{
			return (int)Math.Round(GetAbsValue((float)baseValue));
		}

		public override string ToString()
		{
			return $"[Mode: {Mode}, Value: {Value}]";
		}
	}
	public enum ValueMode
	{
		Rel,
		Abs
	}
	public sealed class ValueBaseConverter : JsonConverter<ValueBase>
	{
		public override bool HandleNull => false;

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(ValueBase);
		}

		public override ValueBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			switch (reader.TokenType)
			{
			case JsonTokenType.Number:
				return new ValueBase(reader.GetSingle(), ValueMode.Abs);
			case JsonTokenType.StartObject:
			{
				ValueBase result3 = default(ValueBase);
				while (reader.Read())
				{
					if (reader.TokenType == JsonTokenType.EndObject)
					{
						return result3;
					}
					if (reader.TokenType != JsonTokenType.PropertyName)
					{
						throw new JsonException("Expected PropertyName token");
					}
					string @string = reader.GetString();
					reader.Read();
					switch (@string.ToLowerInvariant())
					{
					case "value":
						result3.Value = reader.GetSingle();
						break;
					case "mode":
					{
						if (Enum.TryParse<ValueMode>(reader.GetString(), out var result4))
						{
							result3.Mode = result4;
						}
						break;
					}
					case "fromdefault":
						result3.FromDefault = reader.GetBoolean();
						break;
					}
				}
				throw new JsonException("Expected EndObject token");
			}
			case JsonTokenType.String:
			{
				string text = reader.GetString().Trim();
				bool fromDefault = false;
				if (text.EndsWith("of default", StringComparison.OrdinalIgnoreCase))
				{
					fromDefault = true;
					string text2 = text;
					text = text2.Substring(0, text2.Length - 10).TrimEnd();
				}
				if (text.InvariantEndsWith("%"))
				{
					string text2 = text;
					if (float.TryParse(text2.Substring(0, text2.Length - 1).TrimEnd(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var result))
					{
						return new ValueBase(result / 100f, ValueMode.Rel, fromDefault);
					}
				}
				else
				{
					if (text.EqualsAnyIgnoreCase("Unchanged", "Ignore", "Keep", "Original", "KeepOriginal"))
					{
						return new ValueBase(1f, ValueMode.Rel, fromDefault: false);
					}
					if (float.TryParse(text, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var result2))
					{
						return new ValueBase(result2, ValueMode.Abs);
					}
				}
				throw new JsonException("Cannot parse ValueBase string: " + text + "! Are you sure it's in right format?");
			}
			default:
				throw new JsonException($"ValueBaseJson type: {reader.TokenType} is not implemented!");
			}
		}

		public override void Write(Utf8JsonWriter writer, ValueBase value, JsonSerializerOptions options)
		{
			switch (value.Mode)
			{
			case ValueMode.Rel:
			{
				if (Mathf.Approximately(value.Value, 1f))
				{
					writer.WriteStringValue("Unchanged");
					break;
				}
				string format = (value.FromDefault ? "{0}% of default" : "{0}%");
				writer.WriteStringValue(string.Format(format, value.Value * 100f));
				break;
			}
			case ValueMode.Abs:
				writer.WriteStringValue(value.Value.ToString());
				break;
			}
			writer.WriteCommentValue("ValueBase");
		}
	}
}
namespace EEC.Utils.Json.Converters
{
	public sealed class ColorConverter : JsonConverter<Color>
	{
		public override bool HandleNull => false;

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(Color);
		}

		public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			Color color = default(Color);
			float result = 1f;
			switch (reader.TokenType)
			{
			case JsonTokenType.StartObject:
				while (reader.Read())
				{
					if (reader.TokenType == JsonTokenType.EndObject)
					{
						return color * result;
					}
					if (reader.TokenType != JsonTokenType.PropertyName)
					{
						throw new JsonException("Expected PropertyName token");
					}
					string @string = reader.GetString();
					reader.Read();
					switch (@string.ToLowerInvariant())
					{
					case "r":
						color.r = reader.GetSingle();
						break;
					case "g":
						color.g = reader.GetSingle();
						break;
					case "b":
						color.b = reader.GetSingle();
						break;
					case "a":
						color.a = reader.GetSingle();
						break;
					case "multiplier":
						result = reader.GetSingle();
						break;
					}
				}
				throw new JsonException("Expected EndObject token");
			case JsonTokenType.String:
			{
				string text = reader.GetString().Trim();
				string[] array = text.Split("*");
				string text2;
				switch (array.Length)
				{
				case 1:
					result = 1f;
					text2 = array[0].Trim();
					break;
				case 2:
					if (!float.TryParse(array[1].Trim(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out result))
					{
						throw new JsonException("Color multiplier is not valid number! (*): " + text);
					}
					text2 = array[0].Trim();
					break;
				default:
					throw new JsonException("Color format has more than two Mutiplier (*): " + text);
				}
				if (ColorUtility.TryParseHtmlString(text2, ref color))
				{
					return color * result;
				}
				if (TryParseColor(text, out color))
				{
					return color * result;
				}
				throw new JsonException("Color format is not right: " + text);
			}
			default:
				throw new JsonException($"ColorJson type: {reader.TokenType} is not implemented!");
			}
		}

		private static bool TryParseColor(string input, out Color color)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (!RegexUtil.TryParseVectorString(input, out float[] vectorArray))
			{
				color = Color.white;
				return false;
			}
			if (vectorArray.Length < 3)
			{
				color = Color.white;
				return false;
			}
			float num = 1f;
			if (vectorArray.Length > 3)
			{
				num = vectorArray[3];
			}
			color = new Color(vectorArray[0], vectorArray[1], vectorArray[2], num);
			return true;
		}

		public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			writer.WriteStringValue("#" + ColorUtility.ToHtmlStringRGBA(value));
		}
	}
	public sealed class LocalizedTextConverter : JsonConverter<LocalizedText>
	{
		public override bool HandleNull => false;

		public override LocalizedText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			switch (reader.TokenType)
			{
			case JsonTokenType.String:
			{
				string @string = reader.GetString();
				if (MTFOPartialDataUtil.TryGetId(@string, out var id))
				{
					return new LocalizedText
					{
						Id = id,
						UntranslatedText = null
					};
				}
				return new LocalizedText
				{
					Id = 0u,
					UntranslatedText = @string
				};
			}
			case JsonTokenType.Number:
				return new LocalizedText
				{
					Id = reader.GetUInt32(),
					UntranslatedText = null
				};
			default:
				throw new JsonException($"LocalizedTextJson type: {reader.TokenType} is not implemented!");
			}
		}

		public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options)
		{
			JsonSerializer.Serialize<LocalizedText>(writer, value, options);
		}
	}
	public sealed class Vector2Converter : JsonConverter<Vector2>
	{
		public override Vector2 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			Vector2 vector = default(Vector2);
			switch (reader.TokenType)
			{
			case JsonTokenType.StartObject:
				while (reader.Read())
				{
					if (reader.TokenType == JsonTokenType.EndObject)
					{
						return vector;
					}
					if (reader.TokenType != JsonTokenType.PropertyName)
					{
						throw new JsonException("Expected PropertyName token");
					}
					string @string = reader.GetString();
					reader.Read();
					string text2 = @string.ToLowerInvariant();
					string text3 = text2;
					if (!(text3 == "x"))
					{
						if (text3 == "y")
						{
							vector.y = reader.GetSingle();
						}
					}
					else
					{
						vector.x = reader.GetSingle();
					}
				}
				throw new JsonException("Expected EndObject token");
			case JsonTokenType.String:
			{
				string text = reader.GetString().Trim();
				if (TryParseVector2(text, out vector))
				{
					return vector;
				}
				throw new JsonException("Vector2 format is not right: " + text);
			}
			default:
				throw new JsonException($"Vector2Json type: {reader.TokenType} is not implemented!");
			}
		}

		private static bool TryParseVector2(string input, out Vector2 vector)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (!RegexUtil.TryParseVectorString(input, out float[] vectorArray))
			{
				vector = Vector2.zero;
				return false;
			}
			if (vectorArray.Length < 2)
			{
				vector = Vector2.zero;
				return false;
			}
			vector = new Vector2(vectorArray[0], vectorArray[1]);
			return true;
		}

		public override void Write(Utf8JsonWriter writer, Vector2 value, JsonSerializerOptions options)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			writer.WriteStringValue($"({value.x} {value.y})");
		}
	}
	public sealed class Vector3Converter : JsonConverter<Vector3>
	{
		public override bool HandleNull => false;

		public override Vector3 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 vector = default(Vector3);
			switch (reader.TokenType)
			{
			case JsonTokenType.StartObject:
				while (reader.Read())
				{
					if (reader.TokenType == JsonTokenType.EndObject)
					{
						return vector;
					}
					if (reader.TokenType != JsonTokenType.PropertyName)
					{
						throw new JsonException("Expected PropertyName token");
					}
					string @string = reader.GetString();
					reader.Read();
					switch (@string.ToLowerInvariant())
					{
					case "x":
						vector.x = reader.GetSingle();
						break;
					case "y":
						vector.y = reader.GetSingle();
						break;
					case "z":
						vector.z = reader.GetSingle();
						break;
					}
				}
				throw new JsonException("Expected EndObject token");
			case JsonTokenType.String:
			{
				string text = reader.GetString().Trim();
				if (TryParseVector3(text, out vector))
				{
					return vector;
				}
				throw new JsonException("Vector3 format is not right: " + text);
			}
			default:
				throw new JsonException($"Vector3Json type: {reader.TokenType} is not implemented!");
			}
		}

		private static bool TryParseVector3(string input, out Vector3 vector)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (!RegexUtil.TryParseVectorString(input, out float[] vectorArray))
			{
				vector = Vector3.zero;
				return false;
			}
			if (vectorArray.Length < 3)
			{
				vector = Vector3.zero;
				return false;
			}
			vector = new Vector3(vectorArray[0], vectorArray[1], vectorArray[2]);
			return true;
		}

		public override void Write(Utf8JsonWriter writer, Vector3 value, JsonSerializerOptions options)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			writer.WriteStringValue($"({value.x} {value.y} {value.z})");
		}
	}
}
namespace EEC.Utils.Integrations
{
	public static class MTFOPartialDataUtil
	{
		public delegate bool TryGetDelegate(string guid, out uint id);

		public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks";

		private static readonly TryGetDelegate _tryGetIDDelegate;

		public static JsonConverter PersistentIDConverter { get; private set; }

		public static JsonConverter LocalizedTextConverter { get; private set; }

		public static bool IsLoaded { get; private set; }

		public static bool Initialized { get; private set; }

		public static string PartialDataPath { get; private set; }

		public static string ConfigPath { get; private set; }

		static MTFOPartialDataUtil()
		{
			PersistentIDConverter = null;
			LocalizedTextConverter = null;
			IsLoaded = false;
			Initialized = false;
			PartialDataPath = string.Empty;
			ConfigPath = string.Empty;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value))
			{
				return;
			}
			try
			{
				Assembly assembly = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
				if ((object)assembly == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type[] types = assembly.GetTypes();
				Type type = types.First((Type t) => t.Name == "PersistentIDConverter");
				if ((object)type == null)
				{
					throw new Exception("Unable to Find PersistentIDConverter Class");
				}
				Type type2 = types.First((Type t) => t.Name == "PartialDataManager");
				if ((object)type2 == null)
				{
					throw new Exception("Unable to Find PartialDataManager Class");
				}
				PropertyInfo property = type2.GetProperty("Initialized", BindingFlags.Static | BindingFlags.Public);
				PropertyInfo property2 = type2.GetProperty("PartialDataPath", BindingFlags.Static | BindingFlags.Public);
				PropertyInfo property3 = type2.GetProperty("ConfigPath", BindingFlags.Static | BindingFlags.Public);
				if ((object)property == null)
				{
					throw new Exception("Unable to Find Property: Initialized");
				}
				if ((object)property2 == null)
				{
					throw new Exception("Unable to Find Property: PartialDataPath");
				}
				if ((object)property3 == null)
				{
					throw new Exception("Unable to Find Field: ConfigPath");
				}
				Initialized = (bool)property.GetValue(null);
				PartialDataPath = (string)property2.GetValue(null);
				ConfigPath = (string)property3.GetValue(null);
				Type type3 = types.First((Type t) => t.Name == "PersistentIDManager");
				if ((object)type3 == null)
				{
					throw new Exception("Unable to Find PersistentIDManager Class");
				}
				MethodInfo method = type3.GetMethod("TryGetId", BindingFlags.Static | BindingFlags.Public);
				_tryGetIDDelegate = (TryGetDelegate)method.CreateDelegate(typeof(TryGetDelegate));
				PersistentIDConverter = (JsonConverter)Activator.CreateInstance(type);
				IsLoaded = true;
			}
			catch (Exception value2)
			{
				Logger.Error($"Exception thrown while reading data from MTFO_Extension_PartialData:\n{value2}");
			}
		}

		public static bool TryGetId(string guid, out uint id)
		{
			if (!IsLoaded)
			{
				id = 0u;
				return false;
			}
			if (!Initialized)
			{
				id = 0u;
				return false;
			}
			if (_tryGetIDDelegate == null)
			{
				id = 0u;
				return false;
			}
			return _tryGetIDDelegate(guid, out id);
		}
	}
	public static class MTFOUtil
	{
		public const string PLUGIN_GUID = "com.dak.MTFO";

		public const BindingFlags PUBLIC_STATIC = BindingFlags.Static | BindingFlags.Public;

		public static readonly Version MTFO_FORBID;

		public static readonly Version MTFO_V5;

		public static string GameDataPath { get; private set; }

		public static string CustomPath { get; private set; }

		public static bool HasCustomContent { get; private set; }

		public static bool IsLoaded { get; private set; }

		public static bool HasHotReload { get; private set; }

		public static FieldInfo HotReloaderField { get; private set; }

		public static event Action HotReloaded;

		static MTFOUtil()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			MTFO_FORBID = new Version("4.2.0", false);
			MTFO_V5 = new Version("4.3.5", false);
			GameDataPath = string.Empty;
			CustomPath = string.Empty;
			HasCustomContent = false;
			IsLoaded = false;
			HasHotReload = false;
			HotReloaderField = null;
			if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value))
			{
				return;
			}
			Version version = value.Metadata.Version;
			if (version >= MTFO_V5)
			{
				InitMTFO_V5(value);
				return;
			}
			if (version > MTFO_FORBID)
			{
				InitMTFO_V4(value);
				return;
			}
			throw new Exception("You are using unsupported version of MTFO!");
		}

		private static void InitMTFO_V4(PluginInfo info)
		{
			try
			{
				Assembly assembly = ((info == null) ? null : info.Instance?.GetType()?.Assembly) ?? null;
				if ((object)assembly == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type[] types = assembly.GetTypes();
				Type type = types.First((Type t) => t.Name == "ConfigManager");
				if ((object)type == null)
				{
					throw new Exception("Unable to Find ConfigManager Class");
				}
				FieldInfo field = type.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field2 = type.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field3 = type.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
				if ((object)field == null)
				{
					throw new Exception("Unable to Find Field: GameDataPath");
				}
				if ((object)field2 == null)
				{
					throw new Exception("Unable to Find Field: CustomPath");
				}
				if ((object)field3 == null)
				{
					throw new Exception("Unable to Find Field: HasCustomContent");
				}
				GameDataPath = (string)field.GetValue(null);
				CustomPath = (string)field2.GetValue(null);
				HasCustomContent = (bool)field3.GetValue(null);
				IsLoaded = true;
			}
			catch (Exception value)
			{
				Logger.Error($"Exception thrown while reading path from DataDumper (MTFO V{info.Metadata.Version}): \n{value}");
			}
		}

		private static void InitMTFO_V5(PluginInfo info)
		{
			try
			{
				Assembly assembly = ((info == null) ? null : info.Instance?.GetType()?.Assembly) ?? null;
				if ((object)assembly == null)
				{
					throw new Exception("Assembly is Missing!");
				}
				Type[] types = assembly.GetTypes();
				Type type = types.First((Type t) => t.Name == "ConfigManager");
				if ((object)type == null)
				{
					throw new Exception("Unable to Find ConfigManager Class");
				}
				FieldInfo field = type.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field2 = type.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field3 = type.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
				PropertyInfo property = type.GetProperty("IsHotReloadEnabled", BindingFlags.Static | BindingFlags.Public);
				if ((object)field == null)
				{
					throw new Exception("Unable to Find Field: GameDataPath");
				}
				if ((object)field2 == null)
				{
					throw new Exception("Unable to Find Field: CustomPath");
				}
				if ((object)field3 == null)
				{
					throw new Exception("Unable to Find Field: HasCustomContent");
				}
				if ((object)field3 == null)
				{
					throw new Exception("Unable to Find Field: HasCustomContent");
				}
				if ((object)property == null)
				{
					throw new Exception("Unable to Find Property: IsHotReloadEnabled");
				}
				GameDataPath = (string)field.GetValue(null);
				CustomPath = (string)field2.GetValue(null);
				HasCustomContent = (bool)field3.GetValue(null);
				HasHotReload = (bool)property.GetValue(null);
				if (HasHotReload)
				{
					Type type2 = types.First((Type t) => t.Name == "HotReloader");
					if ((object)type2 == null)
					{
						throw new Exception("Unable to Find HotReloader Class");
					}
					FieldInfo field4 = type2.GetField("Current", BindingFlags.Static | BindingFlags.Public);
					if ((object)field4 == null)
					{
						throw new Exception("Unable to Find Field: Current");
					}
					HotReloaderField = field4;
				}
				IsLoaded = true;
			}
			catch (Exception value)
			{
				Logger.Error($"Exception thrown while reading metadata from MTFO (V{info.Metadata.Version}): \n{value}");
			}
		}

		internal static void OnHotReloaded(int _)
		{
			MTFOUtil.HotReloaded?.Invoke();
		}
	}
}
namespace EEC.Utils.Integrations.Inject
{
	[HarmonyPatch(typeof(CM_PageRundown_New), "OnEnable")]
	internal static class Inject_CM_PageRundown_New
	{
		private static bool _isInjected;

		[HarmonyWrapSafe]
		internal static void Postfix()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			if (_isInjected)
			{
				return;
			}
			object obj = MTFOUtil.HotReloaderField?.GetValue(null) ?? null;
			if (obj != null)
			{
				FieldInfo field = obj.GetType().GetField("button", BindingFlags.Instance | BindingFlags.NonPublic);
				if ((object)field != null)
				{
					CM_Item val = (CM_Item)field.GetValue(obj);
					val.OnBtnPressCallback += Action<int>.op_Implicit((Action<int>)MTFOUtil.OnHotReloaded);
					_isInjected = true;
				}
			}
		}
	}
}
namespace EEC.Patches
{
	[CallConstructorOnLoad]
	public static class PatchManager
	{
		static PatchManager()
		{
			ConfigManager.EnemyPrefabBuilt += PrefabBuilt;
		}

		private static void PrefabBuilt(EnemyAgent agent, EnemyDataBlock enemyData)
		{
			if (ConfigManager.Global.UsingFlyerStuckCheck && enemyData.TryGetBehaviourBlock(out EnemyBehaviorDataBlock behaviour) && behaviour.IsFlyer)
			{
				FlyerStuckHandler flyerStuckHandler = ((Component)agent).gameObject.AddComponent<FlyerStuckHandler>();
				flyerStuckHandler.Agent.Value = agent;
				Logger.Debug($"Added Flyer Check to {((GameDataBlockBase<EnemyDataBlock>)(object)enemyData).persistentID}");
			}
		}
	}
}
namespace EEC.Patches.Inject
{
	[HarmonyPatch(typeof(Dam_SyncedDamageBase))]
	internal static class Inject_Patch_HealerEnemies
	{
		[HarmonyPatch("TentacleAttackDamage")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		internal static bool Pre_TentacleDamage(float dam, Dam_SyncedDamageBase __instance)
		{
			return DoHealer(dam, __instance);
		}

		[HarmonyPatch("MeleeDamage")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		internal static bool Pre_PunchDamage(float dam, Dam_SyncedDamageBase __instance)
		{
			return DoHealer(dam, __instance);
		}

		[HarmonyPatch("ExplosionDamage")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		internal static bool Pre_ExplosionDamage(float dam, Dam_SyncedDamageBase __instance)
		{
			return DoHealer(dam, __instance);
		}

		[HarmonyPatch("ShooterProjectileDamage")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		internal static bool Pre_ShooterProjectileDamage(float dam, Dam_SyncedDamageBase __instance)
		{
			return DoHealer(dam, __instance);
		}

		private static bool DoHealer(float dam, Dam_SyncedDamageBase damBase)
		{
			if (dam >= 0f)
			{
				return true;
			}
			if (SNet.IsMaster)
			{
				float num = Math.Abs(dam);
				damBase.SendSetHealth(Math.Min(damBase.Health + num, damBase.HealthMax));
			}
			return false;
		}
	}
}
namespace EEC.Patches.Handlers
{
	[InjectToIl2Cpp]
	internal sealed class FlyerStuckHandler : MonoBehaviour
	{
		public Il2CppReferenceField<EnemyAgent> Agent;

		public float UpdateInterval = float.MaxValue;

		public int RetryCount = int.MaxValue;

		private EnemyAgent _agent;

		private Vector3 _firstPosition;

		private Vector2 _lastGoalXZ;

		private Timer _timer;

		private int _tryCount = -1;

		private bool _shouldCheck = true;

		private void Start()
		{
			if (!SNet.IsMaster)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			_agent = Il2CppReferenceField<EnemyAgent>.op_Implicit(Agent);
			if ((Object)(object)_agent == (Object)null)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			if (!_agent.EnemyBehaviorData.IsFlyer)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			UpdateInterval = ConfigManager.Global.FlyerStuck_Interval;
			RetryCount = ConfigManager.Global.FlyerStuck_Retry;
		}

		private void FixedUpdate()
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Invalid comparison between Unknown and I4
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (_shouldCheck)
			{
				if ((int)((AgentAI)_agent.AI).Mode != 1 || !_timer.TickAndCheckDone())
				{
					return;
				}
				_timer.Reset(UpdateInterval);
				if (_tryCount == -1)
				{
					_firstPosition = _agent.Position;
					_tryCount = 0;
				}
				else if (Vector3.Distance(_firstPosition, _agent.Position) < 0.1f)
				{
					_tryCount++;
					if (_tryCount >= RetryCount)
					{
						Logger.Debug("Flyer was stuck in Place!");
						((Agent)_agent).m_replicator.Despawn();
					}
				}
				else
				{
					_shouldCheck = false;
				}
				return;
			}
			Vector3 navmeshAgentGoal = _agent.AI.NavmeshAgentGoal;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(navmeshAgentGoal.x, navmeshAgentGoal.z);
			Vector2 val2 = val - _lastGoalXZ;
			float sqrMagnitude = ((Vector2)(ref val2)).sqrMagnitude;
			if (sqrMagnitude < 0.1f)
			{
				EB_States val3 = (EB_States)((MachineState<EB_StateBase>)(object)((StateMachine<EB_StateBase>)(object)_agent.AI.m_behaviour).CurrentState).ENUM_ID;
				if ((int)val3 == 5)
				{
					_tryCount = -1;
					_shouldCheck = true;
				}
			}
			else
			{
				_tryCount = -1;
				_shouldCheck = false;
			}
			_lastGoalXZ = val;
		}

		private void OnDestroy()
		{
			Agent = null;
		}
	}
	[Flags]
	public enum ShitpostType
	{
		ForceOff = -1,
		Enable = 0,
		Dinnerbone = 1
	}
}
namespace EEC.Patches.Handlers.Yes.Yes.Yes.Yes
{
	[CallConstructorOnLoad]
	public static class Shitpost2022
	{
		static Shitpost2022()
		{
			if (Configuration.CanShitpostOf(ShitpostType.Dinnerbone))
			{
				EnemyEvents.Spawned += EnemyEvents_Spawned;
			}
		}

		private static void EnemyEvents_Spawned(EnemyAgent agent)
		{
			//IL_00ed: 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)
			NavMarker marker = GuiManager.NavMarkerLayer.PlaceCustomMarker((NavMarkerOption)16, agent.ModelRef.m_markerTagAlign, "<alpha=#44>Dinnerbone", 0f, false);
			marker.SetVisualStates((NavMarkerOption)0, (NavMarkerOption)0, (NavMarkerOption)0, (NavMarkerOption)0);
			marker.m_titleSubObj.SetEnabled(false);
			marker.SetPinEnabled(false);
			((MonoBehaviour)(object)agent.AI).StartCoroutine(UpdateMarker(agent, marker));
			agent.AddOnDeadOnce(delegate
			{
				GuiManager.NavMarkerLayer.RemoveMarker(marker);
			});
			Transform boneTransform = agent.Anim.GetBoneTransform((HumanBodyBones)0);
			if ((Object)(object)boneTransform != (Object)null)
			{
				BoneOffsetHandler boneOffsetHandler = ((Component)boneTransform).gameObject.AddComponent<BoneOffsetHandler>();
				boneOffsetHandler.Animator = Il2CppReferenceField<Animator>.op_Implicit(agent.Anim);
				boneOffsetHandler.RotationOffset = Il2CppValueField<Vector3>.op_Implicit(new Vector3(0f, 180f, 0f));
			}
			else
			{
				agent.MainModelTransform.Rotate(Vector3.forward, 180f);
			}
		}

		private static IEnumerator UpdateMarker(EnemyAgent agent, NavMarker marker)
		{
			WaitForSeconds yielder = WaitFor.Seconds[0.25f];
			bool enabled = false;
			yield return yielder;
			while (((Agent)agent).Alive)
			{
				if ((int)marker.m_currentState == 2)
				{
					Vector3 val = agent.Position - ((Component)CameraManager.GetCurrentCamera()).transform.position;
					float distanceSqr = ((Vector3)(ref val)).sqrMagnitude;
					if (!enabled && distanceSqr <= 64f)
					{
						marker.m_titleSubObj.SetEnabled(true);
						enabled = true;
					}
					else if (enabled && distanceSqr > 64f)
					{
						marker.m_titleSubObj.SetEnabled(false);
						enabled = false;
					}
				}
				else if (enabled)
				{
					marker.m_titleSubObj.SetEnabled(false);
					enabled = false;
				}
				yield return yielder;
			}
		}
	}
}
namespace EEC.Networking
{
	public static class NetworkManager
	{
		public const ulong LOWEST_STEAMID64 = 76561197960265729uL;

		public static EnemyAgentModeReplicator EnemyAgentModeState { get; private set; } = new EnemyAgentModeReplicator();


		public static EnemyHealthInfoReplicator EnemyHealthState { get; private set; } = new EnemyHealthInfoReplicator();


		public static EnemyAnimEvent EnemyAnim { get; private set; } = new EnemyAnimEvent();


		internal static void Initialize()
		{
			EnemyEvents.Spawned += EnemySpawned;
			EnemyEvents.Despawn += EnemyDespawn;
			EnemyAgentModeState.Initialize();
			EnemyHealthState.Initialize();
			EnemyAnim.Setup();
		}

		private static void EnemySpawned(EnemyAgent agent)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			EnemyAgent agent2 = agent;
			if (agent2.TryGetSpawnData(out var spawnData))
			{
				EnemyAgentModeReplicator.State state = default(EnemyAgentModeReplicator.State);
				state.mode = spawnData.mode;
				EnemyAgentModeReplicator.State startState = state;
				EnemyAgentModeState.Register(((Agent)agent2).GlobalID, startState, delegate(EnemyAgentModeReplicator.State newState)
				{
					//IL_0008: Unknown result type (might be due to invalid IL or missing references)
					ConfigManager.FireAgentModeChangedEvent(agent2, newState.mode);
				});
			}
			EnemyHealthInfoReplicator.State state2 = default(EnemyHealthInfoReplicator.State);
			state2.maxHealth = ((Dam_SyncedDamageBase)agent2.Damage).HealthMax;
			state2.health = ((Dam_SyncedDamageBase)agent2.Damage).Health;
			EnemyHealthInfoReplicator.State startState2 = state2;
			EnemyHealthState.Register(((Agent)agent2).GlobalID, startState2, delegate(EnemyHealthInfoReplicator.State newState)
			{
				EnemyDamageEvents.OnHealthUpdated(agent2, newState.maxHealth, newState.health);
			});
			((MonoBehaviour)(object)agent2.AI).StartCoroutine(CheckHealth(agent2));
		}

		private static IEnumerator CheckHealth(EnemyAgent agent)
		{
			WaitForFixedUpdate fixedUpdateYielder = WaitFor.FixedUpdate;
			float health = ((Dam_SyncedDamageBase)agent.Damage).Health;
			while (true)
			{
				if (SNet.IsMaster)
				{
					float newHealth = ((Dam_SyncedDamageBase)agent.Damage).Health;
					if (!Mathf.Approximately(health, newHealth))
					{
						EnemyHealthState.UpdateInfo(agent);
						health = newHealth;
					}
				}
				yield return fixedUpdateYielder;
			}
		}

		private static void EnemyDespawn(EnemyAgent agent)
		{
			EnemyAgentModeState.Deregister(((Agent)agent).GlobalID);
		}
	}
	public delegate void SNetRecallEvent(eBufferType bufferType);
	public delegate void SNetPlayerEvent(SNet_Player player);
	public delegate void SNetPlayerEventWithReason(SNet_Player player, SNet_PlayerEventReason reason);
	public static class SNetEvents
	{
		public static event SNetPlayerEvent AgentSpawned;

		public static event SNetRecallEvent PrepareRecall;

		public static event SNetRecallEvent RecallComplete;

		internal static void OnAgentSpawned(SNet_Player player)
		{
			SNetEvents.AgentSpawned?.Invoke(player);
		}

		internal static void OnPrepareRecall(eBufferType bufferType)
		{
			//IL_000c: Unknown result type (might be due t